Lender Contract
The Lender contract implements the core lending functionality for an instance: collateral management, debt accounting, interest accrual, liquidations, redemptions, and PSM conversions. Contract implementationUser-Facing Functions
adjust
account: Address of the position to adjustcollateralDelta: Amount to add (positive) or remove (negative) collateral (in wei)debtDelta: Amount to borrow (positive) or repay (negative) debt (in wei)chooseRedeemable: True to turn on redeemable (free debt) mode. False to turn off.
- If
collateralDelta > 0:msg.sendermust provide collateral in (approval required) - If
debtDelta > 0: Position must remain solvent after the change - If
debtDelta < 0: Caller must provide Coin to repay (approval required) - If decreasing collateral or increasing debt: caller must be
accountor a delegated address - If
debtDelta != 0: resulting debt must be 0 or ≥minDebt
- Automatically accrues interest before adjustment
- Updates collateral and debt of the borrower
- Maintains minimum debt requirements
- Emits position update events
liquidate
borrower: Address of the position to liquidaterepayAmount: Amount of debt to repay (in wei)minCollateralOut: Minimum collateral amount to receive (caller protection)
collateralOut: Amount of collateral received by liquidator
- Borrower loan must be unhealthy at the oracle price and liquidations allowed
- Up to 25% of total debt can be liquidated per call (minimum 10,000 Coin chunk, or full debt if smaller)
- Liquidator must provide Coin to repay and set an acceptable
minCollateralOut
- Accrue interest on borrower’s position
- Verify liquidation conditions
- Transfer Coin from liquidator to repay debt
- Calculate collateral reward with incentive
- Transfer collateral to liquidator
- Update borrower’s position
- Incentive scales from 0% (at collateralFactor) up to 10% (5 percentage points above collateralFactor), linearly in between
redeem
amountIn: Amount of Coin to redeem (in wei)minAmountOut: Minimum collateral amount to receive (slippage protection)
amountOut: Amount of collateral received
- Redemptions must be allowed (fresh oracle)
- Redeemable borrowers must have sufficient collateral to redeem and debt to repay
amountOutmust be ≥minAmountOut
amountOut = amountIn * 1e18 * (10000 - redeemFeeBps) / price / 10000
sell
coinIn: Amount of Coin to sell (in wei)minAssetOut: Minimum PSM asset amount to receive
assetOut: Amount of PSM asset received
- PSM must be configured with a
psmAsset - Sufficient PSM reserves available
assetOutmust be ≥minAssetOut
- Decimals conversion between 18‑dec Coin and
psmAssetdecimals. No fee.
buy
assetIn: Amount of PSM asset to spend (in wei)minCoinOut: Minimum Coin amount to receive
coinOut: Amount of Coin received
- PSM must be configured
- Must be before immutability deadline
coinOutmust be ≥minCoinOut
- Decimals conversion; buy fee ramps from 0→100 bps during the second half of the immutability window
delegate
delegatee: Address to grant/revoke delegationisDelegatee: True to grant, false to revoke
- Allows delegatee to borrow and withdraw collateral via
adjust()and callsetRedemptionStatus()on behalf of delegator - A delegator may assign multiple concurrent delegatees.
- Delegation can be changed at any time by delegator
setRedemptionStatus
account: Address to set redemption status for (can be any address)chooseRedeemable: True to allow redemption, false to prevent
- Caller must be
accountor a delegated address
- Toggles redeemable status. If true, borrower pays 0 interest. If false, borrowers pays variable rate.
- Default is non‑redeemable.
accrueInterest
- Uses the shared InterestModel to compute current rate and interest
- Splits interest into fees (local/global reserves) and staking yield (minted to the Vault)
writeOff
borrower: Address with bad debt positionto: Address to receive written-off collateral
writtenOff: True if debt was written off
- Oracle must allow liquidations
- Position must be extremely undercollateralized (debt > 100× collateral value)
- Callable by anyone (also attempted from
liquidate()via try/catch)
- Deletes borrower debt
- Redistributes it across free/paid pools proportionally
- Sends remaining collateral to
to
View Functions
getDebtOf
account: Address to query debt for
debt: Current debt amount in wei
getCollateralPrice
price: Normalized to36 - collateralDecimalsdigits (never zero inside consumers)reduceOnly: True if only reductions allowedallowLiquidations: True if liquidations/redemptions/write‑offs permitted
getFreeDebtRatio
ratio: Free debt ratio in basis points (0–10000)
getRedeemAmountOut
amountIn: Amount of Coin to redeem
amountOut: Amount of collateral received
getSellAmountOut
coinIn: Amount of Coin to sell
assetOut: Amount of PSM asset received
getBuyAmountOut
assetIn: Amount of PSM asset to spend
coinOut: Amount of Coin receivedcoinFee: Fee amount deducted
getFeedPrice
price: Raw price from Chainlink feedupdatedAt: Timestamp when price was last updated
Protocol Management Functions
setPendingOperator
_pendingOperator: New operator address
- Caller must be current operator
acceptOperator
- Caller must be pending operator
setManager
_manager: New manager address
- Caller must be operator or manager
enableImmutabilityNow
- Caller must be operator
- Must be before immutability deadline
pullLocalReserves
- Caller must be operator
pullGlobalReserves
_to.
Parameters:
_to: Address to receive reserves
- Caller must be Factory
reapprovePsmVault
- Must be before immutability deadline
Configuration Functions
setHalfLife
halfLife: New half-life in seconds
- Caller must be operator or manager
- Must be before immutability deadline
setTargetFreeDebtRatio
startBps: Minimum free debt ratio (basis points)endBps: Maximum free debt ratio (basis points)
- Caller must be operator or manager
- Must be before immutability deadline
setRedeemFeeBps
_redeemFeeBps: New redemption fee (basis points)
- Caller must be operator or manager
- Must be before immutability deadline
setLocalReserveFeeBps
_feeBps: New fee rate (basis points)
- Caller must be operator
Key State Variables
totalPaidDebt
Cached total amount of interest-bearing debt in the protocol. May be missing accrued interest.totalFreeDebt
Total amount of non-interest-bearing debt in the protocol.collateralFactor
Maximum borrower collateralization ratio in basis points (e.g., 8000 = 80%).minDebt
Minimum debt amount required for positions.immutabilityDeadline
Timestamp after which protocol becomes immutable.feeBps
Protocol fee rate in basis points.Events
PositionAdjusted(address account, int collateralDelta, int debtDelta)HalfLifeUpdated(uint64 halfLife)TargetFreeDebtRatioUpdated(uint16 startBps, uint16 endBps)RedeemFeeBpsUpdated(uint16 redeemFeeBps)DelegationUpdated(address delegator, address delegatee, bool isDelegatee)PendingOperatorUpdated(address pendingOperator)OperatorAccepted(address operator)ManagerUpdated(address manager)LocalReserveFeeUpdated(uint256 feeBps)RedemptionStatusUpdated(address account, bool isRedeemable)Liquidated(address borrower, address liquidator, uint repayAmount, uint collateralOut)WrittenOff(address borrower, address to, uint debt, uint collateral)NewEpoch(uint epoch)Redeemed(address account, uint amountIn, uint amountOut)Sold(address account, uint coinIn, uint assetOut)Bought(address account, uint assetIn, uint coinOut)

