Protocol Overview

Liquidation

How liquidation works on Project 0, including classic and receivership approaches, and the bankruptcy flow.

Liquidation keeps Project 0 solvent. When a borrower's account becomes unhealthy (Maintenance health below zero), third-party liquidators can step in to repay some of the borrower's debt in exchange for seizing collateral at a discount.

Liquidation is open and permissionless. Anyone can liquidate unhealthy accounts.

When Can an Account Be Liquidated?

An account is eligible for liquidation when its Maintenance health drops below zero:

Maintenance Health = Sum(Asset Value * Maintenance Asset Weight) - Sum(Liability Value * Maintenance Liability Weight) < 0

Asset weights discount collateral (below 1.0) and liability weights inflate debt (at or above 1.0), so this check is more permissive than the Initial check used for new borrows.

At any point, the borrower can withdraw or repay themselves to avoid paying the liquidation premium.

Classic Liquidation

The original method, using the lending_account_liquidate instruction. The liquidator must have their own P0 Account.

The liquidator seizes a portion of the borrower's collateral (Asset A) and in exchange assumes some of the borrower's debt (Liability B):

  • If a liquidator reclaims $A in assets, they only have to assume (1 - 0.025) * A in liabilities. The liquidator keeps this 2.5% premium.
  • The borrower only receives a debt repayment of (1 - 0.025 - 0.025) * A. The additional 2.5% goes to the insurance fund.

Classic liquidation cannot raise an account's health above zero. The liquidator can only bring health up to zero at most, preventing over-liquidation.

How do I know when accounts are eligible to be liquidated?

Most liquidators keep a running inventory of all accounts above some dollar threshold, along with current prices for all relevant assets. This is a considerable endeavor with 500k+ accounts.

How do I know how much asset to claim?

Start conservatively, around 70-80% of the amount health is actually negative, since prices may change by the time the transaction lands. Since liquidation cannot raise health above zero, seizing too much will cause the instruction to fail.

I landed a liquidation, now what?

Most liquidators rebalance their inventory as soon as possible: withdraw the asset, swap to the debt token, and repay the debt. Some attempt to do this within the same transaction, though this is not always possible with larger accounts due to transaction size and compute limits. Note that taking on a liability carries risk: there is no guarantee a profitable swap route exists to exit that liability.

Can I use a flashloan in liquidation?

Yes. The liquidator can use a flashloan to avoid keeping collateral on hand. The transaction would look something like:

Start flashloan
Liquidate user
Withdraw asset A from liquidator account
Swap A to debt B on e.g. Jupiter
Repay debt B
End flashloan

In practice, this is considerably difficult to pack into a single transaction.

Do I have to crank all Switchboard oracles before liquidating?

Yes, no stale oracles are permitted for either the liquidatee or the liquidator. Typically, you send a crank transaction just before the liquidation. Some operators prefer to use a Jito bundle, but sending a crank instruction with a small delay before the liquidation typically suffices.

Receivership Liquidation

A newer, more flexible approach using start_liquidation and end_liquidation. The liquidator temporarily takes control of the unhealthy account, enabling them to withdraw and repay as if they are the user. At the end, the protocol validates that account health actually improved.

The process generally looks like this:

ComputeBudgetProgram (optional)
Start Liquidation
Withdraw A
Swap A to B via Jupiter or similar
Repay B
End Liquidation

Within the transaction, the liquidator can withdraw, swap, and repay, keeping whatever is left over. This enables liquidators to operate without holding any funds or creating a P0 account at all.

Why Use Receivership Over Classic?

  • No collateral needed. No account and no starting capital required (just SOL for gas).
  • Higher profit potential. Up to 10% (configurable by the global fee admin via FeeState.liquidation_max_fee), vs 2.5% in classic.
  • No slippage risk. If no profitable swap route exists between A and B, abort the entire transaction.

Profit is defined as:

Seized <= Repaid * (1 + max_fee)

Where Seized is the equity value withdrawn (in $) and Repaid is the equity value repaid (in $). Equity value is the price of the token without any weights applied, but inclusive of oracle confidence interval adjustments.

Receivership Rules

  • start_liquidation must be the first instruction in the transaction (after ComputeBudgetProgram and Kamino refreshes).
  • end_liquidation must be the last instruction. Nothing can come after it.
  • The only other P0 instructions allowed between start and end are Withdraw and Repay.
  • Account health must improve between start and end. All health checks are ignored during withdraw and repay; only the final health matters. This means you can withdraw BEFORE repaying.
  • The liquidator cannot open new positions.
  • The liquidator can freely fully withdraw or fully repay positions, but cannot close them. A position withdrawn or repaid in full therefore still requires passing the oracle for that position at end, unlike a withdraw_all or repay_all in normal circumstances.
  • Isolated positions (asset weight of zero) and positions with a price of 0 cannot be withdrawn during liquidation.
  • The liquidator pays a nominal fee in lamports to use this service, automatically billed to the global fee wallet at end. See FeeState.liquidation_flat_sol_fee for the current fee.

The first liquidator to use receivership on any given account inits a liquidation record (1:1 for that account) and pays a nominal amount of rent to create it. This record stores historical information about the last few liquidation events on that account. Currently, the rent for this record cannot be recovered.

Tips

  • Maintaining a small balance of various assets reduces the need to swap within every liquidation transaction.
  • A large pool of LUTs is typically required to fit a liquidation + swap into transaction size limits, especially for large accounts.
  • Profit is ultimately defined by slippage. Pick asset A and liability B such that swapping A to B (and A to your preferred currency) incurs minimal slippage. For example, SOL to LST and SOL to USDC are typically highly liquid.
  • If liquidating an account with Kamino positions, include the refreshes. Kamino positions use a different withdraw instruction.

Bankruptcy

Bankruptcy is rare. It can only occur when (1) liquidators have not been running properly (e.g. due to congestion), (2) an asset is too illiquid for liquidators to safely clear, or (3) an asset's price changes drastically before liquidators can respond.

A user is technically bankrupt after all their remaining assets are liquidated, at which point they have 0 assets and a non-zero amount of liabilities.

Discharging a Bankruptcy

First, liquidators consume all the remaining assets the user has. If the user has A dollars in assets and B dollars in liabilities (in equity value, excluding weights), B > A. After liquidation completes, assets = 0 and remaining liabilities = B - A + X, where X is the liquidation premium and insurance.

Next, the Group administrator runs handle_bankruptcy on the user. For Banks where PERMISSIONLESS_BAD_DEBT_SETTLEMENT_FLAG is enabled, anyone can do this. The instruction performs the following:

  1. If the Bank's insurance fund has sufficient reserves, it covers the bad debt.
  2. If the insurance fund is insufficient, the remainder is covered by taking liquidity out of the Bank, reducing the asset share value. This socializes the loss to all remaining depositors.
  3. If both the insurance fund and remaining liquidity are exhausted (super-bankruptcy), the Bank is killed. The asset share value is set to zero, wiping out all holdings for all depositors. This state is irrecoverable and the Bank is permanently disabled.

Bankruptcy has never been executed in the main pool as of November 2025. Almost all bankruptcies occur in the Arena, where riskier assets experience extreme volatility.

What happens if bankruptcy is not executed?

If handle_bankruptcy is never called on a bankrupt user, the remaining depositors can never withdraw the full balance in that Bank. The last few depositors who try to withdraw will find there are not enough funds, proportional to the liabilities held by bankrupt users.

When a user goes bankrupt with multiple liabilities, which banks absorb the bad debt?

The liquidator gets to pick which liabilities stay on the user's books. This means the liquidator effectively chooses which Banks absorb the bad debt.

On this page