Skip to main content
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
このページは products/clmm/accounts(アカウントの説明)および products/clmm/math(数学の説明)と対になっています。引数とアカウント順序の権威的な情報源です。具体的なバイト レイアウトは IDL から取得されます。2026-09 プログラム アップグレードは CLMM を Anchor 1.0.2 / Solana 3.1.10 で再構築し、管理者インストラクション CollectExcessLamports を追加し、CreateAmmConfig が owner / fund_owner に書き込む内容を変更しました。ユーザー向けのインストラクションでアカウント、引数、数学が変わったものはありません。2026-09-30 チェンジログ エントリを参照してください。2026-10-22 プログラム アップグレードは CreatePermissionedPool を CreateCustomizablePoolV2 に名前変更し、誰でも呼び出せるようにし、2 つの管理者インストラクションを持つ Permission アカウントを削除しました。2026-10-22 チェンジログ エントリを参照してください。

インストラクション一覧

init-tick-array インストラクションはなく、必要ありません。 ティック配列は OpenPosition* / IncreaseLiquidity* 内の TickArrayState::get_or_create_tick_array で作成され、payer が支払います。 (初期化されていない可能性がある、システム所有の)ティック配列 PDA を tick_array_lower / tick_array_upper として渡すと、プログラムは不足している場合にそれを割り当てます。 OpenLimitOrder は単一の tick_array に対して同じことを行います。
ほとんどの管理者専用インストラクション(CreateAmmConfig、UpdateAmmConfig、UpdatePoolStatus、CreateOperationAccount、UpdateOperationAccount、CloseProtocolPosition)はプログラムのハードコードされた admin 公開鍵によってゲートされています。CreateSupportMintAssociated / CloseSupportMintAssociated は admin 公開鍵または専用のサポート ミント所有者キーを受け入れます。CollectExcessLamports は admin 公開鍵または専用の collect-lamports ウォレットを受け入れます。リワード ストリーム管理者インストラクション(TransferRewardOwner、CollectRemainingRewards)はプログラム管理者ではなくリワード ファンダーによってゲートされています。 V2 サフィックスは「ボルト/NFT で Token-2022 をサポート、ビットマップ拡張スロットが必要」を意味します。SDK は新しいプールに対してデフォルトで V2 を選択します。

CreatePool

引数
アカウント(簡略版)
スロット 10 と 11 はミントごとであり、「SPL Token その後 Token-2022」ではありません。各スロットは一致するミント上の mint::token_program によって制約されるため、token_mint_0 が Token-2022 で token_mint_1 が従来の SPL のプールの場合、スロット 10 に Token-2022 を、スロット 11 に SPL Token を渡す必要があります。 CreateCustomizablePool と CreateCustomizablePoolV2 は同じ 2 つのスロットを使用します。
前提条件
  • token_mint_0 < token_mint_1(バイト順)。
  • amm_config.disable_create_pool == false。
  • ミントは Token-2022 拡張ホワイトリストで拒否されていません。
事後条件
  • pool_state.sqrt_price_x64 = sqrt_price_x64、tick_current = floor(log_{1.0001}(price))。
  • pool_state.liquidity = 0(ポジションなし)。
  • pool_state.fee_on = FromInput(レガシー デフォルト)。
  • pool_state.dynamic_fee_info はゼロ化されています(動的手数料は無効)。

CreateCustomizablePool

新しいプールに推奨されます。CreatePool と同じ効果に加えて、プールごとの手数料回収モードとオプションの動的手数料オプトイン。 引数
アカウント — CreatePool の正確に 13 個の宣言されたアカウント。dynamic_fee_config は宣言されたアカウントではありません。
enable_dynamic_fee = true の場合、スナップショットする DynamicFeeConfig は最後の remaining_account として提供される必要があります。ハンドラーは ctx.remaining_accounts.last() を読み取ります。したがって、SupportMintAssociated バイパス PDA はその前に来る必要があります。そうしないと、プログラムは間違ったアカウントをスナップショットし、逆シリアル化に失敗します。フラグが設定されている間にそれを省略すると、AccountLack で失敗します。
前提条件 — CreatePool と同じ。enable_dynamic_fee = false の場合、remaining_account は不要で、渡されたものはサポート ミント レコードのみスキャンされます。 事後条件
  • pool_state.fee_on は選択された CollectFeeOn バリアントに設定されます。
  • 動的手数料が有効な場合:pool_state.dynamic_fee_info は提供された DynamicFeeConfig から初期化されます(5 つのキャリブレーション パラメータがコピーされ、状態フィールドはゼロ化されます)。
  • それ以外の場合:pool_state.dynamic_fee_info はゼロ化されます(= このプールでは動的手数料は永遠に非アクティブ)。
fee_on と動的手数料有効化ビットはプール作成時のみ設定されます。インプレース アップグレードはありません。レガシー CreatePool で作成されたプールは、動的手数料または片側手数料を遡及的に取得することはできません。新しいデプロイメントはこのインストラクションをデフォルトにする必要があります。

CreateCustomizablePoolV2

CreatePool と CreateCustomizablePool はどちらも ["pool", amm_config, token_mint_0, token_mint_1] からプール PDA を導出するため、(config, mint0, mint1) の組み合わせごとに正確に 1 つ の正規プールアドレスが存在します。同じシードで 2 回目の init を実行するとエラーになります。CreateCustomizablePoolV2 はクライアント提供の seed_index: u16 をプール PDA シードに組み込むことでこの制限を解除し、同じペアと手数料階層に対して複数のプールを作成 できるようにします。各プールは独自のアドレスを持ちます。誰でも呼び出せます。 プールのその他すべての側面は CreateCustomizablePool と同じです。同じ CreateCustomizableParams を受け取り、片側手数料と動的手数料オプトインをサポートします。
2026-10-22 アップグレードまでは、このインストラクションは CreatePermissionedPool と呼ばれており、支払者がアドミン発行の Permission PDA を保有する必要がありました。アップグレードにより名前が変更され、permission アカウントが削除され、権限メカニズムが廃止されました。ディスクリミネータは名前とともに変更されたため、CreatePermissionedPool に対して構築されたクライアントは再構築する必要があります。
引数
アカウント remaining_accounts: Token-2022 ミントが必要とするサポートミント レジストリ PDA、および enable_dynamic_fee = true の場合は DynamicFeeConfig 最後に — CreateCustomizablePool と同じです。 前提条件
  • seed_index != 0。seed_index が 0 の場合はレガシープール用に予約されており、ここで拒否されます。[0, 0] シード コンポーネントがレガシープールアドレスを古典的な 4 シード形式に折りたたみます。
  • 導出されたアドレスにプールが既に存在しません。
  • CreatePool と同じミント / 許可リストルール。
事後条件
  • 新しい pool_state が seed_index 導出アドレスに存在し、pool_state.seed_index = seed_index です。
  • その他すべての事後状態は CreateCustomizablePool と一致します(手数料モード、オプションの動的手数料)。
pool_creator はチェックされないため、任意の支払者が任意のアドレスを pool_state.owner に書き込むことができます。そのアドレスはプールで InitializeReward を呼び出すことができますが、プールを作成した人の証明ではありません。インテグレータは V2 プールを owner でラベル付けまたはランク付けしないでください。

OpenPositionV2 / OpenPositionWithToken22Nft

既存のプール内に新しいポジションを作成します。 引数
アカウント — 2 つのバリアントは 異なる アカウント リストを持ちます。OpenPositionV2 は 22 個を宣言します。OpenPositionWithToken22Nft は 20 個を宣言します。 OpenPositionV2(順序通り): OpenPositionWithToken22Nft は metadata_account(5)と metadata_program(19)が 削除された 同じリストです。代わりに NFT ミント上の Token-2022 メタデータ拡張を通じてポジションのメタデータを書き込みます。これにより 20 個のアカウントになります。その position_nft_mint は単なる Signer で、position_nft_account は UncheckedAccount です。
tick_array_bitmap_extension はどちらのバリアントでも宣言されたアカウントではありません。 ポジションの範囲がプールのインライン tick_array_bitmap(±512 ティック配列)の外にある場合、シード ["pool_tick_array_bitmap_extension", pool_state] で TickArrayBitmapExtension PDA を remaining_accounts[0] として追加してください。
計算 — products/clmm/math を参照してください。base_flag が与えられた場合、プログラムは liquidity または (amount_0_max, amount_1_max) のいずれかを実際の L と消費された実際のトークン金額に解決します。 前提条件
  • tick_lower < tick_upper、両方とも pool.tick_spacing の倍数、[MIN_TICK, MAX_TICK] 内。
  • 2 つのティック配列 PDA が渡されます。それらは既に存在する必要は ありません — get_or_create_tick_array はこのインストラクション内で payer の費用で不足しているものを割り当てます。個別のティック配列初期化インストラクションはありません。
  • ユーザーはソース ATA に少なくとも amount_0_max と amount_1_max を持っています。
事後条件
  • personal_position が存在し、liquidity が設定され、fee_growth_inside_last がスナップショットされます。
  • tick_lower と tick_upper のティック配列エントリが更新されます(liquidity_gross += L、liquidity_net ± L、手数料成長スナップショットが保持されます)。
  • ポジションが範囲内の場合(tick_lower ≤ tick_current < tick_upper)、pool_state.liquidity += L。
  • ポジション NFT ミントは pool_state をフリーズ権限として記録します。ミント権限は単一の NFT がミントされた後に削除されます。フリーズ権限を記録しても、NFT トークンアカウントの状態は変わりません。
  • NFT トークンアカウントは、インストラクションが OpenPositionV2 または OpenPositionWithToken22Nft かつ いずれかのボルトミントのフリーズ権限が CLMM の制限発行者リストと一致する場合を除き、フリーズされたままです。その一致する V2 パスのみがアカウントをフリーズします。OpenPosition V1 はフリーズしません。
一般的なエラー — TickInvalidOrder(tick_lower >= tick_upper)、TickAndSpacingNotMatch(エンドポイントが tick_spacing の倍数ではない)、InvalidTickIndex([MIN_TICK, MAX_TICK] の外)、MissingTickArrayBitmapExtensionAccount(範囲がインラインビットマップの外で拡張が追加されていない)、NotApproved(pool_state.status がオープンをブロック)、ZeroAmountSpecified。
ポジションのフリーズは宣言されたインストラクションアカウントまたは引数を追加しません。クライアントは既存の V2 レイアウトでこれらのポジションを開くことができます。動作はオンチェーンで vault_0_mint と vault_1_mint から選択されます。

IncreaseLiquidityV2

既に開いているポジションにリクイディティを追加します。 引数
アカウント — 15 個で、OpenPosition から導出 できません。rent、system_program、associated_token_program、メタデータアカウントがありません。 ポジションの範囲がインラインビットマップの外にある場合、TickArrayBitmapExtension PDA を remaining_accounts[0] として先頭に追加してください。 効果
  • amount_0_actual / amount_1_actual をユーザー → ボルトから転送します。
  • personal_position.liquidity と pool_state.liquidity(範囲内の場合)をインクリメントし、エンドポイントティックの liquidity_gross / liquidity_net をそれに応じて調整します。
  • 最後のタッチ以降に発生した手数料とリワードを収集 し、token_fees_owed_{0,1} / reward_amount_owed にクレジットします。これらは DecreaseLiquidity / DecreaseLiquidityV2 でのみ支払われ、増加時には支払われません。スタンドアロンの収集インストラクションはありません。

DecreaseLiquidityV2

ポジションからリクイディティを削除します。 引数
アカウント — 16 個で、IncreaseLiquidityV2 と 同じ形状または順序ではありません。personal_position と pool_state が入れ替わり、ボルトがティック配列の前に来て、ユーザー側のアカウントは recipient_token_account_* という名前で、追加の memo_program があります。 残りのアカウント — アクティブなリワードごとに 3 つ、順序は reward_token_vault(W)、recipient_token_account(W)、reward_vault_mint。ポジションの範囲がインラインビットマップの外にある場合、TickArrayBitmapExtension PDA を先頭に追加してください。
これは手数料とリワードを収集する 唯一の 方法です。ポジションを変更せずに収集するには、liquidity = 0、amount_0_min = 0、amount_1_min = 0 で呼び出してください。
効果
  • 現在の sqrt_price_x64 が与えられた場合、削除された L に対して (amount_0, amount_1) を計算します。
  • 最後のタッチ以降に発生した手数料/リワードを決済します(IncreaseLiquidity と同じ)。
  • amount_0 + fees_owed_0 と amount_1 + fees_owed_1 をボルトからユーザーに転送します。
  • リクイディティカウンタをデクリメントします。新しい personal_position.liquidity == 0 の場合、ポジションは ClosePosition の対象になります。
スリッページ — amount_0_min と amount_1_min は、出力側の Token-2022 転送手数料を差し引いた後、ユーザーが受け入れる最小値です。

ClosePosition

ポジション NFT をバーンし、PersonalPositionState をクローズします。 宣言されたアカウント 残りのアカウント
  • フリーズされていない NFT:不要。ハンドラーが読み込まないため、余分なプールアカウントは問題ありません。
  • フリーズされた NFT:最初の残りのアカウントとして personal_position.pool_id を追加します。プログラムはこれを PoolState として読み込み、その PDA シードを使用してシャを実行します。
前提条件
  • personal_position.liquidity == 0。
  • tokens_fees_owed_{0,1} == 0。
  • すべてのリワードカウンター reward_amount_owed == 0。
(つまり、すべてを回収し、先にゼロまで減らします。) 効果
  • NFT トークンアカウントがフリーズされている場合、最初の残りのアカウントが personal_position.pool_id と等しいことを確認してから、プール PDA でシャを実行します。
  • NFT をバーンします。
  • NFT トークンアカウントと personal_position をクローズし、レント を nft_owner に払い戻します。ポジション NFT が Token-2022 を使用している場合、NFT ミントもクローズします。クラシック SPL Token ミントはクローズできず、供給量ゼロのままになります。
シャ、バーン、クローズはアトミックです。NFT はこれらのステップ間で転送可能になることはできません。 条件付きクライアント互換性 — 宣言された IDL レイアウトは変更されていないため、レガシークライアントは既存のフリーズされていないポジションをクローズし続けます。プール残りのアカウントを省略するレガシービルダーは、フリーズされたポジションをクローズするときに AccountLack で失敗します。すべてのクローズでプールを渡すことが最も単純な互換性戦略です。

SwapV2

リクイディティ曲線を歩む。is_base_input に応じて正確な入力 または 正確な出力。 引数
アカウント(簡略版) 呼び出し元は、予想されるスワップウォークをカバーするティックアレイのランク付きリストを渡します。プログラムは必要な数だけ使用します。SDK はこのリストを PoolUtils.computeAmountOutFormat または API のクォートエンドポイント経由で計算します。 前提条件
  • pool_state.status はスワップを許可します。
  • now >= open_time。
  • sqrt_price_limit_x64 は方向に対して sqrt_price_x64 の正しい側にあります。
一般的なエラー — TooLittleOutputReceived(正確入力スリッページ)、TooMuchInputPaid(正確出力スリッページ)、SqrtPriceLimitOverflow、NotEnoughTickArrayAccount、InvalidFirstTickArrayAccount、MissingTickArrayBitmapExtensionAccount、LiquidityInsufficient、NotApproved(pool_state.status でスワップビットが設定)。CLMM には ExceededSlippage バリアントがありません — その名前は CPMM のものです — また TickArrayNotFound もありません。 呼び出し元が知っておくべき SwapV2 が内部で行うこと(2025年リリース後):
  1. 動的フィー追加料金 — pool.dynamic_fee_info がゼロ以外の場合、プログラムは最後のスワップ以降に走査されたティック距離を使用してボラティリティアキュムレータを更新し(products/clmm/fees のフィルター/減衰ルール付き)、AmmConfig.trade_fee_rate の上に dynamic_fee_component を追加します。総フィーは 10%(MAX_FEE_RATE_NUMERATOR / 1_000_000)でキャップされます。
  2. リミットオーダーマッチング — 価格ウォークがオープンなリミットオーダーを保持するティックを横切るとき、プログラムはまずそのティックで利用可能なリミットオーダーリクイディティを埋めます(order_phase による FIFO)、その後 LP リクイディティ曲線に沿って進みます。埋められた金額は tick.unfilled_ratio_x64 と tick.part_filled_orders_remaining を後の決済用に更新します。オーダー自体は所有者が SettleLimitOrder を呼び出すまで未使用のままです。
  3. 片側フィールーティング — pool.fee_on = Token0Only または Token1Only の場合、スワップステップは同じ入出力トレードを計算します。その後、フィーは設定された側にルーティングされます。設定されたフィー側が出力である方向では、フィーはスワップ出力から差し引かれます(ユーザーは out − fee を受け取ります)。設定されたフィー側が入力である方向では、動作は FromInput と一致します。PoolState の is_fee_on_input(zero_for_one) と is_fee_on_token0(zero_for_one) を参照してください。
Swap(V1)は SwapV2 と同じ動的フィー、片側フィールーティング、リミットオーダーマッチングを実装します。唯一欠けている機能は Token-2022 サポートです — 両方のボルトはクラシック SPL Token である必要があります。Token-2022 ミントを持つプールは SwapV2 経由でスワップする必要があります。アグリゲータと SDK はすでにすべての CLMM レッグで V2 を優先するため、呼び出し元はミントタイプで分岐する必要がありません。

OpenLimitOrder

特定のティックで売却オーダーを配置します。オーダーはティックごとの FIFO コホートに座り、価格が通過するにつれて埋まります。 引数
アカウント(簡略版) 残りのアカウント — [0] tick_array_bitmap_extension。開始インデックスがプールのインラインビットマップの外にあるティックアレイを初期化する場合にのみ必須。それ以外の場合は何も渡さないでください。
rent アカウントはありません:構造体は system_program で終わり、13 個の宣言されたアカウントです。位置 14 に迷った rent は、オプションのビットマップ拡張機能が読み込まれる場所に正確に着地するため、インラインビットマップの外にあるティックアレイを最初に作成する必要があるまで、オーダーは機能しているように見えます — その後失敗します。
アカウントリスト変更(2026-07 リリース)。 OpenLimitOrder は入力側に加えて出力側アカウント — output_token_account、output_vault、output_vault_mint — も取得するようになりました。これらは検証にのみ使用されます。プログラムは所有者の入力または出力トークンアカウントがフリーズされている場合、オーダーを拒否します。これにより、フィルが実際に所有者の出力 ATA に決済できることが保証されます。これは許可リスト/デフォルトフリーズ Token-2022 ミント(例:許可トークン)の場合に重要です。ここでアカウントはまだシャされていない可能性があります。古い片側アカウントリストに対して構築されたクライアントは、3 つの出力アカウントを追加する必要があります。
前提条件
  • input_token_account も output_token_account もフリーズされていません(そうでない場合は NotApproved)。
  • pool_state.status はスワップ(ビット 4)とリミットオーダー(ビット 5)操作の両方を許可します(そうでない場合は NotApproved)。
  • tick_index % pool.tick_spacing == 0 で [MIN_TICK, MAX_TICK] 内。
  • tick_index は選択された方向に対して pool.tick_current の右側にあります(token0 を売却 → ティックは現在より上である必要があり、その逆も同様)。既に横切られたティックで売却することはすぐにマッチングされ、拒否されます。
事後条件
  • limit_order が存在し、オープン時に tick.order_phase と tick.unfilled_ratio_x64 をスナップショットします。
  • tick.orders_amount += amount(現在のコホート内)。
  • limit_order_nonce.order_nonce += 1。
  • OpenLimitOrderEvent が発行されます。
一般的なエラー — NotApproved(入力または出力トークンアカウントがフリーズ、またはプールがスワップ/リミットオーダーを無効化)、ZeroAmountSpecified(入力側転送フィー後 amount == 0)、InvalidLimitOrderAmount(金額がそのティックで 1 ベースユニット未満の出力を生成するか、u64 をオーバーフロー)、InvalidTickIndex([MIN_TICK, MAX_TICK] の外、または選択された方向に対して tick_current の間違った側)、TickAndSpacingNotMatch(tick_index % pool.tick_spacing != 0)、OrderPhaseSaturated。

IncreaseLimitOrder

既存のオープンオーダーに追加します。オーダーの owner のみが呼び出し可能です。 引数
アカウント — 8、入力側のみ。ノンスアカウント、3 つすべての出力側アカウントおよび system_program をドロップします。 前提条件
  • limit_order.owner == signer。
  • オーダーはまだ同じコホート内にあります(tick.order_phase == limit_order.order_phase)。コホートが既に埋め始めている場合、オーダーは部分的に決済されています — 呼び出し元は最初に DecreaseLimitOrder または SettleLimitOrder を呼び出して前に進める必要があります。
効果
  • 所有者 ATA から input_vault に amount を転送します。
  • limit_order.total_amount += amount。tick.orders_amount += amount。

DecreaseLimitOrder

オープンオーダーを削減またはキャンセルします。未埋め部分を所有者に払い戻し、過去の部分埋めによって既に決済された出力も払い戻します。 引数
アカウント — 入力と出力トークン側の両方: 効果
  • オープン以降のコホートの unfilled_ratio_x64 からオーダーの埋められた金額を再計算します。
  • 埋められた出力を output_token_account に送信します。
  • 未埋め入力の amount を input_token_account に送り返します。
  • limit_order をそれに応じて更新します。新しい未埋め残高がゼロの場合、プログラムはアカウントをクローズし、レント を owner に払い戻します。

SettleLimitOrder

満たされた出力トークンをオーダーの未決済残高を変更せずにオーナーにプッシュします。auto_withdraw キーパーが長時間実行される部分的な約定をドリップペイしたい場合に便利です。 呼び出し元 — オーダーの owner、またはプログラムの limit_order_admin(自動キーパーループを実行するオフチェーン運用ホットウォレット)。キーパーは他の権限を持たず、満たされた出力をオーダーの owner ATA にプッシュする以外にユーザーファンドを移動することはできません。 アカウント 効果
  • (limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64) を使用して累積出力を計算します。
  • デルタを output_token_account に転送します。
  • limit_order.settled_output を更新します。
  • オーダーを閉じません。残りの入力に対してまだ開いています。

CloseLimitOrder

完全に消費されたオーダーアカウントを閉じます。誰が署名するかに関わらず、レントは常に limit_order.owner に返されます。 呼び出し元 — owner または limit_order_admin。 前提条件
  • オーダーの未決済残高がゼロです(amount == total_amount が満たされて決済されたか、オーナーが以前オーダーをゼロに減らして閉じるのを忘れました)。
効果
  • limit_order を閉じます。レントは limit_order.owner に送信されます。

CreateDynamicFeeConfig(管理者)

u16 インデックスの下に再利用可能なパラメータセットを作成します。 引数
アカウント 一般的なエラー — InvalidDynamicFeeConfigParams(decay_period <= filter_period の場合、または 0 値フィールドが範囲外の場合)。

UpdateDynamicFeeConfig(管理者)

既存の DynamicFeeConfig を変更します。作成時にすでにコンフィグをスナップショットしたプールは遡及的に更新されません。このコンフィグを参照する新しく作成されたプールのみが新しい値を取得します。 引数 — CreateDynamicFeeConfig と同じ 5 つのキャリブレーションフィールド(filter_period、decay_period、reduction_factor、dynamic_fee_control、max_volatility_accumulator)。index は作成時に固定され、ここでは再度渡されません。

CollectProtocolFee / CollectFundFee

プールのボルトから蓄積されたプロトコル/ファンドフィーを受取人にスイープし、対応する PoolState.protocol_fees_* / fund_fees_* フィールドをゼロにします。これは CPMM のレイアウトではありません — CLMM には authority アカウントがなく、受取人フィールドは recipient_token_{0,1}_account ではなく recipient_token_account_{0,1} という名前です。 引数 — amount_0_requested: u64、amount_1_requested: u64。
2026-09 で変更:新しいコンフィグはもはや署名者からフィー所有者を取得しません。 create_amm_config はプログラムのハードコードされた protocol_fee_owner::ID を owner に、fund_fee_owner::ID を fund_owner に書き込むようになりました。以前は、管理者署名者のキーを両方にコピーしていました。メインネットでは、これらはすでに既存の 21 個のコンフィグすべてに保存されている同じキーです。アドレスは reference/program-addresses にあります。上記の受け入れられた署名者は変わりません。管理者はまだ任意のコンフィグから収集でき、既存の AmmConfig アカウントは書き直されません。どちらかの値を想定するのではなく、アカウントから owner / fund_owner を読み取ってください。UpdateAmmConfig パラメータ 3 と 4 はまだそれらをローテーションします。

CollectExcessLamports

CLMM が制御するアカウント上のレント免除最小値を超えるラムポートの管理者スイープ。SIMD-0437 レント削減が各ステップの前に作成されたアカウントに残す過剰資金を回収するために 2026-09 アップグレードで追加されました。 過剰分のみが移動します。トークン残高、アカウントデータ、オーナー、プール状態、価格曲線は変わりません。アカウントがすでに最小値にある場合は、そのままにされるため、各ロールアウトステップ後に命令を安全に再実行できます。 引数:なし。 アカウント スコープ:呼び出しごとに 1 つのプール。 CLMM にはプログラム全体のボルト権限がありません。各プールのボルトは独自の PoolState によって所有されます。したがって、すべてのトークンプログラムソースは、スロット 2 の pool_state をその権限として持つ必要があります:token_vault_0、token_vault_1、またはそのプールの報酬ボルトの 1 つ。別のプールのボルトまたはユーザーのトークンアカウントを渡すと、トークンプログラムのオーナーチェックが失敗し、命令全体が戻ります。スキップされません。ポジション NFT ミントはスイープできません。ポジションが開かれるとミント権限が取り消されるためです。 各ソースアカウントの処理方法 プログラムは remaining_accounts に対して 2 つのパスを実行します:最初にすべてのトークンプログラム CPI、次に直接デビット。2 つをインターリーブするとランタイムの UnbalancedInstruction エラーで中止されるため、順序はプログラムで固定され、リストを自分でソートする必要はありません。
パス 2 はユーザーがレントを支払ったアカウントをカバーします。 ここに渡された PersonalPositionState または LimitOrderState は、他の CLMM 所有アカウントと同様に過剰分を放棄します。レント免除のままで、データを保持します。後で閉じられるとき、オーナーはアカウントがその時点で保持しているものを取得します。スイープ後は現在のレント最小値です。
トランザクションサイズは、1 回の呼び出しに収まるソースの数に対する実際の制限です。これは solana-fundamentals/rent-and-reclaimable-rent で説明されているウォレット側スイープと同じ制約です。 一般的なエラー:
  • NotApproved(6000):間違った署名者。
  • LamportsCalculateError(6052):wSOL ラウンドトリップがゼロに正味化されませんでした。
  • トークンプログラムオーナー不一致エラー:トークンソースが pool_state によって所有されていません。
  • InsufficientFunds:プログラム所有アカウントが独自のレント最小値より少ないです。
SDK ビルダーなし。 @raydium-io/raydium-sdk-v2 はこの管理者パスのビルダーを提供しません。IDL から手動でエンコードしてください。

InitializeReward

プールに新しい報酬ストリームを追加します。最大 3 つのストリームが同時にアクティブになる可能性があります。 引数 — 単一の構造体、param: InitializeRewardParam:
ワイヤエンコーディングは 3 つのフィールドが背中合わせなので、手動で構築された命令は影響を受けません — ただし、IDL 駆動クライアントは 3 つの位置引数ではなく 1 つの param オブジェクトを渡す必要があります。 アカウント 前提条件
  • プール上で現在 3 未満のストリームがアクティブです。
  • ファンダーは total_emission = emissions_per_second × (end_time − open_time) 相当の報酬トークンをこの命令の一部としてボルトに預けます。
  • operation_state ごとにホワイトリストされた報酬ミント。

SetRewardParams

既存の報酬ストリームを拡張、トップアップ、または排出率を変更します。通常、プール作成者または Raydium マルチシグによって呼び出されます。制約はオンチェーンに存在します:通常、end_time を拡張したり排出を増やしたりできますが、遡及的に縮小することはできません。operation_state のオーナーリストを確認してください。

UpdateRewardInfos

純粋な簿記 — reward_growth_global_x64 を emissions_per_second × Δt / liquidity を乗算することで現在の時刻に決済します。流動性に触れるすべての命令によって内部的に呼び出されます。外部アクター(UI、クランク)がそれをトリガーしたい場合があるため、スタンドアロン命令として公開されます。

報酬の収集

スタンドアロンの報酬収集命令はありません。 プログラムは CollectReward エントリポイントを公開せず、公開された IDL にもありません。
ポジションに対する報酬は DecreaseLiquidity / DecreaseLiquidityV2 によって支払われます。ポジションを変更せずに収集するには、liquidity = 0、amount_0_min = 0、amount_1_min = 0 で呼び出してください。報酬ボルトと受取人アカウントは remaining_accounts に、アクティブな報酬ごとに 3 つのグループで、reward_token_vault(W)、recipient_token_account(W)、reward_vault_mint の順序で入ります。 CollectRemainingRewards は別のもので、報酬ファンダーがストリームの end_time 後に、ポジションに割り当てられなかったトークンをスイープできます。

状態変更マトリックス

次のステップ

参考資料: