RemoveLiquidity
Withdraw underlying tokens by burning LP shares. RemoveLiquidity is a mutating dispatch primitive. The user-facing interface is uniform — specify a token and an amount — but what “amount” means differs by protocol.
Signature at a glance
Section titled “Signature at a glance”| Protocol | Required call shape |
|---|---|
| Uniswap V2 | RemoveLiquidity().apply(lp, token, user_nm, amount) |
| Uniswap V3 | RemoveLiquidity().apply(lp, token, user_nm, amount, lwr_tick, upr_tick) |
| Balancer | RemoveLiquidity(kind=Proc.REMOVETKN).apply(lp, token_out, user_nm, amount_out) |
| Stableswap | RemoveLiquidity().apply(lp, token_out, user_nm, amount_out) |
Common parameters
Section titled “Common parameters”| Parameter | Type | Description |
|---|---|---|
lp | Exchange | Initialized pool with active liquidity owned by user_nm. |
token | ERC20 | The token side the user is anchoring the withdrawal against. |
user_nm | str | Account name whose LP shares are burned. |
amount | float | Quantity associated with token. The semantics differ by protocol — see the per-protocol sections below. |
Protocol Variants
Section titled “Protocol Variants”Uniswap V2
Section titled “Uniswap V2”The user names a token side and the amount they want from that side. The dispatcher computes the LP-share burn from the pool’s reserves and total liquidity, then calls lp.remove_liquidity(...) and returns both tokens at the current pool ratio.
| Parameter | Type | Notes |
|---|---|---|
amount | float | Amount of the named token to receive. The dispatcher computes liq = amount × tot_liq / res_token and the matching opposite-side amount via the pool ratio. |
from defipy import RemoveLiquidity
# Burn enough LP to receive 5 ETH on the ETH side; receive matching DAI tooout = RemoveLiquidity().apply(lp, eth, "user", 5)# out = {token0: amount0, token1: amount1} — both tokensUniswap V3
Section titled “Uniswap V3”Same single-token-anchored shape as V2, plus the position’s tick range. The dispatcher computes the in-range liquidity to burn from amount and the active sqrt-price (liq = amount * sqrt_P or amount / sqrt_P depending on which side token is on), then calls lp.burn(user_nm, lwr_tick, upr_tick, liq).
| Parameter | Type | Notes |
|---|---|---|
lwr_tick | int | Lower tick of the position to withdraw from. Must match the range you originally minted into. |
upr_tick | int | Upper tick. |
from defipy import RemoveLiquidity
RemoveLiquidity().apply(lp, eth, "user", 5, lwr_tick, upr_tick)You also receive both tokens at the current sqrt-price ratio for that range (returned as {token0: amount0, token1: amount1}).
Balancer
Section titled “Balancer”Single-asset withdrawal is first-class. The constructor kind selects mode:
Proc.REMOVETKN(default) — passamount_out, the token quantity you want; pool computes the LP-share burn vialp.exit_swap_extern_amount_out(...).Proc.REMOVESHARES— pass an LP-share amount to burn; pool computes the resulting token-out vialp.exit_swap_pool_amount_in(...).
| Parameter | Type | Notes |
|---|---|---|
token_out | ERC20 | The single asset you want to receive. |
amount_out | float | Token-out quantity (REMOVETKN) or LP-shares to burn (REMOVESHARES). |
from defipy import RemoveLiquidityfrom balancerpy.enums import Proc
# Withdraw exactly 1 ETH worth out of an ETH/DAI/USDC poolRemoveLiquidity().apply(lp, eth, "user", 1)
# Or burn a known share amount and let the pool compute the ETH-outRemoveLiquidity(kind=Proc.REMOVESHARES).apply(lp, eth, "user", 5)Stableswap
Section titled “Stableswap”Single-asset withdrawal is also first-class on Stableswap. There is no kind parameter — only token-out-amount mode is exposed. The dispatcher calls lp.remove_liquidity(amount_out, token_out, user_nm).
| Parameter | Type | Notes |
|---|---|---|
token_out | ERC20 | The single asset you want to receive. |
amount_out | float | Quantity of token_out to receive. |
from defipy import RemoveLiquidity
RemoveLiquidity().apply(lp, dai, "user", 1000)Like Balancer, the pool absorbs the imbalance against the invariant — that’s why Stableswap doesn’t need a separate WithdrawSwap primitive (see the WithdrawSwap page for the architectural reason).
How RemoveLiquidity interacts with the rest of the pipeline
Section titled “How RemoveLiquidity interacts with the rest of the pipeline”Join→AddLiquidity— pool initialized and LPs deposited.- Pre-withdrawal analytics —
AnalyzePositiondecomposes the LP’s IL vs accumulated fees so the user can decide whether now is the right time to exit. RemoveLiquidity— burn LP, take the proceeds (this primitive).- Compare alternatives —
WithdrawSwap(V2/V3 only) for single-asset exits without an intermediate manual swap.
See also
Section titled “See also”AddLiquidity— the inverse operationWithdrawSwap— single-asset V2/V3 withdrawalAnalyzePosition— non-mutating IL/fee/PnL decomposition- Tutorials → Uniswap V2 — full pipeline walkthrough
- The Primitive Contract — cross-cutting invariants