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.
Support matrix: CPMM supports Token-2022 fully, including transfer-fee mints. CLMM supports Token-2022 with transfer fees via explicit
SwapV2 accounts. AMM v4 does not support Token-2022 at all. LaunchLab does not support Token-2022 for the base mint (it creates classic SPL mints). Farm v6 supports Token-2022 on both staking and reward mints.What a transfer fee is
Token-2022 is the second SPL Token program (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA → TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb). Among its extensions, the transfer-fee extension makes every TransferChecked on a token mint deduct a fee from the transferred amount. The fee routes to a recipient designated by the mint authority and can be updated by the authority (within bounds).
A mint with transfer fee has two relevant parameters:
transfer_fee_basis_points— the rate (e.g. 100 = 1%).maximum_fee— an absolute cap per transfer (so whales moving huge amounts don’t pay unbounded fees).
Why this matters for swaps
A pool’s vaults hold actual balances. When a user calls a Raydium swap:- User sends
amount_into the pool vault. If the in-mint has a transfer fee, the vault receivesamount_in − fee_in, notamount_in. - The swap math operates on the vault-received amount.
- The pool sends
amount_outto the user’s ATA. If the out-mint has a transfer fee, the user receivesamount_out − fee_out, notamount_out.
amount_in argument, the invariant check fails because the vault got less than the program thinks. Conversely, if it computes amount_out without subtracting the outbound transfer fee, the user sees a shortfall and blames the program.
Raydium CPMM and CLMM (via SwapV2) handle this by:
- Pre-swap: computing
in_after_fee = amount_in − transfer_fee_on(amount_in, in_mint), and usingin_after_feein the curve math. - Post-swap: computing
out_gross = amount_out_from_curve, sendingout_grossto the user viaTransferCheckedwhich the Token-2022 program will itself reduce by the transfer fee.
minAmountOut slippage bound is checked against out_gross (what the pool sends), not against what the user receives. This is how every major Solana DEX handles Token-2022, and it matters because:
- If the pool checked post-fee, a fee-update between quote and execution would cause the trade to revert.
- Checking pre-fee pins the failure to the quote’s own quality, not to the user’s out-of-band fee changes.
Computing the Token-2022 fee
The SPL Token-2022 program exposes a deterministic helper. In Rust:@solana/spl-token):
Adjusted swap formulas (CPMM, exact-input)
Letf_pool be the pool fee rate, f_in the in-mint transfer fee rate, max_in its max cap, f_out the out-mint transfer fee rate, max_out its max cap.
amount_out_gross ≥ min_amount_out (not user_receives ≥ min_amount_out). The user’s minAmountOut is set by the SDK to expected_gross · (1 − slippage) — keep the bound on the “sent” side, not the “received” side.
Adjusted formulas (CPMM, exact-output)
The SDK iterates to findamount_in such that user_receives = amount_out_exact:
max_in / max_out caps make the computation non-linear because once the cap is hit the fee stops growing. The SDK’s computeAmountIn / computeAmountOut handle this by iterating if the naive formula would push past the cap.
Edge cases
Asymmetric fees (one side has a fee, the other does not)
Common in practice. The formulas above already handle this — if one side hasf_in = 0, the relevant terms collapse. There is no special case in the program.
Fee updates mid-swap
If the mint’s transfer fee changes between quote time and execution time, the swap will either land with slightly worse economics (user bears the difference within the slippage tolerance) or revert (the gross output drops belowminAmountOut). Slippage bounds absorb this; no additional protection is needed.
Maximum-fee cap
Once the trade is large enough to hitmaximum_fee, the fee saturates and further growth is zero. This makes the effective rate asymptotic to zero for very large trades, which can cause odd pricing curves on deeply illiquid markets. The SDK’s computeAmountOut accounts for this.
Non-transferable extension
Some Token-2022 mints use theNonTransferable extension, which rejects all Transfer calls except to and from the mint authority. Such mints cannot be used in a Raydium pool at all. CreatePool rejects them at init.
Interest-bearing mints
Token-2022 also supports anInterestBearingConfig extension that makes balances appear to grow over time. Raydium’s pools read raw vault balances (which ignore the interest accrual), so on a pool with an interest-bearing mint, LPs capture the accrued interest as a pure gift whenever they redeem (the vault balance grew faster than the LP supply representation). Integrators should treat this as a non-issue but document it for the LP side.
Transfer hooks
Token-2022’sTransferHook extension allows arbitrary CPI on every transfer. Raydium CPMM supports these — the swap instruction forwards the hook accounts — but it adds CU overhead and requires the hook to be well-behaved. CLMM SwapV2 also supports hooks. AMM v4 does not support Token-2022 at all, so the question does not arise.
Worked example
CPMM pool,x = 1_000_000 USDY, y = 1_000_000 USDC, pool fee 0.25%.
- USDY has a 1% transfer fee,
max_fee = 10_000(0.01 USDY with 6 decimals). - USDC has no transfer fee.
amount_in = 1_000 USDY for USDC (exact-input).
Pointers
products/cpmm/overview— CPMM Token-2022 support.products/clmm/instructions—SwapV2vsSwapfor Token-2022 routing.solana-fundamentals/spl-token-and-token-2022— the general Token-2022 extension model.
- SPL Token-2022 transfer-fee extension docs
- Raydium CPMM program source (
SwapBaseInput/SwapBaseOutputToken-2022 handling). - Raydium CLMM program source (
SwapV2).


