Skip to main content
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
このページは権威あるインストラクション・リファレンスです。これらのインストラクションを実際に構成するコードについては、products/cpmm/code-demos を参照してください。エラーコードの意味については reference/error-codes を参照してください。2026-09 プログラムアップグレードは CPMM を Anchor 1.0.2 / Solana 3.1.10 上に再構築し、管理者インストラクション CollectExcessLamports を追加し、ハードコードされた Token-2022 ミント・ホワイトリストを削除し、CreateAmmConfig が protocol_owner / fund_owner に書き込む内容を変更しました。ユーザー向けのインストラクションは、アカウント、引数、数学に変更がありません。2026-09-09 チェンジログエントリ を参照してください。
クリエイターフィー収集インストラクション 2 つは 2026-09-19 にアカウントリストを変更しました。 CollectCreatorFee は creator_fee_share を追加し、CollectCreatorFeePermissionless は amm_config と creator_fee_share を追加します。いずれも system_program の後に追加(append) されるため、既存クライアントがすでに渡しているアカウントはすべてインデックスを維持します — ただし新しいアカウントは必須であるため、古いレイアウトに対して構築されたトランザクションはアカウント数が不足し、Anchor の AccountNotEnoughKeys(3005)で拒否されます。2 つの管理者インストラクション — CreateCreatorFeeShare と CloseCreatorFeeShare — が追加され、UpdateAmmConfig は新しい param = 8 を取ります。2026-09-19 チェンジログエントリ を参照してください。

インストラクション概要

ステータスビットマスク:各プールの status は u8 で、ビット 0 = デポジット無効、ビット 1 = 引き出し無効、ビット 2 = スワップ無効(プログラムの PoolStatusBitIndex { Deposit, Withdraw, Swap })です。クリアビットは操作が許可されることを意味し、セットビットは一時停止されることを意味します。UpdatePoolStatus は生の u8 を取り、既存の値を上書きします。 次のセクションでは各インストラクションについて詳しく説明します。アカウント順序は CPMM IDL に従います。SDK と raydium-cp-swap/programs/cp-swap/src/instructions の Rust クライアントはこの順序に一致します。

Initialize

新しい CPMM プールを作成します。 引数
アカウント(W = 書き込み可能、S = 署名者) * pool_state はランダムキーペアパスでのみ署名します。正規 PDA パスは pool_state 署名なしで実行されます。 前提条件
  • ミントはソート済み(バイト順で token_0_mint < token_1_mint)。
  • どちらのミントも CPMM 許可リスト外の拡張機能を使用していません(TransferFeeConfig、MetadataPointer、TokenMetadata、InterestBearingConfig、ScaledUiAmount)— products/cpmm/accounts を参照してください。SupportMintAssociated PDA(シード [b"support_mint", mint])が存在するミントは拡張機能チェックをスキップします — ただし、その PDA を remaining_accounts に追加する必要があります。プログラムは渡されたアカウントのみをスキャンし、PDA 自体をロードしません。レジストリに依存しながらアカウントを提供しないと、NotSupportMint(6007)で失敗します。順序は重要ではありません(キーでマッチング)。バイパスが必要な各ミントに 1 つのエントリを渡します。そのレジストリは 2026-09 アップグレードがハードコードされた 4 ミント・ホワイトリストを削除した後の唯一のバイパスです。
  • creator は各 ATA で少なくとも init_amount_0 と init_amount_1 を持っています。
  • amm_config.disable_create_pool == false。
事後条件
  • pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1) — 完全な平方根。クリエイターは lp_supply − 100 をミントされます。100 ロック基本単位は lp_supply でカウントされますが、ミントされません。
  • したがって、プールの存続期間中 lp_mint.supply == pool_state.lp_supply − 100。すべての LP シェア数学(デポジット、引き出し)は lp_supply で除算するため、そのフィールドを使用し、ミントのオンチェーン供給を代用しないでください。sqrt(...) < 100 の場合、InitLpAmountTooLess で戻ります。
  • observation_state が初期化されます。observation_index = 0 で pool_id = pool_state.key()。
  • create_pool_fee ラムポートはクリエイターから受取人に転送され、ネイティブ SOL として同期されます(wSOL ATA です)。
  • プールのステータスビットマスクは 0(デポジット / 引き出し / スワップすべて有効)。
  • enable_creator_fee = false で creator_fee_on = BothToken。Initialize はクリエイターフィーの有効化をサポートしません — そのパスは InitializeWithPermission です。
  • open_time は、呼び出し元が <= block_timestamp の値を渡した場合、block_timestamp + 1 にバンプされます。スワップは open_time 前に拒否されます。デポジットと引き出しは直ちに機能します。
一般的なエラー(完全なリストは reference/error-codes を参照)
  • InvalidInput — ミントがアンソート、または同一ミント。
  • NotSupportMint — ブロックされた Token-2022 拡張機能。
  • ExceededSlippage — まれに。init_amount_0/1 が小数点の不一致により 0 LP になる場合。

Deposit

プールに比例した両方のトークンでリクイディティを追加します。 引数
アカウント 数学
ピンダウンする価値のある 2 つの詳細:按分ベースはフィー除外ボルト合計(vault_amount_without_fee、つまり生残高から蓄積されたプロトコル、ファンド、クリエイターカウンターを差し引いたもの)であり、生ボルト残高ではありません。スリッページキャップは、ペイヤーが実際に転送する内容に対してチェックされ、Token-2022 転送フィーが追加された後、生ボルト移動に対してではありません。 k の比例性に変更なし — 両方の合計と lp_supply は同じ係数でスケーリングされます。 事後条件
  • lp_supply += lp_token_amount。
  • vault_0 += needed_token_0(入力上の Token-2022 転送フィーを差し引いたネット)。
  • vault_1 += needed_token_1(入力上の Token-2022 転送フィーを差し引いたネット)。
一般的なエラー — ExceededSlippage、ZeroTradingTokens、デポジットが一時停止されている場合は InvalidStatus。

Withdraw

LP トークンをバーンし、基礎となる両方のトークンを按分で受け取ります。 引数
アカウント 最初の 13 アカウントは Deposit と同一で、lp_mint は LP トークンがバーンされるため書き込み可能です。Withdraw は追加で 14 番目のアカウント memo_program(制約 address = memo::ID)を取ります — Deposit は取りません。13 アカウント Withdraw は Anchor 逆シリアル化に失敗するため、LP は出口できません。 数学
事後条件
  • lp_supply -= lp_token_amount。
  • ボルトは out_token_0 / out_token_1 を送信します(生。ユーザーは Token-2022 転送フィーを差し引いたネットを受け取ります)。

SwapBaseInput

正確入力スワップ。 引数
アカウント 順序は入力 → 出力で、ユーザーの方向によります。プールの正規 token_0 / token_1 ではありません。プログラムはミントをマッチングすることでどのボルトがどれであるかを判断します。 数学 — products/cpmm/math を参照してください。 前提条件
  • open_time <= now。
  • pool_status はスワップを許可します。
  • どちらのミントもこの権限に対して一時停止またはフリーズされていません。
  • amount_in > 0。
一般的なエラー
  • ExceededSlippage — amount_out < minimum_amount_out。
  • ZeroTradingTokens — トレードが 0 に丸められます。
  • NotApproved — プールは UpdatePoolStatus でスワップに対して一時停止されています。
  • InvalidInput — ミントはプールのボルトミントのいずれとも一致しません。

SwapBaseOutput

正確出力スワップ。 引数
アカウント — SwapBaseInput と同じ。 数学 — 逆曲線と天井、products/cpmm/math を参照してください。 一般的なエラー — ExceededSlippage(gross_in > max_amount_in)、ZeroTradingTokens、InvalidInput、NotApproved。

CollectProtocolFee

ボルトから蓄積されたプロトコルフィーをプロトコル宛先に回収します。 引数 — なし。 アカウント 効果
曲線の有効残高に変更なし(蓄積されたフィーは既に除外されています)。 一般的なエラー — 署名者が amm_config.protocol_owner でもプログラム管理者でもない場合、InvalidOwner(6001)。(このパスに NotApproved はありません。)

CollectFundFee

CollectProtocolFee と同じ形状ですが、amm_config.fund_owner — または再度、プログラム管理者 — によって署名され、fund_fees_* カウンターをゼロにします。間違った署名者に対して同じ InvalidOwner。

CollectCreatorFee

pool_state.pool_creator によって署名されます。蓄積されたクリエイターフィーを決済し、クリエイターの部分をクリエイターのトークンアカウントに転送します。 引数 — なし。 アカウント 効果
プロトコルのシェアはここではボルトを離れません — プロトコルフィーとして再ラベル付けされ、CollectProtocolFee を待ちます。両方のカウンターは既にボルトのビューから除外されているため、プールの価格は移動しません。完全な導出は products/cpmm/fees を参照してください。 一般的なエラー — 両方のクリエイターカウンターがゼロの場合 NoFeeCollect(分割前にチェック)、解決された share_rate が 1_000_000 を超える場合 InvalidInput(6003)、シェアの記帳が protocol_fees_token_* をオーバーフローする場合 MathOverflow(6011)、creator_fee_share が正規 PDA でない場合 Anchor の ConstraintSeeds エラー。

CollectCreatorFeePermissionless

誰でもクリエイターフィー収集をトリガーできます。インストラクションは常にクリエイターの部分を pool_state.pool_creator が所有する正規関連トークンアカウントに送信します。呼び出し元は別のクリエイターまたは宛先を選択できません。どちらかの ATA が不足している場合、ペイヤーがその作成に資金を提供します。 元の CollectCreatorFee は呼び出し可能なままなので、自分の収集に署名したいクリエイターは依然としてできます。 引数 — なし。 アカウント
2 つの新しいアカウントは挿入ではなく、system_program の後に追加(append) されます。payer から system_program までのすべてのアカウントはアップグレード前の位置を維持するため、この破壊的変更はクリーンです — アップグレード前の 14 アカウントレイアウトに対して構築されたトランザクションはボルトをコンフィグとして誤読することはなく、単に渡すアカウント数が不足し、制約チェックが走る前に Anchor が AccountNotEnoughKeys(3005)で拒否します。それでも新しいアカウントは必須であるため、両方を末尾に追加し、IDL をリフレッシュしてください。古いレイアウトに対する互換パスはありません。
効果 — 上記の CollectCreatorFee と同一:シェアは creator_fee_share または amm_config から解決され、プロトコルの部分は protocol_fees_token_{0,1} に記帳され、クリエイターの部分はクリエイター ATA に転送され、両方のクリエイターカウンターはゼロにされ、recent_epoch が更新されます。両方のカウンターがゼロの場合、NoFeeCollect を返します。

UpdatePoolStatus

プール上の個別の操作を一時停止または再開します。status フィールドはビットマスクです: 引数
アカウント 管理者キーはプログラムにコンパイルされた pubkey(crate::admin::ID)であり、BPF アップグレード権限ではありません — 変更にはプログラムアップグレードが必要です。値については reference/program-addresses を、保有者については security/admin-and-multisig を参照してください。

CreateAmmConfig

新しいフィーティアを作成します。 引数
アカウント 前提条件
  • 同じ index を持つ既存の AmmConfig はありません。
  • protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE。
2026-09 で変更:新しいコンフィグのフィー所有者は署名者から来なくなりました。 create_amm_config は現在、プログラムのハードコードされた protocol_fee_owner::ID を protocol_owner に、fund_fee_owner::ID を fund_owner に書き込みます。以前は管理者署名者のキーを両方にコピーしていました。アドレスは reference/program-addresses にあります。結果:新しく作成された AmmConfig 上のフィーは、管理者の代わりに専用フィーウォレットに着地します。管理者は収集の受け入れられた署名者のままです — CollectProtocolFee / CollectFundFee は amm_config.protocol_owner / fund_owner または crate::admin::ID を受け入れます — したがって、回収するために何もローテーションする必要はありません。変更されたのは、デフォルトで収益がどこに行くかだけです。既存の AmmConfig アカウントは書き直されません — それらに保存されているものは依然として支配するため、常にアカウントから protocol_owner / fund_owner を読み取り、どちらかの値を想定しないでください。UpdateAmmConfig パラメータ 3 と 4 は依然としてそれらをローテーションします。

UpdateAmmConfig

既存の AmmConfig のフィーレートまたは所有権を変更します。param: u8(更新するフィールド)と value: u64 を取ります。完全なディスパッチテーブル:
  • param = 0 → trade_fee_rate(trade_fee_rate + creator_fee_rate < 1_000_000 をアサート)
  • param = 1 → protocol_fee_rate(≤ 1_000_000 および + fund_fee_rate ≤ 1_000_000 をアサート)
  • param = 2 → fund_fee_rate(≤ 1_000_000 および + protocol_fee_rate ≤ 1_000_000 をアサート)
  • param = 3 → protocol_owner。新しいキーは value にありません:remaining_accounts[0] として追加します(読み取り専用で問題ありません)。デフォルト pubkey であってはいけず、アカウントを省略すると unwrap() でパニックします。
  • param = 4 → fund_owner。3 と同じメカニズム。
  • param = 5 → create_pool_fee
  • param = 6 → disable_create_pool(ゼロ以外の value は無効化)
  • param = 7 → creator_fee_rate(creator_fee_rate + trade_fee_rate < 1_000_000 をアサート)
  • param = 8 → creator_fee_share_rate(≤ 1_000_000 をアサート)。2026-09-19 で追加。このティア上のクリエイターフィーのプロトコルのデフォルトシェア。products/cpmm/fees を参照してください。トレードフィーを分割する protocol_fee_rate とは関係ありません。
その他の param は InvalidInput を返します。 変更は管理者によって署名され、次のスワップでこの AmmConfig にバインドされたすべてのプールに影響します。マイグレーションなし。プールは単に新しい値を読み取ります。

CreateCreatorFeeShare

1 つの (creator, amm_config) ペアのクリエイターフィーのカスタムプロトコルシェアを設定し、そのフィーティア上でそのクリエイターが所有するすべてのプールの AmmConfig.creator_fee_share_rate をオーバーライドします。2026-09-19 クリエイターフィーシェアアップグレードで追加。 引数
アカウント 前提条件
  • share_rate <= 1_000_000、そうでない場合は InvalidInput(6003)。
  • PDA は既に存在してはいけません — Anchor の init は同じペアの 2 番目の呼び出しで失敗します。レートを変更するには、アカウントを閉じて再度作成します。
事後条件
  • creator_fee_share は bump、creator、amm_config、share_rate を保存します。
  • その後のすべての CollectCreatorFee / CollectCreatorFeePermissionless は、creator によって amm_config の下で作成されたプール上で、コンフィグの代わりにこのアカウントからシェアを解決します。
プール作成者はこのインストラクションの当事者ではなく、署名しません。レートは収集時に読み取られるため、フィーが既に蓄積された後に作成されたオーバーライドはその蓄積残高にも適用されます。

CloseCreatorFeeShare

オーバーライドを削除します。ペアは AmmConfig.creator_fee_share_rate にフォールバックします。 引数 — なし。 アカウント 事後条件
  • アカウントは閉じられ、そのラムポートは owner に行きます。
  • そのペアの収集は再び amm_config.creator_fee_share_rate からシェアを解決します — 管理者が UpdateAmmConfig パラメータ 8 を設定していない限り、これは 0 です。

CollectExcessLamports

CPMM が制御するアカウント上の家賃免除最小値を超えるラムポートの管理者スイープ。2026-09 アップグレードで追加されたため、プロトコルは SIMD-0437 家賃削減 が各ステップの前に作成されたアカウントに残す過剰資金を回収できます。 過剰分のみが移動します。トークン残高、アカウントデータ、所有者、プール状態、曲線は変更されず、インストラクションは既に最小値にあるアカウントに対して no-op です — したがって、各ロールアウトステップ後に再実行しても安全です。 引数 — なし。 アカウント
順序付け修正、2026-09-19。 プログラムは remaining_accounts に対して 2 つのパスを実行します — すべてのトークンプログラム CPI 最初、次に CPMM 所有 PDA の直接デビット。CPI の前に PDA がデビットされるたびに、ランタイムの UnbalancedInstruction(「命令の前後のアカウント残高の合計が一致しない」)で中止されました。呼び出し元の保留中のラムポート変更は、CPI が実際に実行するアカウントにのみフラッシュされるためです。呼び出し元はリストを自分でグループ化またはソートする必要はありません。
各ソースアカウントの処理方法 プログラムはソースアカウントの owner でディスパッチします: 無制限の remaining_accounts リストを取るため、トランザクションサイズが実際の制限です — solana-fundamentals/rent-and-reclaimable-rent で説明されているウォレット側スイープと同じ制約。 一般的なエラー — InvalidOwner(6001、間違った署名者)、LamportsCalculateError(6015、wSOL ラウンドトリップがゼロにネットされなかった)、プログラム所有パスから InsufficientFunds(アカウントが独自の家賃最小値より少ない場合)。 SDK ビルダーなし。 @raydium-io/raydium-sdk-v2 はこのインストラクションのビルダーを出荷しません。raydium-sdk-V2-demo リポジトリも出荷しません — これは管理者パスです。手動でエンコードしてください。solana-fundamentals/rent-and-reclaimable-rent のウォレット側スイープがトークンプログラムインストラクションに対して行うのと同じ方法で。

状態変更マトリックス

次に進む場所

ソース: