Explicit Clearing House Settlements

Clearing House liquidation settlement now declares what each balance movement represents and which market it belongs to, instead of exposing only an unclassified transfer.

Summary

The old Clearing House debit and credit entrypoints moved collateral but did not state whether a movement was realized PnL, funding, or a fee. They also carried no market identifier. An indexer could reproduce the net balance change, but could not attribute it to an economic class or symbol.

v0.8.6 replaces that unclassified path with applyClearingHouseSettlement. The Clearing House supplies final signed components, and the contract emits both the component detail and the exact typed balance changes used to apply it. The same interface serves PartyA takeovers and cross-margin PartyB liquidations.

Settlement input

The call identifies the liquidation and the ledger destination separately:

  • subject, passed to applyClearingHouseSettlement, is the cross-margin PartyB liquidation or PartyA takeover currently in progress.
  • account is the PartyA or PartyB whose balance receives or pays the submitted component.
  • allocationKey selects that account's ledger bucket. PartyB rows use the relevant isolated PartyA key or address(0) for cross margin. PartyA rows normally use address(0); a PartyA takeover may use the designated reimbursement key, address(1), only when debiting reimbursement.
  • The active subject's deallocated pool receives account debits and funds account credits. The entire batch reverts if that pool cannot cover the credits after all debits are included.
struct ClearingHouseSettlement {
    address account;
    address allocationKey;
    uint256 symbolId;
    int256 realizedPnl;
    int256 funding;
    int256 platformFee;
}
  • realizedPnl is final close or liquidation PnL for the market.
  • funding is final funding received or paid for the market.
  • platformFee is a normal platform-fee movement.
  • symbolId must identify an existing market whenever realized PnL or funding is non-zero. A platform fee that is not market-attributed may use symbolId == 0.
  • Values are already final after any Clearing House deficit, haircut, dispute decision, or settlement cap. The core does not infer or reclassify those policies.

There is deliberately no generic adjustment field. A correction is submitted in the economic field being corrected with the opposite sign. This keeps reversals attributable to realized PnL, funding, or platform fees.

Events and reconciliation

event ClearingHouseSettlementComponent(
    address indexed subject,
    address indexed account,
    uint256 indexed symbolId,
    address allocationKey,
    int256 realizedPnl,
    int256 funding,
    int256 platformFee
);

event ClearingHouseAccountSettlement(
    address indexed subject,
    address indexed account,
    address indexed allocationKey,
    int256 amount
);

One component event is emitted for every submitted row. Rows sharing an (account, allocationKey) are accumulated by economic class, then applied using the matching balance-change reason: REALIZED_PNL_IN/OUT, FUNDING_FEE_IN/OUT, or PLATFORM_FEE_IN/OUT.

account amount = sum(realizedPnl + funding + platformFee)
market funding = sum(component.funding grouped by symbolId)
market PnL     = sum(component.realizedPnl grouped by symbolId)

The component sum for an account/allocation group equals ClearingHouseAccountSettlement.amount. The typed balance or reimbursement events show the physical ledger movements. They may net several market rows of the same economic class, while the component events preserve the per-market split.

Validation and execution

The array must be strictly ordered by account, then allocationKey, then symbolId. Duplicate market rows for the same account/allocation group, zero accounts, empty components, and invalid symbols revert. This canonical order lets the contract validate, emit, and settle in one linear pass.

Within each group, positive class totals are credited before negative class totals are debited. The liquidation pool is checked after the batch, and any insufficient account or pool balance reverts the entire transaction, including its logs.

Fees and corrections

Platform fees belong in platformFee. Solver fees are not Clearing House settlement components and liquidatePositionsForClearingHouse has no solver-fee input. PartyA liquidation does not pay PartyB a solver fee, and the Clearing House cannot create one while liquidating positions.

The legacy deallocateForClearingHouse and distributeForClearingHouse selectors remain present only so an upgrade can disable the old ABI entry points. Calls now revert with ClearingHouseFacet: Use explicit settlement. The old unclassified reimbursement enum ordinals are retained as CLEARING_HOUSE_IN_DEPRECATED and CLEARING_HOUSE_OUT_DEPRECATED for historical log decoding.

Indexer contract

Question Canonical source
What did this account receive or pay? ClearingHouseAccountSettlement.amount
How much was funding for one market? Sum signed component funding by symbolId
How much was realized PnL for one market? Sum signed component realizedPnl by symbolId
Which ledger actually changed? Typed PartyA, PartyB, or reimbursement balance-change events
What is the total for the liquidation? Sum account settlement amounts for the same subject

An event-only indexer can therefore recover the final funding, PnL, and platform-fee attribution per market and in total. Transaction calldata or traces are not required for those settled amounts when the complete event stream is available.