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

アカウント一覧

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

PoolState

プールのライブ状態。すべてのスワップとすべてのポジション変更で読み取られます。
実際に操作するフィールド:
  • sqrt_price_x64tick_current はプールの価格状態です。すべてのスワップで一緒に更新されます。tick_currentlog_{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 の動作を再現します。12 はスワップ フィーを本の片側にルーティングします。詳細は products/clmm/fees を参照してください。
  • seed_index は、CreatePool / CreateCustomizablePool 経由で作成されたすべてのプールで [0, 0] です(ペアごとに 1 つの正規プール)。ゼロ以外の値は、プールが CreatePermissionedPool 経由で作成されたことを意味し、インデックスはプールの PDA シードの一部です。同じ (config, mint0, mint1) に対して複数のプールが共存できます。そのようなプールのアドレスを再導出するには、その seed_index を知る必要があります。
  • dynamic_fee_info はダイナミック フィー メカニズムのボラティリティ状態を保持します。有効な場合、すべてのスワップは AmmConfig.trade_fee_rate の上に dynamic_fee_component を再計算します。レイアウトは以下の DynamicFeeInfo に記載されています。ダイナミック フィーなしのプールは構造体全体をゼロのままにします。

AmmConfig

公開されている典型的な CLMM フィー層セット(GET https://api-v3.raydium.io/main/clmm-config に対して確認): protocol_fee_ratefund_fee_rate はトレード フィーの分数です。CPMM と同じ規約です。products/clmm/fees を参照してください。

TickArrayState

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

TickArrayBitmapExtension

PoolState.tick_array_bitmap(インライン)は「スポットに近い」範囲をカバーします。±1,024 ティック配列。その範囲外(極端なティック値の場合)、プログラムは拡張アカウントを保持します:
ポジションの範囲が「通常」の場合、拡張アカウントについて考える必要はありません。フルレンジ ポジション(例:(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_grossliquidity_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 を参照してください。

DynamicFeeConfigDynamicFeeInfo

ダイナミック フィー パラメータは 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_perioddecay_periodreduction_factordynamic_fee_controlmax_volatility_accumulator)を独自の DynamicFeeInfo にスナップショットします。その後の DynamicFeeConfig への編集は、既存のプールに遡及的に影響しません。

DynamicFeeInfoPoolState に埋め込み)

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

LimitOrderState

オープン リミット オーダーごとに 1 つのアカウント。
ライフサイクル:
  1. オープン — ユーザーが open_limit_order を呼び出し、入力トークンの total_amount をデポジット、オーダーは TickState コホートにバインドされます。
  2. (オプション)増加 / 減少increase_limit_ordertotal_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

(ウォレット、nonce_index) ごとのカウンタ。単一ユーザーが PDA 衝突なしでリミット オーダーの複数の並列パイプラインを実行できます。
PDA シード:[user_wallet.as_ref(), &[nonce_index]]。ほとんどのクライアントは nonce_index = 0 を使用し、order_nonce にカーディナリティを実行させます。

Permission

その存在が許可である機能アカウント。特定の権限に対して Permission PDA が導出されると、その権限は CreatePermissionedPool を呼び出すことができます。それが作成された権限を超えて何も保存しません。
PDA シード:["permission", authority.as_ref()]。管理者が CreatePermissionPda 経由で作成し、ClosePermissionPda 経由で削除(レント払い戻し呼び出し元)。両方の管理者命令は、プログラム admin または専用の permission_pda_admin キーのいずれかを受け入れます。PDA をクローズすると許可が取り消されます。権限はそれ以上プールを作成できなくなりますが、既に作成したプールは影響を受けません。

キー アカウントの導出

正確なシード文字列は常にチェーン上の IDL と reference/program-addresses に対して二重チェックする必要があります。

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

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

どこで何を読むか

ソース: