Lender
The Lending Pool module manages the borrowing, repayment, and liquidation processes for Operators.
Overview of Operations
Borrow/Repay: Operators can borrow reserve assets against their delegated collateral
Liquidation: Multi-stage liquidation with grace periods and bonus incentives
Interest Rate Calculation: Dynamic protocol rates and fixed Operator specific rates
Key Loan Parameters
Total Delegation: Total amount of an Operator's received collateral from Delegators
Total Slashable Collateral: Total amount of collateral that can be slashed from a Delegator
Total Debt: An Operator's total debt denominated in USD. Interest accrues to Total Debt
Initial Loan-to-Value (LTV): The maximum amount an Operator can borrow relative to the Total Slashable Collateral. A 50% LTV implies that delegations must be at least 2x the size of the borrow.
Current LTV: An Operator's current Loan-to-Value ratio, calculated as
(Total Debt / Total Delegation) * 100%
Liquidation Threshold: Threshold that determines when an Operator's position becomes slashable in LTV ratio. By default, the threshold is set to 80%.
Health Factor: Represents an Operator's loan health
Calculated as (Total Delegation * Liquidation Threshold) / Total Debt
Liquidations are triggered when Health is below 1
Grace Period: Period for Operators to recover the health before liquidation can occur. Set to 12 hours
Expiry Period: Period after which liquidation rights expire. Set to 3 days
Target health: Target health ratio that liquidators aim to achieve when slashing an Operator. Set to 125%
Bonus Cap: Maximum bonus for liquidators, set to 10%.
Debt Management
The protocol has two distinct types of interest:
Vault Interest: Interest paid to the Vault (stcUSD holders)
Restaker Interest: Interest paid to Delegators who provide collateral coverage
Debt in Cap is managed via Debt tokens. Debt tokens are non-transferrable ERC-20 tokens that track an Operator's debt. Debt tokens are minted when an Operator borrows, and burned when the debt is repayed.
Interest automatically accrues to the debt token per asset, where the interest rate is calculated based on the interest rate mechanism. Accrued interest is handled automatically via index-based scaling, inherited from the ScaledToken base class.
Architecture
The Lending Pool module is designed as an upgradeable proxy with modular logic libraries for maintainability and security.
BorrowLogic Library - Core logic for borrowing, repaying, and interest management
LiquidationLogic Library - Advanced liquidation mechanisms and bonus calculations
ReserveLogic Library - Reserve management and configuration
ViewLogic Library - View functions and calculations
ValidationLogic Library - Comprehensive validation systems
Lender Contract
The Lender contract is the main interface for all lending operations.
Core Functions
Borrowing Operations
borrow
: Allows agents to borrow assets from the lending pool via the BorrowLogic library
function borrow(address _asset, uint256 _amount, address _receiver) external returns (uint256 borrowed)
_asset
: Asset to borrow_amount
: Amount to borrow_receiver
: Address to receive the borrowed assets
repay
: Allows agents to repay assets from the lending pool via the BorrowLogic library
function repay(address _asset, uint256 _amount, address _agent) external returns (uint256 repaid)
_asset
: Asset to repay_amount
: Amount to repay_agent
: Agent whose debt is being repaid
Liquidation
openLiquidation
: Opens a liquidation window for an unhealthy operator
function openLiquidation(address _agent) external
liquidate
: Liquidate debt and slash collateral
function liquidate(address _agent, address _asset, uint256 _amount, uint256 _minLiquidatedValue) external returns (uint256 liquidatedValue)
closeLiquidation
: End liquidation window when position is healthy
function closeLiquidation(address _agent) external
Interest Distribution
Convert accrued interest into debt tokens via the BorrowLogic library
function realizeInterest(address _asset) external returns (uint256 actualRealized)
function realizeRestakerInterest(address _agent, address _asset) external returns (uint256 actualRealized)
Types:
Vault Interest: System-wide interest realization
Restaker Interest: Agent-specific interest for restakers
Admin Functions
addAsset
: Adds new assets to the lending pool
function addAsset(AddAssetParams calldata _params) external checkAccess(this.addAsset.selector)
Parameters:
asset: Asset address to add
vault: Vault address for the asset
debtToken: Debt token address
interestReceiver: Interest receiver address
bonusCap: Liquidation bonus cap
minBorrow: Minimum borrow amount
removeAsset
: Removes assets from the lending pool, if there are no outstanding debt before removal
function removeAsset(address _asset) external checkAccess(this.removeAsset.selector)
papuseAsset
: Pause asset from being borrowed, prevents new borrows when paused
function pauseAsset(address _asset, bool _pause) external checkAccess(this.pauseAsset.selector)
setInterestReceiver
: Sets interest receiver for an asset
function setInterestReceiver(address _asset, address _interestReceiver) external checkAccess(this.setInterestReceiver.selector)
setMinBorrow
: Set Minimum Borrow
function setMinBorrow(address _asset, uint256 _minBorrow) external checkAccess(this.setMinBorrow.selector)
Set Liquidation Parameters
More details can be found in the Liquidation page
function setGrace(uint256 _grace) external checkAccess(this.setGrace.selector)
function setExpiry(uint256 _expiry) external checkAccess(this.setExpiry.selector)
function setBonusCap(uint256 _bonusCap) external checkAccess(this.setBonusCap.selector)
function setTargetHealth(uint256 _targetHealth) external checkAccess(this.setTargetHealth.selector)
View Functions
Agent
: View agent(Operator) information
function agent(address _agent) external view returns (
uint256 totalDelegation, // Total delegation in USD (8 decimals)
uint256 totalSlashableCollateral, // Total slashable collateral in USD (8 decimals)
uint256 totalDebt, // Total debt in USD (8 decimals)
uint256 ltv, // Loan to value ratio (1e27)
uint256 liquidationThreshold, // Liquidation threshold (1e27)
uint256 health // Health factor (1e27)
)
maxBorrowable
: Maximum Borrowable Amount for an agent for an asset
function maxBorrowable(address _agent, address _asset) external view returns (uint256 maxBorrowableAmount)
Debt
: Get the current debt balances for an agent for a specific asset
function debt(address _agent, address _asset) external view returns (uint256 totalDebt);
Data Structures
The LenderStorage stores the list of all the Reserve Data along with agent (Operator) configuration and liquidation parameters.
struct LenderStorage {
// Addresses
address delegation; // Delegation contract managing agent permissions
address oracle; // Oracle for price feeds
// Reserve configuration
mapping(address => ReserveData) reservesData; // Asset to reserve data mapping
mapping(uint256 => address) reservesList; // Reserve ID to asset mapping
uint16 reservesCount; // Total number of reserves
// Agent configuration
mapping(address => AgentConfigurationMap) agentConfig; // Agent configuration data
mapping(address => uint256) liquidationStart; // Liquidation start timestamps
// Liquidation parameters
uint256 targetHealth; // Target health ratio (1e27)
uint256 grace; // Grace period in seconds
uint256 expiry; // Liquidation expiry period
uint256 bonusCap; // Maximum liquidation bonus (1e27)
uint256 emergencyLiquidationThreshold; // Emergency liquidation threshold
}
The reserve data struct stores all relevant Vault information for an underlying asset.
struct ReserveData {
uint256 id; // Reserve ID
address vault; // Vault address
address debtToken; // Debt token address
address interestReceiver; // Interest receiver address
uint8 decimals; // Asset decimals
bool paused; // Pause state
uint256 debt; // Total debt
uint256 totalUnrealizedInterest; // Total unrealized interest
mapping(address => uint256) unrealizedInterest; // Per-agent unrealized interest
mapping(address => uint256) lastRealizationTime; // Last interest realization time
uint256 minBorrow; // Minimum borrow amount
}
Agent (Operator) configuration is stored in the AgentConfigurationMap struct that contains a single uint256 field called data. This field is a bitmap, where each bit represents a boolean of whether an agent is borrowing for a specific reserve. Agent specific loan information such as collateral amount, liquidation threshold is stored in the Delegation contract and can be read via the ViewLogic contract.
Last updated