ERC-7893 DeFi Solvency Proof Standard (DeFi Protocol Solvency Proof Mechanism)

Final · Vaults & DeFi · created 2025-01-30

A standard interface that lets a DeFi protocol record its assets and liabilities onchain so that anyone can look up and verify, in the same way, how well it can repay its debts (solvency).

Why it is needed

Today each DeFi protocol reports its financial status in its own way. The criteria used to calculate assets and liabilities differ, so protocols are hard to compare, and there is no way to check status in real time, so people rely on occasional manual reports. There is also no standardized early warning when conditions worsen, so problems are sometimes noticed only after they have grown. Auditing requires re-matching positions at past points in time one by one, which takes a long time, and assessing risk aggregated across multiple protocols is practically impossible. This standard tries to solve these problems by defining the asset and liability data structures, the calculation formula, the lookup functions, and the alert events as one common interface.

What to implement

In depth

Asset and liability data structures and value notation

The ProtocolAssets and ProtocolLiabilities structs consist of tokens (token addresses), amounts (quantities in each token's own decimals), values (values in ETH with 18 decimals), and timestamp (time of last update). The three arrays must have the same length, and all values must be expressed in ETH with 18 decimals for consistency. The reason for tracking both amounts and values is to keep the state robust even in fast-moving markets, to detect oracle manipulation by comparing the ratio of amount to value over time, and to leave an audit trail for post-incident analysis.

Oracle permissions and update rules

updateAssets and updateLiabilities may be called only by an approved oracle address, and must revert if msg.sender is not an approved oracle. On each update they must verify that the tokens, amounts and values arrays have the same length, set the timestamp field to the current block time (block.timestamp), and must emit a SolvencyMetricsUpdated event on success. Oracle management functions (such as setOracle) are optional, and if provided, emitting an event on permission changes is recommended. The standard does not specify how the oracle is implemented, so Chainlink, API3, a custom oracle or any other source can be used.

Solvency Ratio Calculation

getSolvencyRatio computes the ratio as (totalAssets × 10000) / totalLiabilities and returns it. When assets equal liabilities it returns 10000, and when assets are 105% of liabilities it returns 10500. When liabilities are 0, it is recommended to return a value representing maximum solvency or to revert with an appropriate error. verifySolvency returns a boolean indicating whether the ratio is at or above the minimum threshold (105% in the source, i.e. 10500) together with the current health factor, so that both onchain and offchain systems can quickly assess the state.

Risk Levels and Alert System

The source defines four risk levels. A ratio below 105% is CRITICAL (emergency stop), 105% to 110% is HIGH RISK (risk alert), 110% to 120% is WARNING (watch), and 120% or above is HEALTHY (normal). When financial metrics are updated, a SolvencyMetricsUpdated event must be emitted, and emitting a RiskAlert event when a risk threshold is crossed is recommended. RiskAlert carries the risk level string, the current value that triggered the alert, the threshold that was crossed, and a timestamp. The source states that these levels were validated with simulation tests that include extreme market declines (such as an 80% drop in ETH).

Historical Queries and Retention Policy

getSolvencyHistory(startTime, endTime) must return the timestamp, ratio, and asset and liability state of every snapshot recorded in the specified period (inclusive of both bounds). Implementations must keep historical metrics, but may delete data older than a reasonable retention period (for example, one year). In that case, the retention policy and the queryable time range must be clearly stated in the implementation documentation. The interface comments also state that querying a large time range can consume a lot of gas. The reference implementation shows patterns such as pagination of at most 100 records per query, storage of at most 8760 records (about one year), and a minimum recording interval of one hour.

ERC-165 interface detection

A compliant implementation must implement the ERC-165 supportsInterface function and must return true for the ISolvencyProof interface ID. This lets other contracts check whether an address supports this standard before calling it. The standard assumes ERC-20 and ERC-165, is compatible with existing DeFi protocols, and does not require changes to existing token standards.

Security Measures Shown in the Reference Implementation

The source's reference implementation presents additional safeguards for production environments. Examples include role-based access control (ORACLE_ROLE, EMERGENCY_ROLE, ADMIN_ROLE), rate limiting of one update per 5 blocks per oracle, a circuit breaker that automatically pauses for 1 hour when total assets change by more than 20% at once, multi-oracle consensus validation that rejects prices deviating more than 5% from the median of 3 or more oracles, a limit of 50 tokens per update, and an emergency pause triggered by a guardian. These are recommended implementation patterns, not requirements of the standard.

Things to watch out for

Original ERC · ← ERCs