Documentation Index
Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
Use this file to discover all available pages before exploring further.
The invariant
The pool maintainscoin_reserve × pc_reserve = k, where:
- Reserves include committed-on-OpenBook amounts. The AMM’s limit orders remain part of its liquidity — they are not “lost” to the order book, just escrowed there. Computing
koff only the on-chain vault balances underestimates reserves. - The PnL accrual (
need_take_pnl_*) is subtracted so the curve is conserved when the admin sweeps fees. Same principle as CPMM’sprotocol_fees_*exclusion.
Swap* operation enforces k' ≥ k after adding the LP’s fee share back into the reserves.
Fee convention
AMM v4 uses ratio fees (numerator/denominator pairs) rather than the1/1_000_000 convention of CPMM / CLMM. The on-chain Fees struct (see Fees::initialize in the program source) defaults to:
- Total swap fee:
swap_fee = amount_in × 25 / 10_000 = 0.25%of the gross input. - Protocol share:
pnl_numerator / pnl_denominator = 12 / 100 = 12%of the swap fee, which works out to0.25% × 12% = 0.03%of volume. This share accrues to the PnL counters and is swept byWithdrawPnl. - LP share: the remaining
88%of the swap fee, which works out to0.25% × 88% = 0.22%of volume. Stays in the pool and inflatesk. - No fund share. AMM v4 does not have the CPMM/CLMM fund-fee split.
pnl_numerator / pnl_denominator is a fraction of the fee, not of trade volume — a common misreading of these field names.
trade_fee_numerator / trade_fee_denominator (also 25 / 10_000) is a separate field used by the OpenBook integration when computing fee-inclusive prices for the AMM’s grid of limit orders; it equals swap_fee by default but is read from a different code path.
Deviations from these defaults are rare but do exist on a handful of legacy pools; always read the fees from AmmInfo.fees before quoting.
Direct swap math (AMM path)
The simplest case: user swaps against the pool’s vaults without interacting with OpenBook. The pool’s internal reserves (including on-book allocations) are the denominator. SwapBaseIn (exact input):coin_vault_balance + coin_posted_on_openbook + ... (the AMM’s vault plus the tokens it had locked into OpenBook orders). As of the OpenBook deactivation, the on-book balance is zero, so the effective reserves equal the raw vault balances. The MonitorStep / implicit-settle path that used to refresh the OpenBook side is no longer needed in practice.
SwapBaseOut (exact output):
Order-book interaction (historical)
No longer active. The grid construction described in this section reflects how AMM v4 originally mirrored the curve onto an OpenBook market. The OpenBook integration has been deactivated; pools no longer post or maintain orders on OpenBook. The math below is preserved for context — it explains what the on-chain
target_orders / amm_open_orders accounts were sized for and why the program still validates MonitorStep-related parameters even though the keeper no longer cranks them.AmmInfo parameters:
depth— number of price levels per side.amount_wave— base unit of size per level.min_size,coin_lot_size,pc_lot_size— OpenBook market constraints.state_data.swap_acc_coin_fee,swap_acc_pc_fee— cumulative fee counters since lastTakePnl.
target_orders computed in build_orders and compared with amm_open_orders each MonitorStep. Any divergence results in cancellations + new posts. Freshly filled orders on OpenBook settle into the pool vaults on the next operation that refreshes the OpenBook side.
Integrators rarely need to compute the grid — the Raydium keeper maintains it — but it is useful to know that:
- A pool with significant on-book liquidity has that liquidity contributing to
k, not sitting idle. - A stale OpenBook market (event queue full, cranks blocked) prevents grid updates; the AMM can then quote prices that diverge from the visible order book until the next crank.
Settlement step (PnL)
The 0.03% protocol share accrues intostate_data.need_take_pnl_coin and state_data.need_take_pnl_pc. TakePnl moves these amounts out of the vaults to the admin-specified destination, then zeroes the counters.
Crucial property: reserves in the invariant are always computed minus accrued PnL, so TakePnl does not move the curve. This matches the CPMM convention.
Worked example
Pool state:coin_reserve = 1_000_000_000_000(1,000,000 coin-side; 6 decimals)pc_reserve = 2_000_000_000_000(2,000,000 pc-side; 6 decimals)- Fees: default
swap = 25/10_000,pnl = 3/10_000.
SwapBaseIn exact-input 1_000_000_000 coin (1,000 coin).
2_200_000) is not broken out anywhere — it is simply the residual that raises k'.
Precision rules
- Reserve multiplications use
u128; final divisions round toward zero. swap_feerounds up (so the pool does not undercharge).amount_inforSwapBaseOutrounds up (so the user does not underpay).- Pools with extreme reserve ratios can hit
ZeroTradingTokenson very small inputs; same convention as CPMM.
Limitations vs CPMM
- AMM v4’s reserves include the OpenBook-escrowed portion, so an integrator cannot quote correctly from
getTokenAccountBalancealone. Always fetch the full state (vaults +open_orders.free+open_orders.locked), or use the SDK / API quote. - AMM v4 does not expose a structured on-chain TWAP. External consumers that want an AMM-v4-backed price must compute it themselves from trade logs.
- Token-2022 is not supported.
Where to go next
products/amm-v4/instructions— whereSwapBaseIn,Deposit, etc. plug in.products/amm-v4/fees— full fee mechanics,TakePnldetails.algorithms/constant-product— the shared derivation.
- Raydium AMM program source —
raydium-io/raydium-amm - Raydium SDK v2
Liquiditymodule


