Liquidation
Handles undercollateralised position auctions and bad-debt socialisation.
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.
Liquidation Module
When a user's health-factor drops below 1.0, their position is eligible for liquidation. Any external keeper holding LIQUIDATOR_ROLE can trigger the auction.
Auction Mechanics
- Keeper calls
liquidate(borrower, asset, repayAmount) - Protocol repays up to 50% of the borrower's debt on their behalf
- Borrower's collateral is seized at a 5% discount (liquidation bonus)
- If collateral is insufficient to cover debt (bad debt), the shortfall is socialised across the insurance fund
Health Factor Formula
HF = Σ(collateral_i × collateralFactor_i) / totalDebt
A position is safe when HF ≥ 1.0. Liquidation is available when HF < 1.0. The protocol applies a 5% liquidation bonus to incentivise keepers.
Bad Debt
If a position's collateral value is less than its outstanding debt (e.g. due to a rapid price crash), the shortfall is covered by the protocol's insurance buffer held in the Treasury module. If the buffer is exhausted, the loss is socialised pro-rata among liquidity providers.
Examples
Keeper bot liquidation loop
async function runKeeperLoop(users: string[]) {for (const user of users) {const liquidatable = await liquidation.isLiquidatable(user);if (!liquidatable) continue;const vault = await core.getVault(user);const repayAmt = vault.debt / 2n; // max 50%const seized = await liquidation.callStatic.liquidate(user, USDC_ADDRESS, repayAmt);console.log(`Seizing ${ethers.formatEther(seized)} collateral`);await liquidation.liquidate(user, USDC_ADDRESS, repayAmt);}}
A basic keeper loop that checks all tracked users and liquidates eligible positions.
Edge Cases
- liquidate() reverts if health-factor ≥ 1.0 at the time of execution (front-run protection)
- repayAmount is capped at 50% of outstanding debt per transaction to prevent full liquidations
- If collateral is zero (full bad debt), the function succeeds but collateralSeized returns 0
- Liquidation bonus is applied in collateral asset terms, not USD — fast-moving prices can erode the incentive
Interface
interface ILiquidation {/// @notice Liquidate up to repayAmount of borrower's debt/// @param borrower Address of the undercollateralised user/// @param asset Debt asset to repay/// @param repayAmount Amount of debt to repay (max 50% of total)function liquidate(address borrower,address asset,uint256 repayAmount) external returns (uint256 collateralSeized);/// @notice Returns true when a position is eligible for liquidationfunction isLiquidatable(address user) external view returns (bool);/// @notice Current liquidation bonus (1e18 = 100%, e.g. 1.05e18 = 5% bonus)function liquidationBonus() external view returns (uint256);event Liquidated(address indexed liquidator,address indexed borrower,address asset,uint256 debtRepaid,uint256 collateralSeized);}
