Health Factor
The health factor (HF) measures how well-collateralised a position is. When HF < 1.0, the position is liquidatable.
Formula
HF = (deposit_balance × liquidation_threshold) / current_debtWhere:
deposit_balance=deposit_shares × supply_index / WADcurrent_debt=borrow_principal × (borrow_index_current / borrow_index_snapshot)liquidation_threshold= default 80% (WAD-scaled:800_000_000_000_000_000)
Thresholds
| HF | State | Action |
|---|---|---|
= u128::MAX | Zero debt | No risk |
| > 1.0 WAD | Healthy | No liquidation possible |
| = 1.0 WAD | At threshold | On the edge |
| < 1.0 WAD | Undercollateralised | Liquidatable |
Source: programs/src/math.rs::health_factor returns u128::MAX when debt_balance == 0.
LTV vs Liquidation Threshold
- LTV (Loan-to-Value): Maximum borrow ratio at origination. Default 75%. A user with $1,000 deposited can borrow at most $750.
- Liquidation Threshold: The ratio at which an existing position becomes liquidatable. Default 80%. This gives a 5% buffer between max borrow and liquidation.
This gap is intentional — small price moves won’t immediately liquidate a position that’s at its LTV cap.
Computing Health Factor Off-Chain
const WAD = 1_000_000_000_000_000_000n;
const U128_MAX = (1n << 128n) - 1n;
function healthFactor(
depositBalance: bigint,
debt: bigint,
liqThreshold: bigint, // WAD-scaled, e.g. 800_000_000_000_000_000n for 80%
): bigint {
if (debt === 0n) return U128_MAX;
// (depositBalance × liqThreshold / WAD) × WAD / debt
// = (depositBalance × liqThreshold) / debt
return (depositBalance * liqThreshold) / debt;
}
function isLiquidatable(hf: bigint): boolean {
return hf < WAD;
}Example: At-Risk Position
Deposit: 10,000 USDC
Borrow: 8,500 USDC
HF = (10,000 × 0.80) / 8,500
= 8,000 / 8,500
= 0.941 <-- below 1.0, liquidatableLiquidation Parameters
| Parameter | Default | Description |
|---|---|---|
close_factor | 50% | Max portion of debt that can be repaid in one liquidation |
liquidation_bonus | 5% | Discount on seized collateral for the liquidator |
protocol_liq_fee | 10% | Protocol’s share of the seized collateral |
Liquidation math:
repay = current_debt × close_factor
seized = repay × (1 + liquidation_bonus)
liquidator_gets = seized × (1 - protocol_liq_fee)
protocol_gets = seized × protocol_liq_feeLast updated on