Liquidation Design

A liquidation moves unsafe security-bond allowance from an undercollateralized target vault to a non-liquidatable liquidator vault. Liquidation is punitive: it moves debt to the liquidator and seizes unlocked REP from the target vault at a bonus-priced exchange rate.

The purpose of liquidation is explicit: punish the vault that let its backing fall below the required threshold, reward the liquidator that takes on the unsafe debt, and move the system into a healthier state.

  1. The liquidated vault is punished by losing unlocked REP.
  2. The liquidator is rewarded with seized REP above market value.
  3. The target shortfall shrinks because required REP backing falls faster than REP is seized, and moved debt is accepted only by a caller vault that remains non-liquidatable, meaning at or above the collateral threshold.

Here, healthier means the target shortfall shrinks and the moved debt lands only on a caller vault that remains non-liquidatable under the statoblastSecurityMultiplierBps-adjusted collateral threshold. Liquidation redistributes REP and allowance; it does not increase aggregate backing.

Terms used below: targetUnlockedRep = target vault unlocked REP claim, targetAllowanceEth = target vault allowance, statoblastSecurityMultiplierBps = Statoblast security multiplier in basis points, currentRepPerEthPrice = current REP/ETH price, PRICE_PRECISION = 1e18, BPS_DENOMINATOR = 10_000.

Liquidatable Condition

Security assumptions: A21 genesis REP and WETH behavior, A13 REP liquidity, A14 REP economic backing, A16 timely inclusion, A17 corrector capability, A18 independent correction incentive, and A19 observable correctable price.

The official client may separately show a Uniswap-derived market preview when staging a liquidation. Quote availability and representativeness are client limitations, not protocol security assumptions or the contract's liquidatable condition. Contract execution uses the settled coordinator price under A19.

A vault is liquidatable when its unlocked REP backing is below the required threshold. Allowance admission keeps the affected vault on the non-liquidatable side of this boundary and independently applies the same multiplier-adjusted inequality to aggregate pool backing. Only vaults are liquidation targets:

Punitive FlowThe liquidator takes debt and receives unlocked REP from the target vault. The target is punished, the liquidator is rewarded, and the target becomes healthier only because required REP backing falls faster than REP is seized. The ordinary path uses bonus-priced REP; a full staged-allowance close can instead sweep all current unlocked REP when the ordinary conversion would consume all ownership or leave forbidden REP dust.

targetAllowanceEth statoblastSecurityMultiplierBps currentRepPerEthPrice > targetUnlockedRep PRICE_PRECISION BPS_DENOMINATOR

Liquidatable ConditionThe vault is unsafe when required REP backing exceeds unlocked REP.

The contract snapshots the target vault when liquidation is queued. Execution reuses that snapshot for the initial debt-cap and stale-data checks, so adding REP later cannot make the liquidation stale by itself. A later top-up can still make a full-close sweep fail the strict No gain check if the current unlocked REP grows too large relative to the queued debt.

Why Adding REP Cannot Cure a Pending Liquidation

Queueing preserves the liquidator's opportunity to execute using the target's queue-time state, subject to the execution gates below. A later REP deposit alone does not make that snapshot stale. Decreasing the target's ownership or changing its allowance does. The pending liquidation remains bounded by the allowance and ownership captured at queue time, so a later REP deposit cannot increase the debt or REP that the liquidator may move under that snapshot.

This rule preserves the incentive to pay for and trigger a fresh oracle report. If a target could wait for someone else to fund price discovery, then add REP and cancel the liquidation before settlement, vault owners would have an incentive to keep less backing and use pending liquidations as free warnings. Liquidators would bear the oracle cost without a reliable chance to earn the liquidation bonus, so rational liquidators could stop initiating the reports that make the system's solvency checks live.

For vault owners, the practical consequence is that adding REP can prevent or limit future liquidations, but it does not cancel a liquidation that was validly queued already. Vaults should maintain sufficient backing before an operation is staged rather than treating the oracle settlement window as a cure period.

Execution Gates

The liquidatable-threshold inequality is necessary but not sufficient for execution. A staged liquidation also needs a valid current oracle price, an unexpired staging window, target allowance unchanged and target ownership not below the queued snapshot, and enough distance beyond the threshold to satisfy minLiquidationPriceDistanceBps. These gates fail in different ways. If the current price is stale, execution reverts and the staged operation stays pending. If coordinator-level checks fail after a valid price is available, such as expiry, stale snapshot data, or too little distance from the threshold, the coordinator consumes the staged operation without calling the pool. If the pool call itself fails after consumption, for example because the caller would become liquidatable or because a requested chunk leaves forbidden debt dust, the coordinator emits a failed execution result. See OpenOracle integration for the full settlement and distance-check flow.

Liquidation Decision FlowPrice freshness is the only illustrated failure that leaves the operation queued. Once a valid price reaches execution, later coordinator or pool failures consume the staged operation. The pool selects the ordinary or full-close REP candidate before checking target gain, liquidator health, and final-balance rules.

Penalty Math

The seized REP is based on the debt chunk's market value plus a fixed liquidation bonus. The current implementation uses LIQUIDATION_REP_BONUS_BPS = 500, or a five percent REP bonus to the liquidator.

Constant Value Unit Source
BPS_DENOMINATOR 10000 basis points SecurityPoolUtils.sol
LIQUIDATION_REP_BONUS_BPS 500 basis points SecurityPoolUtils.sol
MIN_REP_DEPOSIT 10e18 REP wei SecurityPoolUtils.sol
MIN_SECURITY_BOND_DEBT 1e18 ETH wei SecurityPoolUtils.sol
PRICE_PRECISION 1e18 fixed-point scale SecurityPoolUtils.sol
computedRepToMove = debtToMovecurrentRepPerEthPrice(BPS_DENOMINATOR+liquidationRepBonusBps) PRICE_PRECISIONBPS_DENOMINATOR computedOwnershipToMove = repToPoolOwnership(computedRepToMove) repToMove = if debtToMovesnapshotTargetAllowanceEth ,  computedRepToMove ,  else if computedOwnershipToMovecurrentTargetOwnership ,  currentTargetUnlockedRep ,  else if poolOwnershipToRep(currentTargetOwnership-computedOwnershipToMove)<MIN_REP_DEPOSIT ,  currentTargetUnlockedRep ,  else computedRepToMove

REP PenaltyThe liquidator normally receives REP worth the liquidated debt plus a bonus. When a liquidation clears the target's entire staged allowance and the ownership conversion of that fixed-bonus seizure would consume all current target ownership or leave forbidden REP dust, the contract instead seizes the target's full current unlocked REP. Sizing uses the queued snapshot allowance, while the final full-close sweep uses current target ownership. That override also applies if the target topped up REP after queueing the liquidation.

The contract first computes an initial REP-bound cap from the target's queued snapshot REP, then applies the debt-floor clamp, and only after that can a full-close liquidation sweep current ownership. Partial liquidations preserve the target's final MIN_REP_DEPOSIT, but a full-close liquidation may consume all current unlocked REP when it also clears all staged target debt.

Variable legend: snapshotTargetUnlockedRep and snapshotTargetAllowanceEth are the queued liquidation inputs; currentTargetOwnership and currentTargetUnlockedRep are read at execution time for the final ownership sweep.

repBoundDebt = if snapshotTargetUnlockedRep>MIN_REP_DEPOSIT ,   (snapshotTargetUnlockedRep-MIN_REP_DEPOSIT)PRICE_PRECISIONBPS_DENOMINATOR currentRepPerEthPrice(BPS_DENOMINATOR+liquidationRepBonusBps)  else 0 targetCapBeforeDebtFloor = min(snapshotTargetAllowanceEth,repBoundDebt) targetCapAfterDebtFloor = if 0<snapshotTargetAllowanceEth-targetCapBeforeDebtFloorMIN_SECURITY_BOND_DEBT ,  snapshotTargetAllowanceEth>MIN_SECURITY_BOND_DEBT ?snapshotTargetAllowanceEth-MIN_SECURITY_BOND_DEBT:snapshotTargetAllowanceEth ,  else targetCapBeforeDebtFloor debtToMove = min(requestedDebt,targetCapAfterDebtFloor)

Executable BoundThe requested debt chunk is capped by the target's queued snapshot REP and then checked against the minimum debt floors. That final debt-floor clamp leaves exactly MIN_SECURITY_BOND_DEBT when the target allowance starts above the floor, but executes the whole allowance when the target itself is already at the minimum-sized 1 ETH debt floor. The later full-close sweep can then consume current target ownership.

debtToMove statoblastSecurityMultiplierBps currentRepPerEthPrice > repToMove PRICE_PRECISION BPS_DENOMINATOR

Health-Improvement GuardEvery successful liquidation must strictly reduce the target shortfall. Equality still fails, so ceiling-rounded REP seizure can make one-wei or otherwise tiny chunks non-executable.

There is one more chunking constraint at execution time: remainingDebt = targetAllowanceEth - debtToMove must be zero or at least MIN_SECURITY_BOND_DEBT. The caller's post-liquidation allowance must also be at least MIN_SECURITY_BOND_DEBT, because any successful liquidation moves non-zero debt to the caller. A chunk that is safe for the target can still revert if it would leave the liquidator below that minimum non-zero debt floor. Very small chunks can also revert when ceiling-rounded REP seizure would reduce the target's REP faster than the chunk reduces required backing, because every successful liquidation must strictly improve target health.

Repeated Liquidations

A punitive liquidation is not guaranteed to restore target safety in one execution. A liquidation can move the target toward safety without restoring it completely, because the liquidator is also paid a REP bonus. Repeated liquidations at the same price can therefore remain possible until the target debt is cleared, the target becomes safe again, the target hits a floor constraint, or the liquidator side would become liquidatable after absorbing more debt. This is one source of path dependence: a smaller first liquidation can make the target safe again and block a later same-price liquidation that would have been absorbed inside one larger execution.

Worked Examples

Unless a row says otherwise, assume the caller vault already has enough REP backing to remain non-liquidatable after it absorbs the moved debt and receives seized REP. The rows focus on target-side sizing and penalty math; execution still applies the caller post-liquidation check.

Case Inputs Result
Penalty liquidation targetUnlockedRep = 1000 REP, targetAllowanceEth = 75 ETH, statoblastSecurityMultiplierBps = 20_000, currentRepPerEthPrice = 10 REP/ETH Required backing is 75 * 2 * 10 = 1500 REP, so the target starts 500 REP short. A 25 ETH liquidation seizes 25 * 10 * 1.05 = 262.5 REP. After liquidation the target has 50 ETH of debt and 737.5 REP of backing. The target is still unsafe, but the shortfall shrinks from 500 REP to 262.5 REP.
Locked escalation REP stays untouched targetUnlockedRep = 300 REP unlocked, targetAllowanceEth = 200 ETH, statoblastSecurityMultiplierBps = 20_000, currentRepPerEthPrice = 1 REP/ETH A full 200 ETH liquidation would seize 210 REP, leaving 90 REP unlocked and 0 ETH debt. Escalation-locked REP is still ignored when sizing the liquidation, so only the unlocked vault claim is at risk.
Target-side debt dust clamp targetAllowanceEth = 1.4 ETH, targetUnlockedRep = 1000 REP, statoblastSecurityMultiplierBps = 20_000, currentRepPerEthPrice = 1000 REP/ETH The target has enough unlocked REP for about 0.94 ETH of punitive liquidation while still keeping 10 REP. That would leave 0.46 ETH of target debt, which is forbidden dust, so the executable target-side cap is reduced to 0.4 ETH instead.
Caller-side dust revert targetAllowanceEth = 1.4 ETH, targetUnlockedRep = 1000 REP, statoblastSecurityMultiplierBps = 20_000, executable target-side cap is 0.4 ETH, caller starts with zero debt A 0.4 ETH liquidation would leave the caller with a non-zero allowance below MIN_SECURITY_BOND_DEBT, so the pool rejects it. In that setup, no punitive liquidation chunk is executable.
Minimum-size full close targetUnlockedRep = 10 REP, targetAllowanceEth = 1 ETH, statoblastSecurityMultiplierBps = 20_000, currentRepPerEthPrice = 6.1 REP/ETH The target is unsafe because 1 * 2 * 6.1 = 12.2 REP is above its 10 REP backing. The REP-bound chunk is 0 ETH, but the debt-floor clamp upgrades the executable chunk to a full 1 ETH close because the remainder would be exactly MIN_SECURITY_BOND_DEBT. The fixed-bonus penalty would be 6.405 REP, which would leave forbidden REP dust, so the liquidation seizes the target's full 10 REP instead and closes the vault.
Queued top-up can remove the gain snapshotTargetUnlockedRep = 10 REP, snapshotTargetAllowanceEth = 1 ETH, statoblastSecurityMultiplierBps = 20_000, currentRepPerEthPrice = 6.1 REP/ETH, target later adds 3 REP The staged debt still sizes from the 10 REP / 1 ETH snapshot, but the full-close sweep now evaluates the target's current 13 REP ownership. That would make 1 * 2 * 6.1 = 12.2 REP not strictly greater than the seized 13 REP, so the queued liquidation fails No gain and is consumed without moving debt or REP.

Slider Examples

These calculators use whole ETH and REP units for readability. The equations above describe the scaled integer math used onchain.

Punitive liquidation calculator

Status: Liquidatable

Required REP: 1500 REP

REP shortfall: 500 REP

Target-side cap before caller checks: 75.00 ETH

Post-max debt: 0.00 ETH

REP seized at Max: 787.50 REP

Liquidation ThresholdThe red curve is required REP backing across the full price range; the green rule is the selected vault's unlocked REP. The highlighted point follows the price slider and changes state when it crosses the boundary.

This calculator only models the target-side cap. A real execution can still revert if the caller vault would fail its own debt-floor or post-liquidation non-liquidatable checks. It also clamps away non-deployable low multipliers, but it remains a whole-unit target-side illustration rather than a wei-level requested-chunk simulator for the strict health-improvement guard.

Path dependence check

Base case is fixed at targetUnlockedRep = 1000 REP, targetAllowanceEth = 75 ETH, statoblastSecurityMultiplierBps = 20_000, and currentRepPerEthPrice = 10 REP/ETH.

Single liquidation using first + second: 50 ETH debt remaining

Two-step path: 50 ETH debt remaining

Same state? Yes

This path comparison assumes each step's caller vault passes the post-liquidation non-liquidatable and debt-floor checks. It models target-side path dependence only.

Incentive Implications

Security assumptions: A01 risk-adjusted incentives, A02 viable operating costs, A03 independent liquidators, A06 liquidation executors, and A25 safe parameter relationships.

The protocol uses a target-funded REP penalty. That means the liquidator has a direct immediate reward and the target is explicitly punished when it falls below the collateral threshold.

This only improves the target if debt relief frees more required backing than the protocol seizes as a REP bonus. Ignoring integer rounding, the economic condition is:

statoblastSecurityMultiplierBps > BPS_DENOMINATOR + liquidationBonusBps

With a 2x Statoblast security multiplier and a 5% REP bonus, ordinary-sized liquidations reduce required backing faster than seized REP, so the target gets healthier even while it loses collateral. The executable rule is still the strict onchain health-improvement guard debtToMove * statoblastSecurityMultiplierBps * currentRepPerEthPrice > repToMove * PRICE_PRECISION * BPS_DENOMINATOR; ceil-rounded tiny chunks can fail with No gain.

The tradeoff is boundary sensitivity, not generic path dependence. Partial liquidations can leave the target still liquidatable, and exact results become path-sensitive when integer rounding, REP floors, debt floors, or caller threshold checks bind. Away from those boundaries, the linear REP penalty means repeated partial liquidations at a fixed price can reach the same final state as one combined liquidation.