# PartyB Liquidations

The PartyB Liquidation Facet handles the decentralized liquidation of insolvent isolated-mode PartyBs. Liquidators with the `PARTYB_LIQUIDATOR_ROLE` detect insolvency off-chain and execute a two-step on-chain process: initiate the liquidation, then close positions. The underlying logic is implemented in the `PartyBLiquidationFacetImpl` library.

This facet handles **isolated-mode** PartyB liquidation only. Cross-mode PartyB liquidation is handled by the [`ClearingHouseFacet` ](https://docs.symm.io/contract-documentation/symmio-perps-v0.8.5/diamond-core-facets/clearing-house-facet), since cross-mode liquidation affects all PartyAs simultaneously and requires centralized coordination.

In v0.8.5, the following key change applies:

* **Dual LiquidatePositionsPartyB Event:** `liquidatePositionsPartyB` now emits two versions of the event — the legacy one and a new one that includes `averageClosedPrices`, matching the pattern used in PartyA liquidation.

***

### Overview

The PartyB Liquidation Facet provides the following key functionalities:

* **Initiate PartyB Liquidation:** Marks an isolated-mode PartyB as insolvent with respect to a specific PartyA, using a Muon uPnL signature.
* **Liquidate PartyB Positions:** Closes all open positions between the liquidated PartyB and the PartyA at oracle-provided prices.

***

### liquidatePartyB()

Initiates the liquidation of a PartyB with respect to a specific PartyA. The Muon `SingleUpnlSig` provides PartyB's uPnL, which the contract uses to verify insolvency. Once called, the PartyB is frozen for this PartyA relationship — no trading operations are permitted.

**Function Signature:**

```solidity
function liquidatePartyB(
    address partyB,
    address partyA,
    SingleUpnlSig memory upnlSig
) external whenNotLiquidationPaused notLiquidatedPartyB(partyB, partyA) notCrossLiquidatedPartyB(partyB) notLiquidatedPartyA(partyA) onlyRole(PARTYB_LIQUIDATOR_ROLE);
```

**Parameters:**

* `partyB`: The address of the PartyB to liquidate.
* `partyA`: The address of the PartyA related to this liquidation.
* `upnlSig`: The Muon signature containing PartyB's unrealized PnL for solvency verification.

**Access:** Requires `PARTYB_LIQUIDATOR_ROLE`. PartyB must not already be in liquidation (isolated or cross). PartyA must not be in liquidation.

**Events Emitted:**

* `LiquidatePartyB(address liquidator, address partyB, address partyA, uint256 partyBAllocatedBalance, int256 upnl)`

***

### liquidatePositionsPartyB()

Closes open positions of the liquidated PartyB for a given PartyA at oracle-provided prices. Can be called in batches. When all positions between the PartyB and PartyA are closed (position count reaches zero), a `FullyLiquidatedPartyB` event is emitted, completing the liquidation.

**Function Signature:**

```solidity
function liquidatePositionsPartyB(
    address partyB,
    address partyA,
    QuotePriceSig memory priceSig
) external whenNotLiquidationPaused onlyRole(PARTYB_LIQUIDATOR_ROLE);
```

**Parameters:**

* `partyB`: The address of the PartyB whose positions are being liquidated.
* `partyA`: The address of the PartyA related to the liquidation.
* `priceSig`: The Muon signature containing quote IDs and their corresponding prices for liquidation.

**Access:** Requires `PARTYB_LIQUIDATOR_ROLE`.

**Events Emitted:**

* `LiquidatePositionsPartyB(address liquidator, address partyB, address partyA, uint256[] quoteIds, uint256[] liquidatedAmounts, uint256[] closeIds)` — legacy event
* `LiquidatePositionsPartyB(address liquidator, address partyB, address partyA, uint256[] quoteIds, uint256[] liquidatedAmounts, uint256[] closeIds, uint256[] averageClosedPrices)` — new event with average closed prices
* `FullyLiquidatedPartyB(address partyB, address partyA)` — when all positions between the pair are closed
