Lending
Manages deposit, borrow, and repay operations with dynamic interest rate models.
Third-party documentation. This is independently authored analysis of the public Aurum Protocol codebase — not the official docs, and not reviewed or endorsed by the Aurum Protocol team.
Lending Module
The Lending module is the primary user-facing interface for capital deployment. Users deposit assets as collateral and borrow against them at algorithmically-set rates.
Interest Rate Model
Rates follow a two-kink piecewise linear curve:
- 0–70% utilisation: base rate (2% APR)
- 70–90% utilisation: base + multiplier (ramps to 20% APR)
- 90–100% utilisation: jump multiplier (ramps to 150% APR)
This creates natural pressure to keep pool utilisation below the first kink, protecting liquidity for withdrawals.
Accrual
Interest accrues per-second using continuous compounding: balance × e^(rate × Δt). The accrueInterest() function must be called (by any account) before any state-changing operation to sync the accumulator.
Examples
Full deposit-and-borrow flow
// 1. Approve the lending module to pull USDCawait usdc.approve(lending.address, depositAmount);// 2. Deposit collateralawait lending.deposit(USDC_ADDRESS, depositAmount);console.log("Deposited", ethers.formatUnits(depositAmount, 6), "USDC");// 3. Borrow ETH against it (70% LTV)const borrowAmt = depositAmount * 70n / 100n;await lending.borrow(WETH_ADDRESS, borrowAmt);console.log("Borrowed", ethers.formatEther(borrowAmt), "ETH");
The canonical flow for opening a leveraged position.
Repay full debt with permit
// Use type(uint256).max to repay all outstanding debtconst sig = await signPermit(signer, weth, lending.address, type(uint256).max);await lending.repayWithPermit(WETH_ADDRESS, type(uint256).max, sig);console.log("Debt fully cleared");
Repay without a prior approve transaction using EIP-2612 permit.
Edge Cases
- borrow() reverts if resulting health-factor < 1.05 (5% safety buffer)
- withdraw() reverts if the withdrawal would drop health-factor below 1.0
- Depositing a delisted asset still succeeds — only borrowing is blocked for delisted assets
- accrueInterest() is idempotent within the same block
Interface
interface ILending {/// @notice Deposit asset as collateralfunction deposit(address asset, uint256 amount) external;/// @notice Withdraw previously deposited collateralfunction withdraw(address asset, uint256 amount) external;/// @notice Borrow asset against existing collateralfunction borrow(address asset, uint256 amount) external;/// @notice Repay outstanding debt (use type(uint256).max to repay all)function repay(address asset, uint256 amount) external;/// @notice Sync interest accumulator — must precede any state mutationfunction accrueInterest(address asset) external;/// @notice Current borrow APR for an asset (1e18 = 100%)function borrowRate(address asset) external view returns (uint256);event Deposited(address indexed user, address indexed asset, uint256 amount);event Borrowed(address indexed user, address indexed asset, uint256 amount);event Repaid(address indexed user, address indexed asset, uint256 amount);}
