Skip to main content

Remove Liquidity

Removes liquidity from a pair by burning LP tokens and receiving the underlying tokens.
A 1% withdrawal fee is applied to liquidity removals. This fee remains in the pool reserves, benefiting remaining LPs.

Withdrawal Fee

When removing liquidity, a 1% fee (LIQUIDITY_WITHDRAWAL_FEE_BPS = 100) is deducted from both token amounts:
amount_out = amount_gross - (amount_gross × 1%)
The fee remains in the pool’s reserves, effectively increasing the value of remaining LP tokens. This mechanism:
  • Discourages short-term liquidity provision
  • Compensates remaining LPs for the impact of withdrawals
  • Reduces potential manipulation via rapid add/remove cycles
Future Enhancement: Optionality to wait for a time period and withdraw for free, or withdraw instantly with the 1% fee.

Accounts

pair
Account<Pair>
required
The pair account.
user_lp_token_account
InterfaceAccount<TokenAccount>
required
User’s LP token account. LP tokens will be burned from here.
user_token0_account
InterfaceAccount<TokenAccount>
required
User’s token0 account. Will receive token0.
user_token1_account
InterfaceAccount<TokenAccount>
required
User’s token1 account. Will receive token1.
user
Signer
required
The user removing liquidity. Must be a signer.

Arguments

liquidity
u64
required
Amount of LP tokens to burn. Must be greater than 0.
min_amount0_out
u64
required
Minimum amount of token0 to receive. Used for slippage protection.
min_amount1_out
u64
required
Minimum amount of token1 to receive. Used for slippage protection.
use anchor_lang::prelude::*;
use omnipair::program::Omnipair;

let remove_liquidity_args = RemoveLiquidityArgs {
    liquidity: 50 * 10u64.pow(9), // 50 LP tokens (9 decimals)
    min_amount0_out: 95 * 10u64.pow(token0_decimals),
    min_amount1_out: 190 * 10u64.pow(token1_decimals),
};

let accounts = AdjustLiquidity {
    pair: pair_pda,
    user_lp_token_account: user_lp_token_account,
    user_token0_account: user_token0_account,
    user_token1_account: user_token1_account,
    user: user.key(),
    // ... other accounts
};

let ctx = CpiContext::new(program_id, accounts);
omnipair::cpi::remove_liquidity(ctx, remove_liquidity_args)?;
{
  "signature": "5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmG5Rk88jH2k9f4w3JHFf7Pjsk3bWqeXrC",
  "slot": 123456789
}