Stable AMM is an independent program with its own program ID. It is not a mode of the AMM v4 program, and it is not traded “through” AMM v4 — it is deployed, upgraded, and called separately. It resembles AMM v4 only in fee and account-layout conventions.
2026-06-22 upgrade — removal of dead OpenBook (market) code. Stable AMM stopped posting orders to OpenBook a long time ago; the orderbook market-making path has been dormant for years. This upgrade deletes the leftover market-related accounts and code — it does not change live trading behavior.Two consequences for integrators:
- Smaller account layouts.
SwapBaseIn / SwapBaseOut (18 → 9), Deposit (14 → 12), and Withdraw (21/22 → 12) drop the dead Serum/market accounts. Old layouts still parse for backwards compatibility. WithdrawPnl (16 → 10) is a hard breaking change with no compatibility path (admin only).
- Most instructions are removed. Only
SwapBaseIn, SwapBaseOut, Deposit, Withdraw, and WithdrawPnl remain callable. All other instructions can no longer be called.
Changelog: reference/changelog.
Instruction inventory
Callable
| Instruction | Category | Notes |
|---|
Deposit | Liquidity | Add liquidity, receive LP. New 12-account layout; old 14-account layout still compatible. |
Withdraw | Liquidity | Burn LP, receive both sides. New 12-account layout; old 21/22-account layout still compatible. |
SwapBaseIn | Swap | Exact-input swap. New 9-account layout; old 18-account layout still compatible. |
SwapBaseOut | Swap | Exact-output swap. New 9-account layout; old 18-account layout still compatible. |
WithdrawPnl | Admin | Sweep accrued protocol fees. New 10-account layout (hard breaking — no old-layout compatibility). |
Removed (no longer callable)
These were removed in the 2026-06-22 upgrade and can no longer be invoked. See Removed instructions.
| Instruction | Former category | Former purpose |
|---|
Initialize | Lifecycle | Create a pool. |
PreInitialize | Lifecycle | Legacy pre-allocation helper. |
InitModelData | Model setup | Create and initialize the lookup table. |
UpdateModelData | Model setup | Populate up to 5 table elements per call. |
MonitorStep | Crank | Settle OpenBook fills, repost orders. |
SetParams | Admin | Change pool parameters. |
WithdrawSrm | Legacy | Sweep SRM fee-discount rebates. |
SimulateInfo | Diagnostic | Read-only quote helper. |
Deposit
Add liquidity, receive LP tokens.
Arguments
max_coin_amount: u64
max_pc_amount: u64
base_side: u64 // 0 = base on coin, 1 = base on pc
Accounts — new layout, 12 accounts (writable W, signer S)
| # | Name | W | S | Notes |
|---|
| 0 | token_program | | | SPL Token. |
| 1 | amm | W | | Pool’s AmmInfo. |
| 2 | amm_authority | | | Program-wide PDA. |
| 3 | amm_target_orders | W | | |
| 4 | amm_lp_mint | W | | LP mint. |
| 5 | amm_coin_vault | W | | Pool coin vault. |
| 6 | amm_pc_vault | W | | Pool pc vault. |
| 7 | model_data_account | | | Read-only lookup table. |
| 8 | user_source_coin | W | | User’s coin input. |
| 9 | user_source_pc | W | | User’s pc input. |
| 10 | user_dest_lp | W | | User’s LP ATA. |
| 11 | user_source_owner | | S | Transaction signer. |
Compatibility: amm_open_orders (old #3) and serum_market (old #9) are removed. When 14 accounts are passed, the instruction is parsed with the old 14-account layout; the Serum accounts are ignored.
Math — standard pro-rata using the lookup table to compute the ratio. The SDK computes coin/pc pair for the desired LP amount and checks against max caps.
Withdraw
Burn LP, receive both sides pro-rata.
Arguments
amount: u64 // LP tokens to burn
Accounts — new layout, 12 accounts (writable W, signer S)
| # | Name | W | S | Notes |
|---|
| 0 | token_program | | | SPL Token. |
| 1 | amm | W | | Pool’s AmmInfo. |
| 2 | amm_authority | | | Program-wide PDA. |
| 3 | amm_target_orders | W | | |
| 4 | amm_lp_mint | W | | LP mint. |
| 5 | amm_coin_vault | W | | Pool coin vault. |
| 6 | amm_pc_vault | W | | Pool pc vault. |
| 7 | model_data_account | | | Read-only lookup table. |
| 8 | user_source_lp | W | | User’s LP source. |
| 9 | user_dest_coin | W | | User’s coin output. |
| 10 | user_dest_pc | W | | User’s pc output. |
| 11 | user_lp_owner | | S | Transaction signer. |
Compatibility: nine Serum accounts (amm_open_orders, serum_program, serum_market, serum_coin_vault, serum_pc_vault, serum_vault_signer, serum_event_q, serum_bids, serum_asks) are removed. The old 21- or 22-account layouts are still accepted. Note, however, that the referral-fee logic for the 22nd optional referrer_pc_wallet account has been removed — it can still be passed but no longer takes effect.
Preconditions
user_source_lp holds at least amount.
Postconditions
amount LP tokens are burned.
- User receives coin and pc amounts according to the current pro-rata, adjusted for accrued fees.
SwapBaseIn
Exact-input swap using the lookup table for pricing.
Arguments
amount_in: u64
minimum_amount_out: u64
Accounts — new layout, 9 accounts (writable W, signer S)
| # | Name | W | S | Notes |
|---|
| 0 | spl_token program | | | SPL Token. |
| 1 | amm | W | | Pool’s AmmInfo. |
| 2 | amm_authority | | | Program-wide PDA. |
| 3 | amm_coin_vault | W | | Pool coin vault. |
| 4 | amm_pc_vault | W | | Pool pc vault. |
| 5 | model_data_account | | | Read-only lookup table. |
| 6 | user_source_token | W | | User’s input token account. |
| 7 | user_destination_token | W | | User’s output token account. |
| 8 | user_source_owner | | S | User (transaction signer). |
Compatibility: the nine OpenBook accounts (amm_open_orders, serum_program, serum_market, serum_bids, serum_asks, serum_event_queue, serum_coin_vault, serum_pc_vault, serum_vault_signer) are removed. If the number of accounts passed is not 9, the instruction is parsed with the old 18-account layout; the Serum accounts must still occupy their positions, but their contents are no longer validated or used.
Preconditions
amm.status allows swap.
user_source_token holds ≥ amount_in.
Postconditions
- User loses
amount_in, gains amount_out ≥ minimum_amount_out.
- Pool fees increment
need_take_pnl_* counters.
Math — Lookup-table interpolation as described in products/stable/math.
SwapBaseOut
Exact-output swap (inverse of SwapBaseIn). Same 9-account layout, different math direction.
Arguments
max_amount_in: u64
amount_out: u64
WithdrawPnl
Admin-only. Sweep accrued protocol fees from need_take_pnl_* into designated PnL accounts.
Hard breaking change — no compatibility path. This instruction has no parsing for the old layout. Sending the old layout fails with validation errors such as InvalidTokenCoin due to account misalignment (old #3 was open_orders). Admin tooling that calls WithdrawPnl must be updated to the new 10-account layout.
Arguments — none (state-driven).
Accounts — new layout, fixed 10 accounts, admin only (writable W, signer S)
| # | Name | W | S | Notes |
|---|
| 0 | spl_token program | | | SPL Token. |
| 1 | amm | W | | Pool’s AmmInfo. |
| 2 | amm_authority | | | Program-wide PDA. |
| 3 | amm_coin_vault | W | | Pool coin vault. |
| 4 | amm_pc_vault | W | | Pool pc vault. |
| 5 | amm_target_orders | W | | |
| 6 | model_data | | | Lookup table. |
| 7 | user_coin | W | | Admin’s coin account (receives fee). |
| 8 | user_pc | W | | Admin’s pc account (receives fee). |
| 9 | amm_admin | | S | Pool admin (signer). |
Logic change: when the pool’s available funds are insufficient to withdraw the accrued PnL, the pool is no longer put into CancelAllOrdersState / Disabled; the instruction returns TakePnlError directly. The optional referrer_pc_wallet has also been removed.
Preconditions
amm_admin must be authorized.
Postconditions
need_take_pnl_coin and need_take_pnl_pc are transferred to the admin’s accounts.
- Counters are zeroed.
Removed instructions
The following instructions were removed in the 2026-06-22 upgrade and can no longer be called. They are documented here only so integrators recognize them in historical transactions and SDKs.
Initialize — formerly bootstrapped a new Stable AMM pool. Removed.
PreInitialize — legacy pre-allocation helper. Removed.
InitModelData — formerly created and initialized the ModelDataInfo lookup table. Removed.
UpdateModelData — formerly populated up to 5 lookup-table elements per call. Removed.
MonitorStep — the OpenBook crank that settled fills and reposted the order grid. Already long-dormant after the pool stopped posting to OpenBook; now removed.
SetParams — admin parameter changes (status, fees, owner, model-data key, etc.). Removed.
WithdrawSrm — swept SRM fee-discount rebates from early Serum-era pools. Removed.
SimulateInfo — read-only quote helper. Removed; use the SDK’s off-chain stable-curve helpers for quoting (see Code demos).
Where to go next
- Accounts — for account field layouts and sizes.
- Math — for the lookup-table interpolation logic.
- Code demos — to see how to call these from the SDK.
Sources:
raydium-stable/program/src/instruction.rs (enum and pack/unpack)
raydium-stable/program/src/processor.rs (execution logic)