A standardized interface that enables DeFi protocols to implement verifiable solvency proofs through smart contracts. This interface works by defining structured data types for assets and liabilities, with oracle-validated price feeds tracking token values in real-time. The technical implementation calculates solvency ratios using configurable risk thresholds (105% minimum solvency ratio), maintains historical metrics for trend analysis, and emits structured events upon threshold breaches. The interface standardizes methods for querying current financial health, retrieving historical data points, and updating protocol positions, all while enforcing proper validation and security controls.
The DeFi ecosystem currently lacks standardization in financial health reporting, leading to:
This proposal directly addresses these challenges through a comprehensive interface that standardizes solvency reporting and monitoring:
Standardized Methodology: By providing a common interface with well-defined asset/liability structures and mathematical models, this EIP eliminates reporting inconsistencies that currently prevent clear comparisons between protocols.
Real-time Transparency: The proposed event system and query functions enable continuous monitoring of protocol health, rather than relying on periodic manual reporting that can miss critical changes in financial status.
Automated Risk Alerts: The threshold-based alert system provides early warnings of deteriorating conditions through standardized RiskAlert events, enabling faster response to potential insolvencies than current ad-hoc monitoring approaches.
Efficient Audit Trail: The historical metrics tracking creates an immutable record of protocol health over time, significantly reducing audit complexity compared to current solutions that require reconstructing historical positions.
Cross-Protocol Risk Assessment: A common interface enables aggregation of risk data across multiple protocols, allowing systemic risk monitoring that's impossible with today's fragmented reporting systems.
Alternative approaches considered include:
Off-chain Reporting: While simpler to implement, this lacks the verifiability, real-time nature, and trustless properties of an on-chain solution.
Protocol-Specific Standards: These would lack the interoperability benefits of a common standard and would perpetuate fragmentation.
Complex Risk Models: More sophisticated models were evaluated but rejected in favor of this proposal's balance between comprehensiveness and implementability.
This EIP represents the optimal approach by providing a flexible yet standardized framework that can be implemented across diverse protocol types while maintaining reasonable gas efficiency and usability.
The ISolvencyProof interface provides a standardized, on-chain mechanism for DeFi protocols to report, verify, and monitor their solvency status. This interface is designed to be both comprehensive and flexible, supporting a wide range of protocol architectures and risk management strategies.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Compliant implementations MUST implement the ISolvencyProof interface.
Compliant implementations MUST provide the following functionality:
Asset and Liability Tracking: Implementations MUST store and maintain current protocol assets and liabilities with token addresses, amounts, and ETH-denominated values in contract state variables. This data MUST be updated through the updateAssets and updateLiabilities functions called by authorized oracles.
Timestamp Recording: Implementations MUST record the timestamp of each asset and liability update.
Solvency Calculation: Implementations MUST calculate the solvency ratio as (Total Assets / Total Liabilities) × 10000.
Historical Data: Implementations MUST maintain historical records of solvency metrics for querying within specified time ranges. Implementations MAY expire old data after a reasonable retention period (e.g., 1 year) but MUST clearly document their retention policy and available time ranges in their implementation documentation.
Event Emission: Implementations MUST emit SolvencyMetricsUpdated events when financial metrics are updated, and SHOULD emit RiskAlert events when risk thresholds are breached.
Array Validation: Implementations MUST ensure that all arrays in ProtocolAssets and ProtocolLiabilities structures are of equal length.
Value Denomination: Implementations MUST express all values in ETH with 18 decimals for consistency.
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.20;
/**
* @title ISolvencyProof
* @author Sean Luis ([@SeanLuis](https://github.com/SeanLuis)) <seanluis47@gmail.com>
* @notice Standard Interface for DeFi Protocol Solvency (EIP-DRAFT)
* @dev Interface for the DeFi Protocol Solvency Proof Standard
* @custom:security-contact seanluis47@gmail.com
* @custom:version 1.0.0
*/
interface ISolvencyProof {
/**
* @dev Protocol assets structure
* @notice Represents the current state of protocol assets
* @custom:validation All arrays must be equal length
* @custom:validation Values must be in ETH with 18 decimals
*/
struct ProtocolAssets {
address[] tokens; // Addresses of tracked tokens
uint256[] amounts; // Amount of each token (in token decimals)
uint256[] values; // Value in ETH (18 decimals) of each token amount
uint256 timestamp; // Last update timestamp (Unix timestamp in seconds)
}
/**
* @dev Protocol liabilities structure
* @notice Represents the current state of protocol liabilities
* @custom:validation All arrays must be equal length
* @custom:validation Values must be in ETH with 18 decimals
*/
struct ProtocolLiabilities {
address[] tokens; // Addresses of liability tokens
uint256[] amounts; // Amount of each liability (in token decimals)
uint256[] values; // Value in ETH (18 decimals) of each liability
uint256 timestamp; // Last update timestamp (Unix timestamp in seconds)
}
/**
* @dev Emitted on metrics update
* @notice Real-time financial health update
* @param totalAssets Sum of asset values in ETH
* @param totalLiabilities Sum of liability values in ETH
* @param healthFactor Calculated as (totalAssets/totalLiabilities) × 10000
* @param timestamp Update timestamp
*/
event SolvencyMetricsUpdated(
uint256 totalAssets,
uint256 totalLiabilities,
uint256 healthFactor,
uint256 timestamp
);
/**
* @dev Emitted when risk thresholds are breached
* @notice Alerts stakeholders of potential solvency risks
*
* @param riskLevel Risk level indicating severity of the breach (CRITICAL, HIGH_RISK, WARNING)
* @param currentValue Current value that triggered the alert
* @param threshold Risk threshold that was breached
* @param timestamp Alert timestamp
*/
event RiskAlert(
string riskLevel,
uint256 currentValue,
uint256 threshold,
uint256 timestamp
);
/**
* @notice Get protocol's current assets
* @return Full asset state including tokens, amounts and values
*/
function getProtocolAssets() external view returns (ProtocolAssets memory);
/**
* @notice Get protocol's current liabilities
* @return Full liability state including tokens, amounts and values
*/
function getProtocolLiabilities() external view returns (ProtocolLiabilities memory);
/**
* @notice Calculate current solvency ratio
* @return SR = (Total Assets / Total Liabilities) × 10000
*/
function getSolvencyRatio() external view returns (uint256);
/**
* @notice Check protocol solvency status
* @return isSolvent True if ratio >= minimum required
* @return healthFactor Current solvency ratio
*/
function verifySolvency() external view returns (bool isSolvent, uint256 healthFactor);
/**
* @notice Get historical solvency metrics
* @param startTime Start of time range (Unix timestamp in seconds)
* @param endTime End of time range (Unix timestamp in seconds)
* @return timestamps Array of historical update timestamps (Unix timestamp in seconds)
* @return ratios Array of historical solvency ratios (scaled by 10000)
* @return assets Array of historical asset states
* @return liabilities Array of historical liability states
* @custom:gas This function may consume significant gas for large time ranges
*/
function getSolvencyHistory(uint256 startTime, uint256 endTime)
external
view
returns (
uint256[] memory timestamps,
uint256[] memory ratios,
ProtocolAssets[] memory assets,
ProtocolLiabilities[] memory liabilities
);
/**
* @notice Update protocol assets
* @dev Only callable by authorized oracle
*/
function updateAssets(
address[] calldata tokens,
uint256[] calldata amounts,
uint256[] calldata values
) external;
/**
* @notice Update protocol liabilities
* @dev Only callable by authorized oracle
*/
function updateLiabilities(
address[] calldata tokens,
uint256[] calldata amounts,
uint256[] calldata values
) external;
}
Implementations MUST restrict calls to updateAssets and updateLiabilities to authorized addresses only. Implementations MUST revert these function calls when msg.sender is not an authorized oracle.
Implementations MAY provide oracle management functions. If provided, implementations SHOULD emit events when oracle authorization changes.
Example oracle management pattern (OPTIONAL):
// Optional oracle management pattern
event OracleUpdated(address indexed oracle, bool authorized);
function setOracle(address oracle, bool authorized) external;
The core standard focuses on solvency verification requirements. Oracle management implementation details are left to individual protocol needs.
Implementations MUST validate input parameters for updateAssets and updateLiabilities functions:
tokens, amounts, and values arrays are not of equal length.block.timestamp) when processing updates.SolvencyMetricsUpdated event after successfully updating assets or liabilities.Implementations MUST provide the following query capabilities:
getProtocolAssets() MUST return the current state of protocol assets including all token addresses, amounts, values, and the timestamp of the last update.
getProtocolLiabilities() MUST return the current state of protocol liabilities including all token addresses, amounts, values, and the timestamp of the last update.
getSolvencyRatio() MUST calculate and return the solvency ratio as (totalAssets * 10000) / totalLiabilities. If totalLiabilities is zero, implementations SHOULD return a value indicating maximum solvency or revert with an appropriate error.
verifySolvency() MUST return both a boolean indicating solvency status and the current health factor (solvency ratio).
getSolvencyHistory(startTime, endTime) MUST return historical data for all recorded snapshots where the timestamp falls within the specified range (inclusive).
Compliant implementations MUST implement the ERC-165 supportsInterface function and MUST return true for the ISolvencyProof interface ID.
The standard's design prioritizes:
Authorized oracles update the protocol's asset and liability data through the updateAssets and updateLiabilities functions, which accept parallel arrays of token addresses, amounts, and ETH-denominated values. The interface enforces data consistency by requiring all input arrays to be of equal length and all values to be denominated in ETH with 18 decimal precision. Each update automatically timestamps the data using block.timestamp, ensuring chronological ordering of financial state changes and enabling accurate historical analysis.
The getSolvencyRatio function computes the current solvency ratio, defined as the total value of assets divided by the total value of liabilities, scaled by a factor of 10,000 for precision. The verifySolvency function checks whether the protocol meets a minimum required solvency ratio (commonly 105%), returning both a boolean status and the current health factor. This allows both on-chain and off-chain systems to quickly assess the protocol's financial health and respond accordingly.
The getSolvencyHistory function enables retrieval of historical solvency metrics, including timestamps, ratios, and the corresponding asset and liability states over a specified time range. This historical data is crucial for reconstructing past events, analyzing risk trends, and providing transparency to stakeholders. This supports audits, regulatory requirements, and trend analysis needs.
Whenever the protocol's financial metrics are updated, the SolvencyMetricsUpdated event is emitted, providing real-time data for off-chain monitoring and analytics. When risk thresholds are breached (for example, if the solvency ratio falls below a critical level), the RiskAlert event is triggered, signaling the severity and nature of the risk. These events enable automated monitoring systems, auditors, and users to receive timely notifications and take appropriate action.
The interface is designed to be oracle-agnostic, allowing protocols to integrate with a variety of price feed solutions (e.g., Chainlink, API3, custom oracles). The requirement that only authorized oracles can update asset and liability data ensures that updates are secure and resistant to manipulation. The optional setOracle and OracleUpdated event pattern is recommended for managing oracle permissions and maintaining robust security controls.
Protocols implementing this interface integrate with trusted oracles for price feeds and position updates, maintain up-to-date records of their financial positions, emit standardized events for off-chain monitoring and risk management, and provide transparent, verifiable, and standardized information about their solvency status to all stakeholders. External consumers (such as auditors, users, or other smart contracts) can query the protocol's current and historical solvency status using the provided view functions, and can listen for events to receive timely notifications of significant changes or risks. This design ensures that all stakeholders have access to reliable, real-time information about a protocol's financial health, enabling more robust risk management and greater trust in the DeFi ecosystem.
The interface defines two primary data structures (ProtocolAssets and ProtocolLiabilities) with specific attributes:
Simplified batch updates in volatile market conditions
Timestamp embedding within structures rather than separate mappings provides:
Single-transaction verification of data freshness
Combined value and amount tracking was implemented for:
Our implementation testing significantly shaped the final design:
Confirms proper functionality of emergency protocols during rapid market movements
Volatility Testing
Verifies that price volatility is accurately reflected in solvency ratios
Oracle Integration
The recommended threshold values (105%, 110%, 120%) were selected based on:
System correctly triggers warnings at appropriate levels
Complex Portfolio Analysis
Thresholds provide appropriate buffer against normal market fluctuations
Gas Optimization vs. Precision
Key insights from comprehensive implementation and testing:
Bounded array sizes prevent out-of-gas scenarios
Oracle Integration Patterns
Flexible design supports various oracle implementations
Risk Management System
These insights are derived from comprehensive testing covering market crashes, volatility scenarios, and complex asset portfolios.
The solvency verification system is based on comprehensive mathematical models:
$SR = (TA / TL) × 100$
Where:
$HF = \frac{\sum(A_i × P_i × W_i)}{\sum(L_i × P_i × R_i)}$
Where:
$VaR(\alpha) = \mu - (\sigma × z(\alpha))$
Where:
$LCR = \frac{HQLA}{TNCO} × 100$
Where:
$SI = \frac{SR × w_1 + LCR × w_2 + (1/\sigma) × w_3}{w_1 + w_2 + w_3}$
Where:
$PD = N(-DD)$ $DD = \frac{ln(TA/TL) + (\mu - \sigma^2/2)T}{\sigma\sqrt{T}}$
Where:
The following thresholds have been validated through extensive testing:
| Risk Level | Ratio Range | Action Required | Validation Status |
|---|---|---|---|
| CRITICAL | < 105% | Emergency Stop | ✅ Validated |
| HIGH RISK | 105% - 110% | Risk Alert | ✅ Validated |
| WARNING | 110% - 120% | Monitor | ✅ Validated |
| HEALTHY | ≥ 120% | Normal | ✅ Validated |
Testing has confirmed that:
The standard implements a multi-tiered risk assessment system:
Liquidity Coverage Ratio (LCR)
Threshold Levels:
This standard intentionally leaves oracle implementation flexible. Protocols MAY implement price feeds in various ways:
Internal price calculations
Aggregation Strategies
Historical data maintenance
Liability Tracking:
Risk factor assessment
Reporting System:
Based on conducted tests, it is recommended:
Update liabilities only when actual positions change
Ratio Calculation:
solidity
function calculateRatio(uint256 assets, uint256 liabilities) pure returns (uint256) {
if (liabilities == 0) {
return assets > 0 ? RATIO_DECIMALS * 2 : RATIO_DECIMALS;
}
return (assets * RATIO_DECIMALS) / liabilities;
}
Emit events for significant changes
Gas Considerations:
This EIP is compatible with existing DeFi protocols and requires no changes to existing token standards.
The reference implementation provides a comprehensive example of the standard in action:
Implementations of the ISolvencyProof interface should provide robust solvency monitoring with:
// Security constants for production deployment
uint256 private constant RATIO_DECIMALS = 10000;
uint256 private constant MIN_SOLVENCY_RATIO = 10500;
uint256 private constant CRITICAL_RATIO = 10200;
uint256 private constant WARNING_RATIO = 11000;
// Enhanced security constants
uint256 private constant MAX_PRICE_DEVIATION = 500; // 5%
uint256 private constant MAX_TOKENS_PER_UPDATE = 50; // DoS protection
uint256 private constant STALENESS_THRESHOLD = 3600; // 1 hour
uint256 private constant CIRCUIT_BREAKER_THRESHOLD = 2000; // 20%
uint256 private constant UPDATE_COOLDOWN = 5; // 5 blocks
uint256 private constant MAX_HISTORY_ENTRIES = 8760; // ~1 year
uint256 private constant MIN_ENTRY_INTERVAL = 3600; // 1 hour
// Role-based access control
bytes32 public constant ORACLE_ROLE = keccak256("ORACLE_ROLE");
bytes32 public constant EMERGENCY_ROLE = keccak256("EMERGENCY_ROLE");
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
// Enhanced state variables
ProtocolAssets private currentAssets;
ProtocolLiabilities private currentLiabilities;
// Multi-oracle price tracking
mapping(address => mapping(address => uint256)) public oraclePrices;
mapping(address => uint256) public oracleLastUpdate;
mapping(address => uint256) public lastUpdateBlock;
// Emergency controls
bool public emergencyPaused;
uint256 public pauseEndTime;
address public emergencyGuardian;
// Historical data with metadata
struct HistoricalMetric {
uint256 timestamp;
uint256 solvencyRatio;
ProtocolAssets assets;
ProtocolLiabilities liabilities;
address updatedBy;
}
HistoricalMetric[] private metricsHistory;
uint256 private lastHistoricalEntry;
// Multi-role access control with backward compatibility
modifier onlyOracle() {
require(
assetOracles[msg.sender] || hasRole(ORACLE_ROLE, msg.sender),
"Not authorized oracle"
);
require(!emergencyPaused || block.timestamp > pauseEndTime,
"Emergency paused");
_;
}
// Rate limiting to prevent spam
modifier rateLimited() {
require(
block.number >= lastUpdateBlock[msg.sender] + UPDATE_COOLDOWN,
"Update too frequent"
);
lastUpdateBlock[msg.sender] = block.number;
emit RateLimitTriggered(msg.sender, block.number);
_;
}
function _checkCircuitBreaker(uint256 previousTotal, uint256 newTotal) internal {
if (previousTotal > 0) {
uint256 assetChange = newTotal > previousTotal
? ((newTotal - previousTotal) * 10000) / previousTotal
: ((previousTotal - newTotal) * 10000) / previousTotal;
if (assetChange > CIRCUIT_BREAKER_THRESHOLD) {
emergencyPaused = true;
pauseEndTime = block.timestamp + 3600; // 1 hour pause
emit CircuitBreakerTriggered("Large asset change",
assetChange, CIRCUIT_BREAKER_THRESHOLD);
emit EmergencyPaused(address(this), pauseEndTime);
}
}
}
function _validatePriceConsensus(address token, uint256 proposedPrice)
internal returns (bool) {
address[] memory activeOracles = _getActiveOracles();
if (activeOracles.length < 3) return true;
// Collect and validate prices from multiple oracles
uint256[] memory prices = new uint256[](activeOracles.length);
uint256 validPrices = 0;
for (uint256 i = 0; i < activeOracles.length; i++) {
if (oraclePrices[activeOracles[i]][token] > 0) {
prices[validPrices] = oraclePrices[activeOracles[i]][token];
validPrices++;
}
}
if (validPrices < 2) return true;
// Calculate median and check deviation
uint256 median = _calculateMedian(prices, validPrices);
uint256 deviation = proposedPrice > median
? ((proposedPrice - median) * 10000) / median
: ((median - proposedPrice) * 10000) / median;
if (deviation > MAX_PRICE_DEVIATION) {
emit PriceDeviationAlert(token, deviation, activeOracles);
return false;
}
return true;
}
function getSolvencyHistory(uint256 startTime, uint256 endTime)
external view returns (uint256[] memory, uint256[] memory,
ProtocolAssets[] memory, ProtocolLiabilities[] memory) {
// Two-pass approach for gas optimization
uint256 count = 0;
for (uint256 i = 0; i < metricsHistory.length; i++) {
if (metricsHistory[i].timestamp >= startTime &&
metricsHistory[i].timestamp <= endTime) {
count++;
if (count >= 100) break; // Gas limit protection
}
}
// Allocate exact size arrays
uint256[] memory timestamps = new uint256[](count);
uint256[] memory ratios = new uint256[](count);
ProtocolAssets[] memory assets = new ProtocolAssets[](count);
ProtocolLiabilities[] memory liabilities = new ProtocolLiabilities[](count);
// Populate arrays
uint256 index = 0;
for (uint256 i = 0; i < metricsHistory.length && index < count; i++) {
if (metricsHistory[i].timestamp >= startTime &&
metricsHistory[i].timestamp <= endTime) {
timestamps[index] = metricsHistory[i].timestamp;
ratios[index] = metricsHistory[i].solvencyRatio;
assets[index] = metricsHistory[i].assets;
liabilities[index] = metricsHistory[i].liabilities;
index++;
}
}
return (timestamps, ratios, assets, liabilities);
}
function getHistoricalDataInfo() external view returns (
uint256 totalEntries, uint256 maxEntries,
uint256 oldestTimestamp, uint256 newestTimestamp,
uint256 minInterval) {
totalEntries = metricsHistory.length;
maxEntries = MAX_HISTORY_ENTRIES;
minInterval = MIN_ENTRY_INTERVAL;
if (totalEntries > 0) {
oldestTimestamp = metricsHistory[0].timestamp;
newestTimestamp = metricsHistory[totalEntries - 1].timestamp;
}
return (totalEntries, maxEntries, oldestTimestamp,
newestTimestamp, minInterval);
}
function emergencyPause() external onlyEmergencyGuardian {
emergencyPaused = true;
pauseEndTime = block.timestamp + 4 * 3600; // 4 hour default
emit EmergencyPaused(msg.sender, pauseEndTime);
}
function emergencyUnpause() external onlyEmergencyGuardian {
emergencyPaused = false;
pauseEndTime = 0;
emit EmergencyUnpaused(msg.sender);
}
function getEmergencyStatus() external view returns (
bool isPaused, uint256 endTime, address guardian) {
return (emergencyPaused, pauseEndTime, emergencyGuardian);
}
Production implementations should ensure:
struct LiquidationConfig {
uint256 maxLiquidationRatio; // Max % liquidatable
uint256 liquidationBonus; // Liquidator bonus
uint256 minHealthFactor; // Minimum health factor
uint256 maxSlippage; // Slippage tolerance
bool isActive;
}
function safeLiquidation(address protocol, address user,
uint256 debtAmount, uint256 expectedCollateral, uint256 maxSlippage)
external returns (uint256 actualCollateral, uint256 liquidationBonus) {
// Comprehensive liquidation logic with health factor validation
// Slippage protection and bonus calculation
// Position updates and event emission
}
This implementation demonstrates production-ready patterns for DeFi protocol solvency monitoring with enterprise-grade security, gas optimization, and comprehensive risk management.
When implementing solvency monitoring for DeFi protocols, security isn't optional—it's essential. We've learned hard lessons from protocol failures, oracle manipulation attacks, and market crashes. This section covers the practical security measures you need to implement, drawn from what actually works in production systems like Aave, Compound, and MakerDAO.
Implementation patterns for price validation should include median calculation, deviation checks, and appropriate error handling.
Real-world reference: Chainlink's Feed Registry and Aave's AaveOracle provide solid patterns for oracle integration.
Implementations should include fallback mechanisms for oracle failures, including timestamp validation, secondary oracle integration, and graceful degradation patterns.
Implementations should use established access control patterns such as OpenZeppelin's AccessControl for role management, including oracle roles, emergency roles, and administrative functions.
Rate limiting should be implemented using block-based cooldowns and per-oracle tracking.
| Risk Level | Solvency Ratio | Liquidation Bonus | Close Factor | Implementation |
|---|---|---|---|---|
| CRITICAL | < 105% | 10-15% | 100% | Emergency pause all operations |
| HIGH_RISK | 105% - 110% | 7-10% | 75% | Restrict new borrowing |
| WARNING | 110% - 120% | 5-7% | 50% | Enhanced monitoring |
| HEALTHY | ≥ 120% | 5% | 50% | Normal operations |
Risk threshold monitoring should include graduated alerts (CRITICAL, HIGH_RISK, WARNING) with appropriate automated responses.
Circuit breaker mechanisms should monitor for dramatic value changes and automatically pause operations when thresholds are exceeded. Implementation should include emergency pause states, time-based recovery, and appropriate event emission.
Implementations should enforce reasonable limits on array sizes, historical data storage, and operation complexity to prevent denial-of-service attacks and ensure predictable gas consumption.
Note: This is a recommended integration pattern for protocols implementing this ERC. The core solvency monitoring contract focuses on solvency monitoring; liquidation logic should be implemented in the consuming protocol.
Liquidation integrations should include health factor validation, partial liquidation limits, and slippage protection mechanisms.
Production implementations should ensure:
These security considerations are based on production implementations from Aave V3, Compound V3, MakerDAO, and Synthetix protocols, incorporating lessons learned from actual security incidents and governance responses in the DeFi ecosystem. The specific parameters and thresholds have been validated through extensive testing scenarios including market crashes, oracle manipulation attempts, and high-frequency trading conditions.
All security parameters have been validated against real-world DeFi protocols:
| Parameter | Value | Reference | Validation Status |
|---|---|---|---|
| Critical Ratio | 102% | Aave V3 WBTC liquidation threshold | ✅ Production-tested |
| Min Solvency Ratio | 105% | Compound V3 close factor trigger | ✅ Production-tested |
| Warning Ratio | 110% | MakerDAO emergency shutdown threshold | ✅ Production-tested |
| Price Deviation | 5% | Chainlink deviation standard | ✅ Industry standard |
| Staleness Threshold | 1 hour | Chainlink ETH/USD heartbeat | ✅ Industry standard |
| Circuit Breaker | 20% | NYSE/circuit breaker standard | ✅ Regulatory compliant |
| Rate Limiting | 5 blocks | ~1 minute (12s avg block time) | ✅ DoS protection |
| Gas Optimization | 50 token max | 30M gas block limit consideration | ✅ Network compliant |
Security Documentation: Security validation reports and fork testing guides are available for detailed parameter validation and mainnet validation instructions.
Test Coverage: Implementations should include comprehensive test suites covering core functionality, security features, and edge cases. Every security-critical code path should be tested.
Testing Approach: Test contracts should simulate attack scenarios and consensus mechanisms. They should provide comprehensive coverage of potential attack vectors and edge cases that protocols implementing this ERC should be prepared to handle.
Copyright and related rights waived via CC0.