Dynamic Liquidation Engine (DLE)
Overview
The Dynamic Liquidation Engine (DLE) is a sophisticated liquidation management system implemented in the Curvance Protocol. Facilitating market collateral liquidations through a buffer-based approach with Atlas integration for OEV (OracleExtractable Value) capture.
Technical Architecture
OEV Integration with Atlas
The contract integrates OEV (Oracle Extractable Value) capture:
OEV Auction Mechanism: When price updates make positions liquidatable, an off-chain auction (running ~300ms) allows liquidators to bid for execution rights.
Atomic Execution: Winning bids are executed immediately in the same block as an oracle update.
Bid Distribution: Successful liquidation bids are distributed to Curvance Protocol through the account abstraction operation.
Collateral Targeting: Each auction targets a specific collateral type, enforced through transient storage during transaction execution.
Auction Buffer System
The contract implements a liquidation buffer that gives auction transactions priority access to liquidations:
Buffer Mechanism: A 10 basis point (0.1%) buffer gives auction transactions priority for liquidations.
Implementation: When MEV-boosted liquidations are detected via transient storage, liquidation health checks apply the buffer as a discount to collateral value.
Benefits:
Captures liquidations from non-oracle based changes as interest accrual or LST (Liquid Staking Token) yield distribution.
Compensates for execution latency.
Transient Storage Risk Parameters
Dynamic liquidation parameters are managed through transient storage:
Liquidation Penalty: Configurable within min/max bounds set by governance.
Close Factor: Determines what percentage of debt can be liquidated.
Transient Nature: Parameters exist only for the duration of a transaction.
Validation: All parameters undergo boundary validation before being applied.
Liquidation Types
The contract supports token-specific liquidations:
Token-Specific Liquidations:
Targets individual collateral positions within an account.
Uses the
unlockAuctionForMarket()
combined with_setTransientLiquidationConfig()
mechanism to specify which token can be liquidated.Ideal for soft liquidations where only specific assets need adjustment.
Multi-Liquidation Support
The system is designed to efficiently process liquidations:
Batch Processing: Can handle multiple liquidations in a single transaction.
Cached Pricing: Retrieves asset prices once per transaction rather than per liquidation.
Gas Optimization: Significantly reduces gas costs during liquidation cascades.
Debt Repayment Rollup: Combines debt repayment and bad debt recognition into a single action (1,000 liquidations requires 1 debt token transfer, not 1,000 transfers).
Dual-Oracle Architecture
Curvance's pricing system is designed with risk mitigation as its primary focus through a dual-oracle approach that enhances reliability and security.

For each supported asset, Curvance can simultaneously integrate with two independent oracle providers. This creates redundancy and provides additional verification of asset prices, with the following benefits:
Enhanced security: Mitigates risk from oracle failures or manipulation.
Continuous operation: Ensures liquidations can proceed even in volatile markets.
Safety Buffer: Creates a safety buffer when valuing collateral during distressed situations.
Price Selection Logic
When determining an asset's price, Curvance employs the "most safe" selection algorithm:
Each oracle reports its price for the asset.
The system applies sanity checks to both reported prices:
Deviation from previous price must not exceed configured limits.
Price must be above minimum threshold (non-zero).
Oracle must have reported within the maximum allowable reporting window.
For borrowable assets, the system selects the higher of the two valid prices.
For collateral assets, the system selects the lower of the two valid prices.
// inside of _getLiquidationConfig()
(tData.collateralSharesPrice, tData.debtUnderlyingPrice) =
CommonLib._oracleManager(centralRegistry)
.getPriceIsolatedPair(collateralToken, debtToken, 2);
This approach ensures that in liquidation scenarios, the protocol always errors on the side of protecting itself from bad debt, while giving borrowers the benefit of the most favorable valid price.
Validation Process
Liquidation attempts undergo multiple validation checks.
For example, we check if collateral is unlocked for auction transactions:
// Will revert if this liquidation is an attempted auction liquidator
// and liquidator has chosen incorrect collateral or market.
// Pulls any relevant offchain liquidation configuration.
(tData.auctionBuffer, aData.liqInc, aData.closeFactor) =
_checkLiquidationConfig(collateralToken);
Risk Mitigation
The system incorporates several safeguards:
Transient Storage: Ensures parameters reset after each transaction.
Permission Checks: Restricts access to orderflow auction functions to authorized addresses.
Collateral Locking: Prevents liquidation of unauthorized collateral during Atlas transactions.
Protocol Benefits
Value Capture: Extracts MEV from liquidations that would otherwise go to third parties.
Liquidation Efficiency: Ensures timely liquidations even during high volatility.
Gas Optimization: Uses efficient code combined with transient storage for parameter management.
Graceful Degradation: Protocol remains secure even if OEV auctions fail.
By implementing this sophisticated liquidation system, Curvance balances the needs of protocol security, liquidator incentives, and value capture, creating a powerful framework for position management across diverse market conditions.
User Interaction Functions
statusOf()
Description: Determine account
's current status between collateral, debt, and additional liquidity.
Contract: MarketManager
Function signature:
function statusOf(
address account
) external returns (uint256, uint256, uint256) {
address
account
The account to check liquidation status for.
Return data:
uint256
The current total collateral amount of account
.
uint256
The maximum debt amount of account
can take out with their current collateral.
uint256
The current total borrow amount of account
.
canLiquidate()
Description: Validates and processes batch liquidations for multiple accounts, calculating collateral seizure amounts, debt repayment, and bad debt based on account health and market parameters.
Contract: MarketManager
Function signature:
function canLiquidate(
uint256[] memory debtAmounts,
address liquidator,
address[] calldata accounts,
IMarketManager.LiqAction memory action
) external returns (LiqResult memory, uint256[] memory);
address[]
debtAmounts
The amounts of outstanding debt the liquidator wishes to repay, in underlying assets, empty if intention is to liquidate maximum amount possible for each account.
address
liquidator
The address of the account trying to liquidate accounts
.
address[]
accounts
The addresses of the accounts to be liquidated.
LiqAction
action
Instructions for a liquidation action.
Return data:
LiqResult
Hypothetical results for a liquidation action.
uint256[]
An array containing the debt amounts to repay from accounts
, in assets.
Last updated