PartyA Liquidation
The PartyA Liquidation Facet handles the decentralized liquidation of insolvent PartyA accounts. Liquidators (addresses with LIQUIDATOR_ROLE) detect insolvency off-chain, then execute a multi-step on-chain process: initiate liquidation, set symbol prices, close positions, and settle with counterparty PartyBs.
Note: In v0.8.5, the following key changes apply:
Deferred Liquidation: A new deferred liquidation flow (
deferredLiquidatePartyA/deferredSetSymbolsPrice) allows the liquidation to reference a historical block and timestamp rather than the current one. This handles cases where the insolvency was detected earlier but the on-chain transaction was delayed.Liquidation Insurance Vault: A cap on per-position liquidator profit (
maxLiquidationProfitPerPosition) redirects excess liquidation fees to a protocol insurance vault. This prevents disproportionately large liquidator payouts and creates protocol revenue that can cover future overdue liquidation deficits.ClearingHouse Takeover: If a PartyA liquidation gets stuck or enters a corrupted state, the ClearingHouse can take it over via
ClearingHouseFacet.takeoverPartyALiquidation. Once taken over, all normal liquidation functions on this facet are blocked — only ClearingHouse functions can proceed. Auto-takeover also occurs when a cross PartyB liquidation encounters a PartyA that is mid-liquidation.Dual LiquidatePositionsPartyA Event:
liquidatePositionsPartyAnow emits two versions of the event — the legacy one and a new one that includesaverageClosedPrices.
Overview
The PartyA Liquidation Facet provides the following key functionalities:
Initiate Liquidation: Marks a PartyA as insolvent using a Muon signature, freezing the account.
Set Symbol Prices: Provides oracle prices for symbols, classifies the liquidation type (NORMAL, LATE, OVERDUE), and applies the insurance vault cap.
Deferred Liquidation: An alternative initiation path that references a historical point in time for the insolvency snapshot.
Liquidate Pending Positions: Cancels all pending quotes, returning trading fees to the PartyA.
Liquidate Open Positions: Closes open positions at the oracle-provided prices.
Settle Liquidation: Distributes remaining funds to counterparty PartyBs and liquidators.
Resolve Dispute: An admin function to correct settlement amounts when a liquidation is disputed.
Liquidation Flow
The standard liquidation follows this sequence:
Liquidation Types
The liquidation is classified during setSymbolsPrice based on how much of the locked balance the deficit consumes:
NORMAL
deficit < LF
Enough LF remains to pay liquidators (subject to insurance vault cap).
LATE
LF ≤ deficit ≤ LF + CVA
LF is fully consumed; deficit eats into CVA.
OVERDUE
deficit > LF + CVA
Both LF and CVA consumed; PartyBs absorb losses.
Insurance Vault Cap (NORMAL liquidations only)
In NORMAL liquidations, the remaining LF (after covering the deficit) is capped at maxLiquidationProfitPerPosition × partyAPositionsCount. Any excess is credited to the liquidationInsuranceVault address. The capped amount is split equally between the two liquidators at settlement.
liquidatePartyA()
Initiates the liquidation of a PartyA. The Muon signature provides the uPnL and total unrealized loss, which the contract uses to verify insolvency. Once called, the PartyA is frozen and no deposits, withdrawals, allocations, or trading operations are permitted.
Function Signature:
Parameters:
partyA: The address of the PartyA to liquidate.liquidationSig: The Muon signature containing uPnL, total unrealized loss, symbol IDs, prices, and a unique liquidation ID.
Access: Requires LIQUIDATOR_ROLE. PartyA must not already be in liquidation.
Events Emitted:
LiquidatePartyA(address liquidator, address partyA, uint256 allocatedBalance, int256 upnl, int256 totalUnrealizedLoss, bytes liquidationId)
setSymbolsPrice()
Sets the oracle prices for symbols at the time of liquidation. Must be called after liquidatePartyA. The Muon signature's liquidationId must match the one from the initiation call. This step classifies the liquidation type (NORMAL/LATE/OVERDUE) and applies the insurance vault cap if applicable. This can be called multiple times to set prices for different batches of symbols.
Function Signature:
Parameters:
partyA: The address of the PartyA in liquidation.liquidationSig: The Muon signature containing symbol IDs and their corresponding prices, with a matching liquidation ID.
Access: Requires LIQUIDATOR_ROLE.
Events Emitted:
SetSymbolsPrices(address liquidator, address partyA, uint256[] symbolIds, uint256[] prices, bytes liquidationId)
deferredLiquidatePartyA()
An alternative initiation path that references a historical block number and timestamp for the insolvency snapshot. This handles cases where insolvency was detected at an earlier point but the liquidation transaction was delayed (e.g., due to network congestion). The Muon signature includes the historical block number, timestamp, and the allocated balance at that point.
Function Signature:
Parameters:
partyA: The address of the PartyA to liquidate.liquidationSig: The Muon deferred signature containing uPnL, total unrealized loss, liquidation ID, the historical block number, timestamp, and allocated balance.
Access: Requires LIQUIDATOR_ROLE.
Events Emitted:
DeferredLiquidatePartyA(address liquidator, address partyA, uint256 allocatedBalance, int256 upnl, int256 totalUnrealizedLoss, bytes liquidationId, uint256 liquidationBlockNumber, uint256 liquidationTimestamp, uint256 liquidationAllocatedBalance)
deferredSetSymbolsPrice()
Sets symbol prices for a deferred liquidation. Functions identically to setSymbolsPrice but uses the DeferredLiquidationSig structure. The liquidationId must match the one from deferredLiquidatePartyA.
Function Signature:
Parameters:
partyA: The address of the PartyA in deferred liquidation.liquidationSig: The Muon deferred signature containing symbol IDs, prices, and matching liquidation ID.
Access: Requires LIQUIDATOR_ROLE.
Events Emitted:
SetSymbolsPrices(address liquidator, address partyA, uint256[] symbolIds, uint256[] prices, bytes liquidationId)
liquidatePendingPositionsPartyA()
Cancels all pending quotes for the PartyA in liquidation. For each pending quote, the opening trading fee is returned to the PartyA's allocated balance. Quote statuses are set to LIQUIDATED_PENDING.
Function Signature:
Parameters:
partyA: The address of the PartyA whose pending positions will be liquidated.
Access: Requires LIQUIDATOR_ROLE.
Events Emitted:
LiquidatePendingPositionsPartyA(address liquidator, address partyA, uint256[] pendingQuoteIds, uint256[] liquidatedAmounts, bytes liquidationId)
liquidatePositionsPartyA()
Closes open positions at the previously set oracle prices. Can be called in batches. If the accumulated settlement amounts diverge from the Muon-reported uPnL beyond an acceptable threshold, the liquidation enters a disputed state, requiring admin intervention via resolveLiquidationDispute.
Function Signature:
Parameters:
partyA: The address of the PartyA whose positions will be liquidated.quoteIds: An array of quote IDs to liquidate in this batch.
Access: Requires LIQUIDATOR_ROLE.
Events Emitted:
LiquidatePositionsPartyA(address liquidator, address partyA, uint256[] quoteIds, uint256[] liquidatedAmounts, uint256[] closeIds, bytes liquidationId)— legacy eventLiquidatePositionsPartyA(address liquidator, address partyA, uint256[] quoteIds, uint256[] liquidatedAmounts, uint256[] closeIds, uint256[] averageClosedPrices, bytes liquidationId)— new event with average closed pricesLiquidationDisputed(address partyA, bytes liquidationId)— if settlement diverges from reported uPnL
settlePartyALiquidation()
Settles the liquidation for one or more counterparty PartyBs. Distributes remaining funds based on the liquidation type and settlement amounts computed during position liquidation. The capped liquidation fee is split equally between the two liquidators (the one who called liquidatePartyA and the one who called setSymbolsPrice).
Can be called by anyone (no role restriction). When all PartyBs are settled, the PartyA exits liquidation state and a FullyLiquidatedPartyA event is emitted.
Important: Settlement with a PartyB that is in cross liquidation is blocked — the ClearingHouse must handle that PartyB's settlement through its own flow.
Function Signature:
Parameters:
partyA: The address of the PartyA to settle.partyBs: An array of PartyB addresses to settle with.
Events Emitted:
SettlePartyALiquidation(address partyA, address[] partyBs, int256[] settleAmounts, bytes liquidationId)FullyLiquidatedPartyA(address partyA, bytes liquidationId)— when all PartyBs have been settled
resolveLiquidationDispute()
Resolves a liquidation dispute by providing corrected settlement amounts. Called by an admin with DISPUTE_ROLE when the accumulated settlement during position liquidation diverges from the Muon-reported uPnL. The admin can set the disputed flag to true to keep the dispute open for further resolution, or false to clear it.
Function Signature:
Parameters:
partyA: The address of the PartyA in the disputed liquidation.partyBs: An array of PartyB addresses involved in the dispute.amounts: Corrected settlement amounts for each PartyB.disputed: Whether the liquidation should remain in disputed state after this resolution.
Access: Requires DISPUTE_ROLE.
Events Emitted:
ResolveLiquidationDispute(address partyA, address[] partyBs, int256[] amounts, bool disputed, bytes liquidationId)
Last updated

