> For the complete documentation index, see [llms.txt](https://docs.jaawle.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.jaawle.xyz/risk/liquidation-and-insurance.md).

# Liquidation and insurance

A position is closed by force when its equity no longer covers the maintenance margin. The `PositionManager` decides liquidatability, the keeper (then anyone) executes, and the `InsuranceVault` pays the pool whatever the trader's collateral could not.

## Maintenance margin

```
equity      = collateral + unrealised P&L at the mid + dividend adjustment - borrow owed - closeFee
closeFee    = size x takerFeeBps
maintenance = size x maintenanceBps
liquidatable when equity <= maintenance
```

`maintenanceBps` is 50 (0.50 % of size) on stock, ETF and crypto markets and 200 (2.00 %) on meme markets in the local deployment.

**Off-hours multiplier.** Outside the Regular session the maintenance level is multiplied by `offHoursMaintenanceMult` (1.5, so 0.75 % on stocks). It applies in the Extended session, where liquidations execute, and while Closed, where they are only detected. A position that is safe at 16:00 can be liquidatable at 16:01 by the multiplier alone.

The contract answers `liquidatable` through `getPosition`, and `flag` re-derives it on-chain, so the keeper never computes solvency itself.

## While the market is closed

Between sessions the PriceFeed serves the closing mark. `getPosition` and `flag` keep working on that mark, so a position can be flagged overnight, but `liquidate` (like any close) reverts `SessionClosed` until the first live print. A position that is under water at the close is liquidated at the first print of the next session, which may be far past the liquidation price: the gap is the trader's up to the collateral, and the insurance vault's beyond that. Because the priority window will have passed by then, a position flagged while closed can be liquidated by anyone at that first print.

## Who liquidates

1. **The keeper** (`KEEPER` role) may call `liquidate(account, pool, isLong)` at any time the position is liquidatable. The keeper scans every open position on a schedule and after every position event.
2. **Anyone** may call `flag(account, pool, isLong)` on a liquidatable position. The flag records `liquidatableSince` and emits `PositionFlagged`; flagging is not gated by the pause flag or the session.
3. **Anyone** may call `liquidate` once `keeperPriorityWindow` seconds (30) have passed since the flag; before that a non-keeper caller gets `KeeperPriority(until)`.

The flag is cleared when the position is reduced by its owner; a position that becomes healthy again simply is not liquidatable, since `liquidate` re-checks the condition at the moment of the call.

## What a liquidation does

`liquidate` is a decrease with `isLiquidation = true`. It fills at the bid (long) or ask (short) like any close, in the Regular or Extended session, and pays the taker fee (doubled in Extended hours) and the borrow and funding leg the same way.

1. **Chunk size.** If the position is larger than `partialLiquidationThresholdUsd` ($50 000) it is closed in chunks of `partialLiquidationBps` (30 %) of its size; smaller positions are closed in full. Each chunk is a separate call that must find the position still liquidatable at the mid over its full size.
2. **Settlement.** Realised P\&L on the closed notional, the dividend adjustment, the borrow leg and the fee are settled against the collateral, giving `remaining`.
3. **Penalty.** `liquidationPenaltyBps` (150, 1.5 %) of the closed notional, capped at `remaining`. `liquidatorRewardBps` (30 %) of the penalty is paid to `msg.sender`; the rest goes to the insurance vault.
4. **The rest of the collateral.** On a full liquidation whatever is left after the penalty goes to the pool, which carried the risk. On a partial liquidation it stays as the collateral of the reduced position, whose snapshots reset to the current indices.
5. **Event.** `PositionLiquidated(account, pool, isLong, sizeUsd, price, collateralLost)`: on a full liquidation `collateralLost` is the whole collateral; on a partial one it is the penalty.

With a 0.50 % maintenance level and a 5 bps close fee a position is liquidated when about 0.45 % of its notional is left as equity, so the 1.5 % penalty is almost always capped by what remains. The maintenance level, not the penalty, is what protects the pool.

## Bad debt and the insurance vault

If the settlement leaves `remaining` below zero the trader owes more than the collateral. The trader can only lose the collateral, so the PositionManager asks the insurance vault for the shortfall, rounded up to the cent:

```
shortfall = -(collateral + realised)
covered   = InsuranceVault.cover(pool, shortfall)
```

`cover` pays the least of the shortfall, `maxCoverPerTx` ($50 000), what is left of `maxCoverPerDay` ($200 000, rolling from the first payment of each day) and the vault's balance. Whatever is covered is added to what the pool receives, so the pool is made whole up to that amount. Anything not covered is added to `PositionManager.badDebtUsd` and emitted as `BadDebt(pool, account, shortfall, covered)`; it is a loss of the pool, that is, of its LPs.

When the collateral plus the cover is not even enough for the fee and the borrow leg, those are paid first (borrow before fee) and the pool books the rest as the trader's loss; nothing is left for a penalty.

## The insurance vault

The `InsuranceVault` is protocol-owned USDC with no LP token. It is funded by:

* `insuranceFeeBps` (10 %) of every taker fee and of every borrow and funding leg, forwarded by the PositionManager on every settlement;
* 70 % of every liquidation penalty;
* anything else sent through `fund(amount)`, which anyone may call (the local deployment seeds it with $100 000).

Only the `POSITION_MANAGER` role may call `cover`. Only ADMIN (the timelock) may `withdraw` or change the caps with `setLimits`. The caps default to zero on an unconfigured vault, so the vault is off rather than "always on". The treasury takes no share of penalties: liquidations fund the backstop, not the platform.

`stats()` returns total funded, total covered, covered today and both caps.

## Caps at a glance

| parameter                        | local value                                              | field                                                                |
| -------------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------- |
| maintenance                      | 0.50 % of size (2.00 % memes)                            | `MarketConfig.maintenanceBps`                                        |
| off-hours maintenance multiplier | 1.5                                                      | `RiskConfig.offHoursMaintenanceMult`                                 |
| liquidation penalty              | 1.5 % of closed notional, capped by remaining collateral | `RiskConfig.liquidationPenaltyBps`                                   |
| liquidator reward                | 30 % of the penalty                                      | `RiskConfig.liquidatorRewardBps`                                     |
| partial liquidation              | above $50 000, 30 % chunks                               | `RiskConfig.partialLiquidationThresholdUsd`, `partialLiquidationBps` |
| keeper priority                  | 30 s after a flag                                        | `RiskConfig.keeperPriorityWindow`                                    |
| insurance fee                    | 10 % of fees and of the borrow leg                       | `RiskConfig.insuranceFeeBps`                                         |
| cover per transaction            | $50 000                                                  | `InsuranceVault.maxCoverPerTx`                                       |
| cover per day                    | $200 000                                                 | `InsuranceVault.maxCoverPerDay`                                      |

A full liquidation is worked through in [Worked examples](/protocol/worked-examples.md#c-the-long-in-a-is-liquidated).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.jaawle.xyz/risk/liquidation-and-insurance.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
