Crypto Training

Liquidation as a Security Property: Fairness, Liveness, and Solvency

Liquidation logic is often treated as pure economics. In practice, it is a security boundary where liveness failures and asymmetry bugs convert stress into protocol loss.

Crypto Training2026-01-062 min read

Liquidation systems are security systems.

They decide who can force balance-sheet transitions under stress.

flowchart LR A[Price move] --> B[Position unhealthy] B --> C[Liquidation callable] C --> D[Repay + seize collateral] D --> E[Protocol solvency restored] C --> F[If blocked: bad debt accumulates]

Security dimensions of liquidation design#

DimensionQuestion
LivenessCan healthy liquidations still execute under stress?
FairnessCan borrowers repair positions before forced close?
SolvencyDoes completed liquidation actually reduce system risk?

Failure patterns observed repeatedly#

  1. Token transfer restrictions block seizure transfers.
  2. Pause controls freeze borrower repair but leave liquidations active.
  3. Fixed bonus math makes deep positions unliquidatable.
  4. Callback-based integrations allow liquidation-step reentrancy/DoS.

Control-flow hardening#

stateDiagram-v2 [*] --> Healthy Healthy --> Warning: healthFactor < warn Warning --> Recovering: borrower repay Warning --> Liquidating: keeper call Liquidating --> Settled: repay and seize success Liquidating --> Blocked: transfer/callback failure Blocked --> EmergencyPath: governance mitigation Settled --> Healthy

Safer liquidation function skeleton#

SOLIDITY
function liquidate(address user, uint256 repayAmount) external {
    _refreshOracle();
    require(_isLiquidatable(user), "not-liquidatable");
    require(repayAmount > 0, "zero-repay");

    uint256 beforeDebt = debtOf[user];
    _pullDebtAsset(msg.sender, repayAmount);

    uint256 applied = _applyRepay(user, repayAmount);
    uint256 seize = _computeSeize(applied); // bounded rounding policy

    _seizeCollateral(user, msg.sender, seize);
    require(debtOf[user] < beforeDebt, "no-debt-progress");
}

The key line is final progress assertion: liquidation must strictly move risk in the correct direction.

Test cases that matter most#

TestExpected result
paused market + repay attemptrepay path available or explicit safe policy
blocklisted collateral recipientgraceful fallback, no partial-accounting corruption
extreme price gapno arithmetic overflow/underflow, no revert traps
repeated micro-liquidationsno rounding-based value extraction

Operator playbook#

  • Maintain emergency liquidation fallback strategy.
  • Monitor liquidation fail rate by reason code.
  • Simulate outage scenarios with mainnet-like constraints.
  • Run post-incident fairness review, not just solvency review.

Further reading#