# marginX HLP-Style Liquidity Vault — Liquidations, Market Making & Design

> Research + design doc for an **HLP-style protocol liquidity vault** that **market-makes**
> *and* **backstops liquidations**, with depositors sharing the PnL + fees. Studies
> Hyperliquid (HLP), Extended (Vault), and Lighter (LLP), maps them onto marginX's existing
> contracts, and proposes a concrete design + phased plan.
> Author: engineering. Status: for review. Last updated: 2026-05-31.

---

## 0. TL;DR

- A perp exchange needs a **counterparty of last resort** for liquidations and a **liquidity
  source** for markets. Hyperliquid (HLP), Extended (Vault), and Lighter (LLP) all solve both
  with **one depositor-owned vault** that market-makes *and* absorbs liquidated positions,
  paying the resulting PnL + fees back to depositors.
- **marginX already has all the pieces** — `BackstopVault` (ERC4626-style, absorbs liquidation
  PnL, socializes bad debt), `InsuranceFund` (penalties + fee pool + funding shortfall),
  `MarketMakingVault` (ERC4626 MM vault), and an **ADL engine** in `PositionHandler`. They are
  **fragmented**; the HLP upgrade is to **unify them into one depositor vault** that is a
  first-class liquidation counterparty and market maker.
- This doc: (1) how marginX liquidations work **today**, (2) how HLP/Extended/Lighter work,
  (3) the **ideal unified vault** design + algorithms + diagrams, (4) a phased plan.

---

## 1. How marginX liquidations work TODAY

### 1.1 Margin model
- **Initial margin** `INITIAL_MARGIN_FACTOR = 500 bps (5%)` → up to 20x.
- **Maintenance margin** `MAINTENCANCE_MARGIN_FACTOR = 300 bps (3%)`.
- Per-market overrides via `DataStore` margin tiers; cross-margin valued by the **Quantum Risk
  Engine (QRE)** with shock pricing (requires `RiskOracle.setPerpRiskParams` per market).
- A position is liquidatable when `equity = collateral + unrealizedPnL < maintenanceMargin`
  (isolated: `PositionHandler.isPositionLiquidatable`; cross: `BalanceManagerVault.canLiquidateCrossMargin`).

### 1.2 The loss-absorption waterfall (verified live on Arc)
When `liquidatePosition` fires, the loss is absorbed in this order:

```mermaid
flowchart TD
    A[Position becomes liquidatable<br/>equity < maintenance margin] --> B{Liquidate}
    B --> C[1. Close against the ORDER BOOK<br/>reduce-only IOC at mark]
    C -->|fully filled| D[Realize PnL vs book<br/>liquidationFee --> InsuranceFund]
    C -->|book has no/par­tial liquidity| E[2. ADL: force-reduce profitable<br/>counterparties at bankruptcy price<br/>_triggerADL: scan<=200, max 25/pass]
    E -->|counterparties absorb residual| F[Counterparty realizes gain<br/>position closed]
    E -->|residual still uncovered| G[3. BackstopVault.updateVaultPnL<br/>vault eats the loss]
    G -->|vault has funds| H[totalVaultValue -= loss]
    G -->|vault depleted| I[4. SOCIALIZE: totalSocializedDebt += deficit<br/>DebtSocialized event]
    D --> Z[InsuranceFund grows]
    H --> Z2[Depositor NAV drops]
    I --> Z3[Bad debt recorded]
```

**Live-verified figures (Arc, 2026-05-31):** cross-margin liq routed the penalty to the
InsuranceFund (+10.85 USDC); ADL force-reduced a counterparty short to 0 (it realized +7.49
USDC); a contrived insolvency drained `BackstopVault` 18.6→0, `InsuranceFund` 15.7→0, and
recorded `totalSocializedDebt = 27 USDC`.

### 1.3 Components today (fragmented)
| Contract | Role today | ERC4626? | Depositor-owned? |
|---|---|---|---|
| `BackstopVault` | absorbs un-ADL'd liquidation loss; socializes bad debt | yes (shares, perf fee 10%, withdraw fee 0.1%, `MAX_UTILIZATION` 80%) | **yes** but not used as MM/liquidator counterparty |
| `InsuranceFund` | liquidation penalties + per-fill fee pool + funding shortfall cover | LP deposits exist | partially |
| `MarketMakingVault` | automated MM (ERC4626 + gauge rewards) | yes | yes, **separate silo** |
| `PositionHandler` ADL | `_triggerADL` force-reduces counterparties (bankruptcy price) | n/a | n/a |

The gap vs HLP: **no single vault both quotes markets and acts as the liquidation
counterparty while paying one PnL stream to depositors.** The roles are split across three
contracts + the ADL routine.

---

## 2. How the leaders do it

### 2.1 Hyperliquid — HLP (Hyperliquidity Provider)
A single **community-owned** vault that: provides liquidity via **multiple market-making
strategies**, **performs liquidations**, supplies USDC in Earn, and **accrues a share of
trading fees**. Depositors share its PnL directly; **4-day withdrawal lock** from last deposit.

Liquidation flow (mark price = external CEX prices blended with book state; maintenance margin
= ½ initial at max leverage → **1.25%–16.7%**):
1. **Book liquidation** — Clearinghouse sends market orders to close; if filled, residual
   collateral returns to the trader.
2. **Partial (>$100k)** — only **20%** sent as a market order, **30s cooldown**, then the full
   remaining size.
3. **Backstop** — if equity falls below **⅔ of maintenance margin**, the **liquidator vault**
   (a component strategy of HLP) takes over the position. The maintenance margin is **not
   returned** to the user — that buffer keeps backstop liquidations profitable on average.
4. **PnL → community** entirely through HLP. Liquidations are usually profitable (positions
   acquired at distressed prices), but **"toxic" unwinds** in thin liquidity can lose (the
   Mar-2025 whale event cost HLP ~$4M → BTC leverage capped 40x, ETH 25x).

```mermaid
sequenceDiagram
    participant T as Trader (underwater)
    participant CH as Clearinghouse
    participant OB as Order Book
    participant LV as Liquidator Vault (HLP)
    participant HLP as HLP depositors
    T->>CH: equity < maintenance margin
    CH->>OB: market order(s) to close (20% if >$100k, 30s cooldown)
    alt book absorbs
        OB-->>T: closed; residual collateral returned
    else equity < 2/3 maintenance margin
        CH->>LV: hand position to liquidator vault (keep maintenance margin as buffer)
        LV->>HLP: realized PnL streamed to depositors
    end
```

### 2.2 Extended — the Vault
**One vault handles ALL liquidations** *and* **quotes every market** (automated MM with global
+ per-market exposure controls, dynamic capital allocation, spread management). It earns a
**1% liquidation fee** on healthy liquidations + exchange fees. Two yields: **Base** (trading +
liquidation activity, all depositors) and **Extra** (share of exchange fees, activity-based).

**Loss controls (the important part):**
- **Global daily limit** — the vault can't be depleted by more than **15% in a day** for
  liquidations.
- **Per-market daily budget** — each market may use only a fraction of vault balance / 24h;
  **less liquid assets get a smaller share**.
- **Per-liquidation loss cap** — a hard cap on the max absorbable loss per single liquidation.

A liquidated user's collateral/XVS is always withdrawable; if still unhealthy, the regular perp
liquidation proceeds against the vault.

### 2.3 Lighter — LLP (Liquidity Pool / Insurance Fund)
A **public pool** that is simultaneously **liquidity provider, price generator, and risk
buffer**. Multi-tier margin: **Initial → Maintenance → Close-out**.
- **Partial liquidation**: engine orders the underwater account's positions by heuristic and
  sends **IoC limit orders at "zero price"** for the full size, one by one; if filled better
  than zero, it takes up to **1%** fee → LLP.
- **Close-out**: below the close-out margin, **LLP closes all positions and absorbs the
  remaining collateral**.
- **ADL** is the **last resort** when LLP + book can't cover. LLP depositors share platform
  profits *and* counterparty losses.

### 2.4 Side-by-side

| | Hyperliquid HLP | Extended Vault | Lighter LLP | marginX (today) |
|---|---|---|---|---|
| One vault MM + liquidate | ✅ | ✅ | ✅ | ❌ (split: MMVault + Backstop + IF) |
| Liquidation counterparty of last resort | liquidator vault (HLP strat) | the Vault | LLP | BackstopVault (loss-only, not a quoting counterparty) |
| Depositor PnL share | ✅ (4-day lock) | ✅ (Base+Extra) | ✅ | BackstopVault shares exist, unused as MM |
| Liquidation fee | premium / buffer | **1%** | **1%** | `liquidationFee` → InsuranceFund |
| Per-market / daily loss caps | leverage caps | **15%/day + per-market + per-liq** | tiered | `MAX_UTILIZATION 80%`, no daily/per-liq cap |
| ADL | (not documented) | — | last resort | ✅ `_triggerADL` |
| Backstop trigger | equity < ⅔ maintenance | unhealthy | < close-out margin | book-empty residual |

**Takeaways for marginX:** (a) unify into one vault; (b) the vault must be a **quoting
counterparty**, not just a loss sink; (c) adopt **Extended-style loss caps** (daily global +
per-market budget + per-liquidation cap) — we only have a utilization cap; (d) keep ADL as the
tier *between* counterparty book liquidity and vault socialization; (e) a **withdrawal lock**
(HLP 4-day) protects the vault from run-on-bank during stress.

---

## 3. Ideal design — marginX HLP Vault

### 3.1 Principle
**One ERC4626 vault** (`HLPVault`) that is registered as (1) an **authorized market-making
adapter** quoting across markets, and (2) the **liquidation counterparty of last resort**,
sitting in the waterfall **above** bad-debt socialization. Depositors get one share price =
NAV = `idle USDC + Σ mark-to-market of vault positions + accrued fees − liabilities`.

### 3.2 Where it sits in the liquidation waterfall (ideal)

```mermaid
flowchart TD
    A[Liquidatable position] --> B[1. Book: reduce-only IOC<br/>open competition / MM quotes]
    B -->|filled| OK[penalty --> InsuranceFund]
    B -->|residual| C[2. ADL profitable counterparties<br/>bankruptcy price, bounded scan]
    C -->|residual| D[3. HLP VAULT takes over the position<br/>as counterparty at bankruptcy price]
    D --> E{Vault risk checks<br/>daily global cap / per-market budget / per-liq cap}
    E -->|within limits| F[Vault books the position<br/>marks it, unwinds via its MM quotes]
    E -->|exceeds limits| G[4. InsuranceFund cover]
    G -->|insufficient| H[5. SOCIALIZE residual<br/>totalSocializedDebt]
    F --> I[Vault PnL --> depositor NAV<br/>liquidation usually profitable]
```

Key change vs today: insert **"HLP vault takes over the position"** as a real tier (the vault
*holds and unwinds* the position via its own quotes), instead of `BackstopVault` only eating a
PnL number. This is the Hyperliquid/Extended/Lighter model and is what makes liquidations a
**yield source** rather than only a loss sink.

### 3.3 Vault as market maker

```mermaid
flowchart LR
    subgraph HLPVault
      NAV[NAV / shares] --> Alloc[Capital allocator<br/>per-market budget + spread mgmt]
    end
    Alloc -->|quotes bids/asks| OBs[(Per-market order books)]
    OBs -->|fills| Pos[Vault positions]
    Pos -->|funding + spread + fees| NAV
    Liq[Liquidation engine] -->|hands over residual positions| Pos
```

The vault runs (or co-runs) the market-making that `MarketMakingVault` does today, but its
inventory and the **liquidation takeovers share one balance sheet** — so liquidation inventory
is hedged/unwound by the same quoting logic (exactly how HLP nets liquidation positions against
its MM book).

### 3.4 Deposit / withdraw (ERC4626 + lock)

```mermaid
sequenceDiagram
    participant U as Depositor
    participant V as HLPVault (ERC4626)
    U->>V: deposit(USDC)
    V-->>U: mint shares = USDC / pricePerShare
    Note over V: lock window starts (e.g. 4 days, HLP-style)
    Note over V: NAV moves with MM PnL + liquidation PnL + fees − socialized loss
    U->>V: requestWithdraw(shares) (after lock)
    V-->>U: burn shares; pay shares * pricePerShare − withdrawFee
```

Reuse `BackstopVault`'s share math (dead-shares anti-inflation, 10% performance fee, 0.1%
withdraw fee) + add an HLP-style **lock window** and a **withdrawal queue** for stress periods.

### 3.5 Risk controls (adopt Extended's, keep ours)
| Control | Source | Purpose |
|---|---|---|
| `MAX_UTILIZATION` (OI vs vault size, 80%) | ours (BackstopVault) | cap vault exposure |
| **Daily global loss cap (≤15%/day)** | Extended | stop a bad day from draining the vault |
| **Per-market daily budget** (fraction/24h, smaller for illiquid) | Extended | isolate toxic markets |
| **Per-liquidation loss cap** | Extended | bound a single toxic unwind (the HLP $4M lesson) |
| Withdrawal lock + queue | Hyperliquid | prevent run-on-bank during drawdown |
| Maintenance-margin buffer not returned on backstop | Hyperliquid | keep backstop +EV |
| Leverage caps per market | Hyperliquid (post-incident) | reduce attack surface |

### 3.6 Accounting invariants
- `pricePerShare = NAV / totalShares`, `NAV = idleUSDC + Σ(markToMarket positions) + accruedFees − pendingSocialization`.
- A liquidation takeover must **conserve OI**: vault gains the exact size the liquidated trader
  loses (long OI == short OI always — see `PERP_MECHANISM_COMPARISON.md`).
- Socialization only when **vault NAV ≤ 0 for the market's budget** (last resort), mirroring
  Lighter/our backstop.

---

## 4. Phased plan

- **P0 — Research memo (this doc).** Decide unify-vs-extend. Recommendation: **extend
  `BackstopVault` into `HLPVault`** (it already has shares + PnL absorption + socialization) and
  fold `MarketMakingVault` quoting into it, rather than a green-field contract.
- **P1 — Vault-as-counterparty tier.** Register the vault as an authorized perp adapter; route
  the post-ADL residual to it (`vault takes the position` instead of `updateVaultPnL(loss)`).
  Add the Extended loss caps (daily global, per-market budget, per-liq). Measure with the
  existing liquidation E2E suite (`E2EArcLiqSuite*`, `E2EArcSocialize`).
- **P2 — Vault market making.** Drive MM quotes from vault capital (absorb `MarketMakingVault`),
  one balance sheet for MM + liquidation inventory; spread/allocation logic per market.
- **P3 — Depositor UX.** ERC4626 deposit/withdraw + lock + queue + perf fee; surface vault APY,
  NAV, drawdown on the STATS dashboard (we already snapshot `backstop_vault` / `bad_debt`).
- **P4 — Permissionless user vaults** (Hyperliquid-style leader/follower), optional.

Every contract change follows the **Mandatory Post-Change Workflow** (sizes, full tests, fuzz,
Pashov + Nemesis audits, Monad/non-Monad parity) before shipping.

---

## 5. Open questions for review
1. **One global vault** vs **per-market vaults** (Hyperliquid = one HLP + permissionless user
   vaults; Extended = one vault). Recommend: one global `HLPVault` first.
2. Should the vault **always** quote (continuous MM) or only act as **backstop counterparty**?
   (HLP/Extended do both; Lighter LLP does both.) Recommend both, gated by per-market budget.
3. Funding interaction: our funding is **OI-imbalance-driven** (an outlier — see
   `PERP_MECHANISM_COMPARISON.md`); a quoting vault that takes the minority side earns funding
   like HLP **only if** funding is **premium-based**. This couples to the premium-funding
   upgrade (`project_perp_funding_liq_upgrade`).
4. Withdrawal lock length (HLP = 4 days) vs capital efficiency.
5. Insurance fund vs vault: keep `InsuranceFund` as a **separate** senior tranche (covers
   funding shortfall + small penalties) above the vault, or merge? Recommend keep separate
   (senior/junior split).

---

## 6. Sources
- Hyperliquid — Protocol Vaults: https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/vaults/protocol-vaults
- Hyperliquid — Liquidations: https://hyperliquid.gitbook.io/hyperliquid-docs/trading/liquidations
- Hyperliquid — Margining: https://hyperliquid.gitbook.io/hyperliquid-docs/trading/margining
- Extended — Vault: https://docs.extended.exchange/extended-resources/vault
- Lighter — Liquidations & LLP (Insurance Fund): https://docs.lighter.xyz/perpetual-futures/liquidations-and-llp-insurance-fund
- Lighter — Whitepaper: https://assets.lighter.xyz/whitepaper.pdf
- marginX internal: `docs/PERP_MECHANISM_COMPARISON.md`, `docs/FUNDING_FEES_LIQUIDATION.md`, `docs/ADL_UPGRADE_PLAN.md`, `src/perpetual/{PositionHandler,BackstopVault,InsuranceFund}.sol`, `src/MarketMakingVault.sol`.
