Skip to main content

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.

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

Discriminator nameWho signsWhat it does
Initializepool creatorCreate a new CPMM pool from two mints and an AmmConfig. Permissionless; anyone can call it. Hardcodes enable_creator_fee = false on the new pool. The pool_state account can be either the canonical PDA or a fresh random keypair (see Initialize accounts).
InitializeWithPermissionpayer + a holder of a Permission PDAPermissioned variant of Initialize. The caller (payer) must own a Permission PDA derived from their own pubkey. Used by platforms that need gated pool creation (e.g. LaunchLab graduations). Lets the caller pin creator_fee_on (BothToken / OnlyToken0 / OnlyToken1) and forces enable_creator_fee = true on the new pool. The creator field on pool_state is set to a separately-passed creator account, not the payer. Same canonical-PDA-or-random-keypair flexibility for pool_state as Initialize.
DepositLPAdd liquidity in both tokens; receive LP tokens.
WithdrawLPBurn LP tokens; receive both underlying tokens pro-rata.
SwapBaseInputswapperExact-input swap (amount_in in, ≥ minimum_amount_out out).
SwapBaseOutputswapperExact-output swap (≤ maximum_amount_in in, amount_out out).
CollectProtocolFeeprotocol_owner (from AmmConfig)Sweep accrued protocol fees from vaults.
CollectFundFeefund_owner (from AmmConfig)Sweep accrued fund fees from vaults.
CollectCreatorFeepool_creatorSweep accrued creator fees (if creator fee was enabled).
UpdatePoolStatusadminPause / resume specific operations on a pool via a bitmask.
UpdateAmmConfigadminChange fee rates or the protocol/fund owner on an AmmConfig.
CreateAmmConfigadminCreate a new fee tier (new AmmConfig account).
CreatePermissionPdaadminMint a Permission PDA that allows a specific authority to call InitializeWithPermission.
ClosePermissionPdaadminRevoke a previously-issued Permission PDA.
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
init_amount_0: u64
init_amount_1: u64
open_time:     u64   // Unix timestamp; swaps rejected before this
Accounts (W = writable, S = signer)
#NameWSNotes
1creatorWSPays rent; recorded as pool_state.pool_creator.
2amm_configThe chosen fee tier.
3authorityCPMM global authority PDA.
4pool_stateWS*inited here. Either the canonical PDA ["pool", amm_config, token_0_mint, token_1_mint] or a fresh random keypair — when not the canonical PDA, the program requires pool_state to sign (require_eq!(pool_account_info.is_signer, true)). The random-keypair path lets a creator dodge front-running attempts on the canonical PDA. The downstream PDAs (lp_mint, vaults, observation_state) are derived from pool_state.key() either way.
5token_0_mintSorted: token_0_mint < token_1_mint.
6token_1_mint
7lp_mintWinited here. Authority set to authority.
8creator_token_0WSource ATA for init_amount_0.
9creator_token_1WSource ATA for init_amount_1.
10creator_lp_tokenWDestination for LP (created if missing).
11token_0_vaultWinited here. Owned by authority.
12token_1_vaultW
13create_pool_feeWDestination ATA for the create_pool_fee paid by the creator.
14observation_stateWinited here.
15token_programSPL Token (for LP mint).
16token_0_programSPL Token or Token-2022.
17token_1_programSPL Token or Token-2022.
18associated_token_program
19system_program
20rent
* 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_mint by byte order).
  • Neither mint uses an extension outside the CPMM allow-list (TransferFeeConfig, MetadataPointer, TokenMetadata, InterestBearingConfig, ScaledUiAmount) — see products/cpmm/accounts. A small per-mint allow-list inside the program bypasses the check for case-by-case onboarding.
  • creator has at least init_amount_0 and init_amount_1 in the respective ATAs.
  • amm_config.disable_create_pool == false.
Postconditions
  • pool_state exists with lp_supply = sqrt(init_amount_0 * init_amount_1) − LOCKED_LP.
  • The LP starter of LOCKED_LP (100 lamports of LP token) is permanently locked in the pool — pool_state.lp_supply records liquidity − 100 while 100 LP units remain outside circulation, preventing the pool from being fully drained and dividing by zero.
  • observation_state is initialized; observation_index = 0 and pool_id = pool_state.key().
  • create_pool_fee lamports 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 = false and creator_fee_on = BothToken. Initialize does not support enabling the creator fee — that path is InitializeWithPermission.
  • open_time is bumped to block_timestamp + 1 if the caller passed a value <= block_timestamp. Swaps are rejected before open_time; deposits and withdrawals work immediately.
Common errors (full list in reference/error-codes)
  • InvalidInput — mints unsorted, or identical mints.
  • NotSupportMint — blocked Token-2022 extension.
  • ExceededSlippage — rarely; if init_amount_0/1 result in zero LP due to decimals mismatch.

Deposit

Add liquidity in both tokens proportional to the pool. Arguments
lp_token_amount:   u64   // how many LP tokens to mint to the LP
maximum_token_0:   u64
maximum_token_1:   u64
Accounts
#NameWS
1ownerS
2authority
3pool_stateW
4owner_lp_tokenW
5token_0_accountW
6token_1_accountW
7token_0_vaultW
8token_1_vaultW
9token_program
10token_program_2022
11vault_0_mint
12vault_1_mint
13lp_mintW
Math
needed_token_0 = ceil(lp_token_amount * vault_0 / lp_supply)
needed_token_1 = ceil(lp_token_amount * vault_1 / lp_supply)
require(needed_token_0 <= maximum_token_0, "ExceededSlippage")
require(needed_token_1 <= maximum_token_1, "ExceededSlippage")
No change to 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).
Common errorsExceededSlippage, ZeroTradingTokens, InvalidStatus if deposit is paused.

Withdraw

Burn LP tokens and receive both underlying tokens pro-rata. Arguments
lp_token_amount:   u64
minimum_token_0:   u64
minimum_token_1:   u64
Accounts
#NameWS
1ownerS
2authority
3pool_stateW
4owner_lp_tokenW
5token_0_accountW
6token_1_accountW
7token_0_vaultW
8token_1_vaultW
9token_program
10token_program_2022
11vault_0_mint
12vault_1_mint
13lp_mintW
(Identical to Deposit; lp_mint is writable because the LP tokens are burned.) Math
out_token_0 = floor(lp_token_amount * vault_0 / lp_supply)
out_token_1 = floor(lp_token_amount * vault_1 / lp_supply)
require(out_token_0 >= minimum_token_0, "ExceededSlippage")
require(out_token_1 >= minimum_token_1, "ExceededSlippage")
Postconditions
  • 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
amount_in:            u64
minimum_amount_out:   u64
Accounts
#NameWS
1payerS
2authority
3amm_config
4pool_stateW
5input_token_accountW
6output_token_accountW
7input_vaultW
8output_vaultW
9input_token_program
10output_token_program
11input_token_mint
12output_token_mint
13observation_stateW
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_status allows swap.
  • Neither mint paused or frozen for this authority.
  • amount_in > 0.
Common errors
  • ExceededSlippageamount_out < minimum_amount_out.
  • ZeroTradingTokens — the trade rounds to zero.
  • NotApproved — pool is paused for swaps via UpdatePoolStatus.
  • InvalidInput — mints do not match either of the pool’s vault mints.

SwapBaseOutput

Exact-output swap. Arguments
max_amount_in:  u64
amount_out:     u64
Accounts — same as SwapBaseInput. Math — inverse curve with ceiling, see products/cpmm/math. Common errorsExceededSlippage (gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.

CollectProtocolFee

Sweep accrued protocol fees from the vaults to the protocol destination. Arguments — none. Accounts
#NameWS
1ownerSMust match amm_config.protocol_owner.
2authority
3pool_stateW
4amm_config
5token_0_vaultW
6token_1_vaultW
7vault_0_mint
8vault_1_mint
9recipient_token_0_accountW
10recipient_token_1_accountW
11token_program
12token_program_2022
Effect
transfer pool_state.protocol_fees_token0 from vault_0 to recipient_0
transfer pool_state.protocol_fees_token1 from vault_1 to recipient_1
pool_state.protocol_fees_token0 = 0
pool_state.protocol_fees_token1 = 0
No change to the curve’s effective balances (accrued fees were already excluded). Common errorNotApproved 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:
BitFlagEffect when set
0DEPOSIT_DISABLEDDeposit rejects with NotApproved.
1WITHDRAW_DISABLEDWithdraw rejects.
2SWAP_DISABLEDSwapBaseInput / SwapBaseOutput reject.
Arguments
status: u8      // new bitmask
Accounts
#NameWS
1authoritySMust match the admin key on the CPMM program.
2pool_stateW
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
index:             u16
trade_fee_rate:    u64
protocol_fee_rate: u64
fund_fee_rate:     u64
create_pool_fee:   u64
Accounts
#NameWS
1ownerWSAdmin.
2amm_configWinited here.
3system_program
Preconditions
  • No existing AmmConfig with the same index.
  • 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 = 0trade_fee_rate
  • param = 1protocol_fee_rate
  • param = 2fund_fee_rate
  • param = 3new_protocol_owner (pass Pubkey bytes as a reinterpret)
  • param = 4new_fund_owner
  • param = 5create_pool_fee
  • param = 6disable_create_pool
Changes are signed by the admin and affect every pool bound to this AmmConfig on the next swap. No migration; pools simply read the new values.

State-change matrix

Instructionlp_supplyVault balancesAccrued-fee fieldsobservation
Initialize+ init LP+ init_amount_{0,1}0init
InitializeWithPermission+ init LP+ init_amount_{0,1}0init
Deposit++ both
Withdraw− both
SwapBaseInput+ in, − out+ trade_fee split into protocol/fund; + creator_fee if enabled+ (if interval elapsed)
SwapBaseOutput+ in, − out+ trade_fee split into protocol/fund; + creator_fee if enabled+ (if interval elapsed)
CollectProtocolFee− (by protocol buckets)protocol_* → 0
CollectFundFee− (by fund buckets)fund_* → 0
CollectCreatorFee− (by creator buckets)creator_* → 0
UpdatePoolStatus

Where to go next

Sources: