Liquidation and ADL
This page is the dedicated execution reference for perp liquidation, portfolio margin liquidation, auto-deleveraging, and BOLE lending liquidation. It is meant to sit between the broad paper and the raw RE notes: concrete enough to implement from, honest about what is still inferred, and explicit about where spot and outcomes diverge from the perp liquidation family.
crates/hl-engine/src/liquidation.rs (private repo path)
1. Product Surface Split
| Surface | Trigger family | Execution lane | LtHash / state effect |
|---|---|---|---|
| Perp cross | account_value < maintenance_margin |
Liquidate action, then ADL on residual shortfall |
LiquidatedCross |
| Perp isolated | allocated_margin + uPnL < maintenance_margin |
Liquidate action, then ADL on residual shortfall |
LiquidatedIsolated |
| Portfolio margin | Unified account ratio breach across eligible assets | Same liquidation family as cross margin, but with PM account summary and mixed asset exposure | Same perp liquidation family; exact mixed-leg order still open |
| BOLE lending | health_factor < 0.8 |
begin_block lending liquidation pass |
BoleMarketLiquidation, BoleBackstopLiquidation, BolePartialLiquidation |
| Spot | No normal perp-style liquidation path | Separate spot clearinghouse / dust conversion behavior | SpotDustConversion is the relevant state-hash lane |
| Outcomes | Settlement / cancellation, not liquidation | outcomeSettledCanceled, outcomeSettledRejected, merge / settlement logic |
Outcome state transitions, not perp liquidation categories |
2. End-to-End Liquidation Flow
The high-level split is simple: ordinary liquidation first, ADL only if bad
debt remains, and BOLE handled in an earlier lending pass during
begin_block.
3. Trigger Formulas
Perp Cross
confirmed structure
margin_available
= balance
+ cross_uPnL
- maintenance_margin_used
liquidatable if margin_available < 0
Perp Isolated
confirmed structure
isolated_margin_available
= allocated_margin
+ unrealized_pnl
- isolated_maintenance_margin
liquidatable if isolated_margin_available < 0
Margin Tiers
tiered table
initial_margin
= sum(notional_in_tier / max_leverage)
maintenance_margin
= sum(notional_in_tier / max_leverage
- maintenance_deduction)
BOLE Health
implemented on main
ltv = borrowed_value / supplied_value
health_factor
= supplied_value * reserve.liquidation_threshold
/ borrowed_value
liquidatable if health_factor < 0.8
| Formula / rule | Current best state | Confidence |
|---|---|---|
| Perp liquidation trigger | account_value < maintenance_margin |
Confirmed structure |
| ADL ranking | Opposing profitable side, ordered by ROE descending | Confirmed surface |
| BOLE threshold | health_factor < 0.8 |
Confirmed / implemented locally |
| BOLE partial cooldown | 30s default cooldown guard |
Observed in docs + local implementation |
| PM mixed-leg liquidation order | Depends on live account exposure and oracle ordering | Open implementation detail |
4. Auto-Deleveraging
ADL is the bad-debt cleanup lane, not the first response. The exchange only
flips into ADL when ordinary liquidation leaves residual shortfall. Current
engine state exposes the same core fields the binary notes point at:
perform_auto_deleveraging,
adl_shortfall_remaining, and per-bucket requirements keyed by
asset plus side.
roe = unrealized_pnl / margin_allocated
ADL bucket key = (asset, opposing_side)
eligible side = opposite side of the liquidated position
priority = higher ROE first, then larger notional
What is still not fully closed: exact shortfall sizing and the final residual handling when the ranked profitable side cannot absorb all remaining debt.
5. BOLE begin_block Lane
On current main, BOLE liquidation is a top-of-block lending pass.
It runs immediately after funding distribution and before the aggressive OI-cap
cancel lane. That keeps lending insolvency handling ahead of later cleanup and
trading-prep effects.
| Mode | Meaning | Key guardrail |
|---|---|---|
| Market | Normal BOLE liquidation path | Only after health-factor breach and absent higher-priority backstop route |
| Partial | Risk reduction without full account transfer | partial_liquidation_cooldown |
| Backstop | Default liquidator takes the borrow position | Requires configured liquidator and reserve routing |
6. Portfolio Margin and Non-Perp Surfaces
Portfolio margin is not modeled here as its own liquidation engine. It is a mode overlay on the same liquidation family, with a different account summary and broader asset set. The current protocol claim in the repo is: keep PM as an account mode, not a separate universe.
- Perps and PM share the liquidation family.
- Spot is not handled like a normal perp liquidation path; dust conversion is the visible state-hash lane.
- Outcomes settle and cancel through their own execution stack instead of the perp liquidation engine.
- BOLE is a lending liquidation system with separate begin-block execution and separate LtHash categories.
7. Call Graph and Code Map
| Surface | Primary local code path | Reference artifact |
|---|---|---|
| begin_block ordering | crates/hl-engine/src/exchange.rs (private repo path) |
exchange_block_pipeline.dot (omitted from public export) |
| ADL planning | crates/hl-engine/src/liquidation.rs (private repo path) |
Liquidation Engine note |
| BOLE state and reserves | crates/hl-engine/src/services.rs (private repo path) |
clearinghouse_liquidation.dot (omitted from public export) |
| Paper overview | paper chapter 9 | rendered call-graphs page |
8. What Is Still Open
| Gap | Why it matters | Status |
|---|---|---|
| Exact ADL execution sizing | Needed for end-to-end parity, not just ranking parity | open |
| Residual shortfall handling after ADL capacity is exhausted | Solvency and parity risk surface | open |
| Portfolio margin mixed-leg order | Needed to replay PM liquidation exactly across perps and spot borrows | open |
| Final BOLE penalty / sizing details | Current local execution is directionally correct but not yet final-protocol exact | work in progress |
| Outcome solvency lane | Outcome settlement and merge logic is a separate safety review, not a liquidation path | active research |