Skip to main content
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
このページでは、各アカウントのレイアウトと役割について説明します。シード値は正規のものであり、reference/program-addresses に記載されています。CLMM プールは CPMM プールよりもアカウント数が多いです。これはリクイディティがティック範囲全体に疎らに保存されるためです。この疎性の理解がこのページの大部分を占めます。

アカウント一覧

ライブ CLMM プールは、以下のアカウント群で構成されます。すべて CLMM プログラムによって所有されていますが、2 つのミントとそのボルトは除きます。

PoolState

プールのライブ状態。すべてのスワップとすべてのポジション変更時に読み取られます。
実際に操作するフィールド:
  • sqrt_price_x64 と tick_current はプールの価格状態です。すべてのスワップで一緒に更新されます。tick_current は log_{1.0001}(price) の床です。
  • liquidity はアクティブリクイディティです。tick_current を含む範囲内のすべてのポジションの L 値の合計です。スワップがティックを横切るたびに、またはポジションが開かれる/閉じられる/リサイズされるたびに変更されます。
  • fee_growth_global_{0,1}_x64 は、プール全体の履歴全体にわたるリクイディティ単位あたりの累積手数料です。ポジションはこれを読み取って、自分たちに何が支払われるべきかを計算します。
  • tick_spacing は初期化時に AmmConfig にロックされ、変更されることはありません。ポジション エンドポイントとして許可されるティック インデックスを決定します。
  • tick_array_bitmap は、スポット価格周辺の一般的に使用されるティック範囲をカバーするインラインビットマップです。ポジションが遠くまで達するプールの場合、オーバーフロー追跡は別の TickArrayBitmapExtension に存在します。
  • fee_on はプール作成時に固定されます。0(FromInput)は古典的な Uniswap-V3 の動作を再現します。1 と 2 はスワップ手数料をブックの単一側にルーティングします。トレードオフについては products/clmm/fees を参照してください。
  • seed_index は、CreatePool / CreateCustomizablePool 経由で作成されたすべてのプールで [0, 0] です(ペアあたり 1 つの正規プール)。ゼロ以外の値は、プールが CreateCustomizablePoolV2(2026-10-22 前は CreatePermissionedPool という名前)経由で作成されたことを意味し、インデックスはプールの PDA シードの一部です。同じ (config, mint0, mint1) に対して複数のプールが共存できます。そのようなプールのアドレスを再導出するには、その seed_index を知る必要があります。
  • dynamic_fee_info はダイナミック フィー サージの変動性状態を保持します。有効な場合、すべてのスワップは AmmConfig.trade_fee_rate の上に dynamic_fee_component を再計算します。レイアウトは下の DynamicFeeInfo に記載されています。ダイナミック フィーなしのプールは構造体全体をゼロのままにします。

AmmConfig

2026-09 アップグレード以降、CreateAmmConfig はプログラムのハードコードされた protocol_fee_owner::ID を owner に、fund_fee_owner::ID を fund_owner に書き込みます。それ以前は、管理者署名者のキーを両方にコピーしていました。既存の設定は、作成またはローテーションされたものを保持しているため、アカウントから両方のフィールドを読み取ります。UpdateAmmConfig パラメータ 3 / 4 はそれでも両方をローテーションします。アドレスは reference/program-addresses にあります。 典型的に公開されている CLMM フィー層のセット(GET https://api-v3.raydium.io/main/clmm-config に対して確認): protocol_fee_rate と fund_fee_rate はトレード手数料の分数です。CPMM と同じ規約です。products/clmm/fees を参照してください。

TickArrayState

CLMM は 1 つのティックごとに単一のレコードを保存しません。それでは数十億のアカウントが必要になります。代わりに、隣接する初期化済み・未初期化のティック TICK_ARRAY_SIZE 個(通常、プログラムバージョンによって 60 または 88)を 1 つの TickArrayState にグループ化し、初回使用時に遅延作成します。
4 つのリミットオーダーフィールドは、リミットオーダーに使用されたことのないティックではすべてゼロです。オーダーがティックで開かれると、プログラムはそれらをコホートのシーケンスとして追跡します。
  • order_phase はコホート ID です。コホートが「すべて未約定」から「部分的に約定」に遷移するたびにインクリメントされます。
  • orders_amount は現在の(最新の)コホートの入力トークン合計です。
  • part_filled_orders_remaining は、進行中のスワップによって現在約定中の前のコホートを追跡します。
  • unfilled_ratio_x64 はコホートに付与される Q64.64 乗数です。スワップがコホートの X% を約定させると、比率は (1 − X) で乗算されます。各オープンオーダーはオープン時に独自の (order_phase, unfilled_ratio_x64) スナップショットを保存するため、決済計算はスナップショットの比較に帰着します。
ルール:
  • ポジションのエンドポイントティック t は t % tick_spacing == 0 を満たす必要があります。プログラムはスペーシング外のポジションを拒否します。
  • ティックの配列は floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing) に位置します。
  • ティック配列は遅延初期化されます。未初期化の配列に触れる最初のポジションまたはスワップが、レント代を支払って作成します。
  • ティック配列はプログラムによって決して閉じられません。割り当てられると、内部のすべてのティックが liquidity_gross == 0 に戻った後でも、プール存続期間中は永続します。その後のポジションとスワップは、追加のレント代なしで既存のアカウントを再利用します。ティック配列のクリーンアップパスとして ClosePosition 駆動型はありません。

TickArrayBitmapExtension

PoolState.tick_array_bitmap(インライン)は「スポット付近」の範囲をカバーします。±512 ティック配列(TICK_ARRAY_BITMAP_SIZE = 512;[u64; 16] フィールドは 1,024 ビットで負と正の開始インデックスに均等に分割され、配列インデックス −512 … +511)。その範囲外(極端なティック値の場合)、プログラムは拡張アカウントを保持します。
ポジションの範囲が「通常」の場合、拡張アカウントについて考える必要はありません。フルレンジポジション(例:(MIN_TICK, MAX_TICK))にはそれが必要です。SDK がそれを解決します。

ポジション

CLMM ポジションは、3 つのアカウントとミントのバンドルです。

ポジション NFT ミント

供給量が 1 の SPL Token または Token-2022 ミント。オーナーのウォレット内のポジション NFT は、その単一トークンを保有する ATA です。プログラムは状態に保存された Pubkey ではなく、NFT の ATA 残高の現在の保有者に認可をキーイングします。 新しいポジション NFT ミントは、単一トークンをミントしてミント権限を削除する前に、pool_state をフリーズ権限として設定します。フリーズ権限を設定しても、それ自体は NFT アカウントをフリーズしません。 OpenPositionV2 または OpenPositionWithToken22Nft を使用し、かつ基礎となるボルトミントの少なくとも 1 つのフリーズ権限が CLMM の制限発行者リストに表示される場合にのみ、アカウントはフリーズされたままで転送可能です。その場合のみ、CLMM はミント後に NFT アカウントをフリーズします。これは PersonalPositionState または PoolState バイトを変更しません。

PersonalPositionState

オープンポジションごとに 1 つ。NFT ミントでキーイングされます。

ProtocolPositionState(非推奨)

古い CLMM リリースでは、(pool, tick_lower, tick_upper) ごとの集計ブックキーピングを ProtocolPositionState PDA に保存していました。新しいリリースではこのアカウントを作成または読み取りません。 スロットは ABI 互換性のため OpenPosition / IncreaseLiquidity / DecreaseLiquidity アカウントリストに UncheckedAccount として表示されたままですが、プログラムはそれに書き込みません。チェーン上の既存アカウントは痕跡です。管理者は CloseProtocolPosition を呼び出してそれらのレント代を回収できます。集計範囲ブックキーピングは、TickArrayState の 2 つのエンドポイントティック(liquidity_gross、liquidity_net、ティックごとの fee_growth_outside_* / reward_growths_outside_x64)から直接導出されるようになりました。フィー成長内部公式 fee_growth_inside = global − outside_lower − outside_upper は、集計ポジションアカウントなしで引き続き機能します。

オブザベーション

CLMM のオブザベーションバッファは、累積価格ではなく累積ティックを保存します。外部コンシューマーは (tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) から区間にわたる幾何平均価格を計算し、その後 price = 1.0001 ** tick を計算します。algorithms/clmm-math を参照してください。

DynamicFeeConfig と DynamicFeeInfo

ダイナミックフィーパラメーターは 2 つの場所に存在します。再利用可能なテンプレート DynamicFeeConfig は管理者が管理し、オプトインしたプール間で共有されます。プールごとのランタイム状態 DynamicFeeInfo は PoolState に埋め込まれ、すべてのスワップによって更新されます。

DynamicFeeConfig

PDA シード:["dynamic_fee_config", index.to_be_bytes()]。create_dynamic_fee_config(管理者ゲート)で作成され、update_dynamic_fee_config で変更されます。enable_dynamic_fee = true で作成されたプールは、作成時にコンフィグの 5 つのキャリブレーションパラメーター(filter_period、decay_period、reduction_factor、dynamic_fee_control、max_volatility_accumulator)を独自の DynamicFeeInfo にスナップショットします。その後の DynamicFeeConfig への編集は、既存のプールに遡及的に影響しません。

DynamicFeeInfo(PoolState に埋め込み)

下位 4 つのフィールドは状態です。上位 5 つは DynamicFeeConfig からコピーされたキャリブレーションです。フィー計算と減衰ルールは products/clmm/math と products/clmm/fees に記載されています。 公式で使用される定数:

LimitOrderState

オープンリミットオーダーごとに 1 つのアカウント。
ライフサイクル:
  1. オープン — ユーザーが open_limit_order を呼び出し、入力トークンの total_amount をデポジットし、オーダーは TickState コホートにバインドされます。
  2. (オプション)増加 / 減少 — increase_limit_order は total_amount に追加します。decrease_limit_order は未約定トークン(およびその時点までの決済済み出力)を返します。
  3. 決済 — コホートが完全または部分的に約定されると、オーナーまたは運用キーパーが settle_limit_order を呼び出して、出力トークンをオーナーの ATA にプッシュします。
  4. クローズ — unfilled_amount == 0 になると、アカウントはクローズ可能です。レント代は常に owner に返されます。
PDA シード:[owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]。オーダー PDA は (owner, nonce_index, order_nonce) ごとに一意です。

LimitOrderNonce

ユーザーが複数の並列リミットオーダーパイプラインを実行する際に、PDA の衝突を避けるための (wallet, nonce_index) ごとのカウンター。
PDA シード:[user_wallet.as_ref(), &[nonce_index]]。ほとんどのクライアントは nonce_index = 0 を使用し、order_nonce で基数を管理します。

Permission(廃止)

Permission アカウントは 2026-10-22 アップグレード で削除されました。以前は CreatePermissionedPool をゲートしていましたが、現在はパーミッションレスの CreateCustomizablePoolV2 に置き換わっています。プログラムはこれらのアカウントを読み取ったり閉じたりしなくなり、CreatePermissionPda / ClosePermissionPda 命令は廃止されました。アップグレード前に作成された PDA(["permission", authority]、280 バイト)はチェーン上に不活性データとして残ります。CLMM 所有アカウントをスキャンする際は無視してください。

キーアカウントの導出

正確なシード文字列は、常にオンチェーン IDL と reference/program-addresses に対して確認してください。

ライフサイクル クイックリファレンス

TickArrayState アカウントはプログラムによって決して閉じられません — プールの存続期間中ずっと保持されます。ティック配列が初期化されると、その中のすべてのティックが liquidity_gross == 0 に戻った場合でも、チェーン上に残ります。既存のティック配列を再利用するのは無料です。初めて初期化されていない配列に触れるポジションだけがそのレントを支払います。

各トピックの参照先

ソース: