This page is the authoritative instruction reference. For code that actually composes these instructions, see
products/cpmm/code-demos. For error-code meanings see reference/error-codes.Instruction summary
Status bitmask: each pool’s
status is a u8 where bit 0 = deposit disabled, bit 1 = withdraw disabled, bit 2 = swap disabled (PoolStatusBitIndex { Deposit, Withdraw, Swap } in the program). A clear bit means the operation is allowed; a set bit means it is paused. UpdatePoolStatus takes a raw u8 and overwrites the existing value.
The next sections go through each in detail. Account ordering follows the CPMM IDL; the SDK and the Rust client in raydium-cp-swap/programs/cp-swap/src/instructions match this order.
Initialize
Create a new CPMM pool.
Arguments
* pool_state signs only on the random-keypair path; the canonical-PDA path runs without pool_state signing.
Preconditions
- Mints are sorted (
token_0_mint < token_1_mintby byte order). - Neither mint uses an extension outside the CPMM allow-list (
TransferFeeConfig,MetadataPointer,TokenMetadata,InterestBearingConfig,ScaledUiAmount) — seeproducts/cpmm/accounts. A small per-mint allow-list inside the program bypasses the check for case-by-case onboarding. creatorhas at leastinit_amount_0andinit_amount_1in the respective ATAs.amm_config.disable_create_pool == false.
pool_stateexists withlp_supply = sqrt(init_amount_0 * init_amount_1) − LOCKED_LP.- The LP starter of
LOCKED_LP(100lamports of LP token) is permanently locked in the pool —pool_state.lp_supplyrecordsliquidity − 100while100LP units remain outside circulation, preventing the pool from being fully drained and dividing by zero. observation_stateis initialized;observation_index = 0andpool_id = pool_state.key().create_pool_feelamports are transferred from the creator to the receiver and synced as native SOL (it is a wSOL ATA).- The pool’s status bitmask is
0(deposit / withdraw / swap all enabled). enable_creator_fee = falseandcreator_fee_on = BothToken.Initializedoes not support enabling the creator fee — that path isInitializeWithPermission.open_timeis bumped toblock_timestamp + 1if the caller passed a value<= block_timestamp. Swaps are rejected beforeopen_time; deposits and withdrawals work immediately.
reference/error-codes)
InvalidInput— mints unsorted, or identical mints.NotSupportMint— blocked Token-2022 extension.ExceededSlippage— rarely; ifinit_amount_0/1result in zero LP due to decimals mismatch.
Deposit
Add liquidity in both tokens proportional to the pool.
Arguments
Math
k’s proportionality — both vaults and lp_supply scale by the same factor.
Postconditions
lp_supply += lp_token_amount.vault_0 += needed_token_0(net of any Token-2022 transfer fee on input).vault_1 += needed_token_1(net of any Token-2022 transfer fee on input).
ExceededSlippage, ZeroTradingTokens, InvalidStatus if deposit is paused.
Withdraw
Burn LP tokens and receive both underlying tokens pro-rata.
Arguments
(Identical to
Deposit; lp_mint is writable because the LP tokens are burned.)
Math
lp_supply -= lp_token_amount.- Vaults send
out_token_0/out_token_1(gross; the user receives net of any Token-2022 transfer fee).
SwapBaseInput
Exact-input swap.
Arguments
The ordering input → output is by the user’s direction, not by the pool’s canonical
token_0 / token_1. The program figures out which vault is which by matching mints.
Math — see products/cpmm/math.
Preconditions
open_time <= now.pool_statusallows swap.- Neither mint paused or frozen for this authority.
amount_in > 0.
ExceededSlippage—amount_out < minimum_amount_out.ZeroTradingTokens— the trade rounds to zero.NotApproved— pool is paused for swaps viaUpdatePoolStatus.InvalidInput— mints do not match either of the pool’s vault mints.
SwapBaseOutput
Exact-output swap.
Arguments
SwapBaseInput.
Math — inverse curve with ceiling, see products/cpmm/math.
Common errors — ExceededSlippage (gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.
CollectProtocolFee
Sweep accrued protocol fees from the vaults to the protocol destination.
Arguments — none.
Accounts
Effect
NotApproved if signer is not protocol_owner.
CollectFundFee
Same shape as CollectProtocolFee but signed by fund_owner and zeroing the fund_fees_* counters.
CollectCreatorFee
Same shape again, signed by pool_state.pool_creator. Only emits transfers if the pool was initialized with a non-zero creator-fee rate.
UpdatePoolStatus
Pause or resume individual operations on a pool. The status field is a bitmask:
Arguments
The admin key is the upgrade authority on the CPMM program — in practice, the Raydium multisig. See
security/admin-and-multisig.
CreateAmmConfig
Create a new fee tier.
Arguments
Preconditions
- No existing
AmmConfigwith the sameindex. protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
UpdateAmmConfig
Change fee rates or ownership on an existing AmmConfig. Takes a param: u8 (discriminator for which field to update) and a value: u64. The value semantics per param are in the source; commonly:
param = 0→trade_fee_rateparam = 1→protocol_fee_rateparam = 2→fund_fee_rateparam = 3→new_protocol_owner(passPubkeybytes as a reinterpret)param = 4→new_fund_ownerparam = 5→create_pool_feeparam = 6→disable_create_pool
AmmConfig on the next swap. No migration; pools simply read the new values.
State-change matrix
Where to go next
products/cpmm/code-demos— runnable TypeScript samples for the above.reference/error-codes— the complete Anchor error table.products/cpmm/fees— the fee-accrual model thatCollectProtocolFee/CollectFundFee/CollectCreatorFeedrain.

