Skip to main content
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
CPMM のプログラム ID と PDA シードは reference/program-addresses に正式に記載されています。このページは、ハードコードされたアドレスではなく、各アカウントの用途と保持する不変量に焦点を当てています。

CPMM プールの 6 つのアカウント

すべての CPMM プールは、CPMM プログラム下の 6 つのプログラム派生アドレス(PDA)と、それが参照する 1 つの共有 AmmConfig アカウントで完全に記述されます。2 つのミントがあれば、ネットワークに接触することなく、すべてを決定論的に導出できます。 および共有設定:

2 つのミントだけからプールを導出

プール PDA を導出する前に、常にミントをソートしてください。 シードはユーザー順ではなく、バイト順で 2 つのミントをハッシュします。(A, B)(B, A) を持つ 2 つのプールはオンチェーンで衝突します — ソートはプログラムがマッピングを正規にする方法です。
プール ID は常に正規 PDA ではありません。 Initialize は、上記の PDA に加えて、pool_state として任意の署名者キーペアを受け入れます。渡されたアカウントが正規 PDA と一致しない場合、プログラムはそれが署名者であることを要求します — つまり、クリエイターは自分が署名する新しいキーペアを渡します。これが前走り防御です:正規 PDA を掴むためにレースしている第三者は、正当なクリエイターがランダムキーペアを代わりに使用することで回避できます。ダウンストリーム PDA(lpMintvault0vault1observation)は依然として poolState.key() から導出されるため、使用されたアドレスに関わらず一意のままです。プールをインデックス化する場合、正規 PDA を導出することではなく、オンチェーン状態からプール ID を常に検出してください(例:CPMM プログラム下の PoolState アカウント)— 後者はランダムキーペアプールを見落とします。

アカウントレイアウト

完全な Rust 定義は raydium-cp-swap ソースに存在します。以下のフィールドは、統合から読み取るものです。

PoolState

実際に読み取るべきもの:
  • lp_supply — LP ミントの総供給量のプールの内部ミラー。LP シェア計算に使用します。値はミントのオンチェーン供給量と一致する必要がありますが、PoolState から読み取ることで追加のアカウント取得を回避します。
  • protocol_fees_token{0,1}fund_fees_token{0,1}蓄積された フィーはまだスイープされていません。これらはスワップ価格に影響しません。CollectProtocolFee / CollectFundFee が呼び出されるまでボルトに留まります。
  • statusSwapDepositWithdraw が許可されているかどうかを制御するビットマスク。UpdatePoolStatus を介して管理者によって更新されます。SDK はトランザクションを構築する前にこれをチェックします。直接 CPI している場合は、自分でチェックしてください。
  • token0_program / token1_program — 各ボルトに CPI するトークンプログラム。1 つは古典的な SPL Token で、もう 1 つは Token-2022 である可能性があります。これらは独立しています。
  • open_time — Unix タイムスタンプ。この時間前のスワップは失敗します。open_time 前のデポジットは許可されるため、プールをシードできます。
  • creator_fee_on / enable_creator_fee — 一緒に、このプールに対してオプションのクリエイターフィーがアクティブであるかどうか、およびスワップのどちら側から収集されるかを制御します。enable_creator_fee == false はクリエイターフィーパスを完全にゼロにします。有効な場合、creator_fee_on は以下を選択します:0 = スワップ入力であるトークンからフィーを取得(BothToken);1 = token_0 からのみフィーを取得(token_1 → token_0 スワップをスキップ);2 = token_1 からのみフィーを取得。InitializeWithPermission を介してプール作成時に設定;その後変更できません。
  • creator_fees_token_{0,1} — 蓄積されたクリエイターフィー、CollectCreatorFee または CollectCreatorFeePermissionless によってスイープされます。両方のパスは完全なカウンターをゼロにします。パーミッションレスパスは受取人を pool_creator の正規 ATA に固定します。

AmmConfig

3 つの注意点:
  1. trade_fee_ratecreator_fee_rate はボリュームの分数で、両方とも 1/1_000_000 の単位で表示されます。2500 はトレードボリュームの 0.25% を意味します。protocol_fee_ratefund_fee_rateトレードフィーの 分数(ボリュームではなく)で、同じ 1/1_000_000 分母です。クリエイターフィーはトレードフィーの分数ではなく、独自の独立したレートです。完全な算術は products/cpmm/fees にあります。
  2. indexu16 なので、シードハッシュは 2 バイトのビッグエンディアンを使用します。バイト順のオフバイワンは一般的な統合バグです。
  3. AmmConfig はプールレベルで不変です。 プールは作成時に 1 つの AmmConfig を指し、決して切り替わりません。フィー変更は、プールが各スワップで設定を読み取るため伝播します — ただし、プールはフィーティア間で移動できません。
クリエイターフィーに関する注記:レート自体creator_fee_rate)は AmmConfig に存在し、フィーティア全体で共有されます。特定のプールが実際にそれを請求するかどうか(enable_creator_fee)、およびスワップのどちら側に着地するか(creator_fee_on)は PoolState に存在します。クリエイターフィーはトレードフィーの 独立した — 独自のレート、独自のカウンター(creator_fees_token_{0,1})に蓄積され、LP / プロトコル / ファンドのトレードフィーシェアを削減することはありません。スイープは CollectCreatorFee または宛先制約付き CollectCreatorFeePermissionless を介して行われます。完全なメカニクスについては products/cpmm/fees を参照してください。

Permission

InitializeWithPermission で使用される小さなアクセス制御アカウント。CPMM プログラムは、他のプログラム(例:LaunchLab がトークンを CPMM に卒業させる場合)が特定の AmmConfig に対してプールを作成する権利があることを証明できるように、パーミッション付きプール作成パスをサポートしています。
Permission PDA は、CPMM 管理者または専用パーミッション PDA クリエイター権限のいずれかによって CreatePermissionPda を介して作成されます。CPMM 管理者のみが ClosePermissionPda を介してそれを取り消すことができます。エンドユーザーはこのアカウントと直接対話しません — クロスプログラムフローのための配管です。ロール境界については security/admin-and-multisig を、正規アドレスについては reference/program-addresses を参照してください。

ボルトと Token-2022

vault0vault1 は CPMM authority PDA が所有し、それらのトークンプログラムオーナー(token_program)は SPL Token または Token-2022 で、プール作成時にミントのプログラムによって決定されます。プールは 2 つのケースを透過的に処理します — Swap / Deposit / Withdraw 命令アカウントで各側の正しいトークンプログラム ID を渡します。 CPMM はプール作成時に厳密な 拡張許可リスト を実施します(utils/token.rsis_supported_mint)。Token-2022 ミントは、それが保有する すべての 拡張がこのリストにある場合にのみ CPMM プールで使用できます:
  • TransferFeeConfig すべての転送でミントによって適用されます。プールは SwapBaseInput デポジットの受信側で、引き出しの送信側です。プログラムはボルトに着地する ネット 金額を計算し、曲線をそれに応じて設定します。algorithms/token-2022-transfer-fees を参照してください。
  • MetadataPointerTokenMetadata ミント上の標準メタデータ。スワップ数学に影響なし。
  • InterestBearingConfig ミントの UI 金額は利息を蓄積します。ボルトは生の金額を保存します。曲線は生の金額でのみ動作します。APR を表示する UI は Token-2022 ヘルパーを呼び出して UI 金額をレンダリングする必要があります。
  • ScaledUiAmount UI 表示スケーリング拡張。InterestBearingConfig と同じ処理 — 曲線は生の金額を使用します。
その他の拡張 — PermanentDelegateTransferHookDefaultAccountStateNonTransferableConfidentialTransferGroup/GroupMemberMintCloseAuthority など — は InitializeNotSupportMint で拒否させます。例外は、プログラムの小さなハードコード ミントホワイトリスト(いくつかの特定の公開鍵)で、拡張チェックをバイパスします。これは特定のミントをケースバイケースでオンボードするために使用されます。 検証済み拡張リストとミントホワイトリストは CP-Swap ソースの programs/cp-swap/src/utils/token.rs に存在し、将来のプログラムアップグレードで変更される可能性があります。

Observation

observation アカウントは ObservationState エントリのリングバッファで、各エントリは block_timestamp累積価格 を保存します。すべてのスワップで、最後のものから十分な時間が経過している場合、プログラムは新しい observation を追加します。TWAP は 2 つの observation を読み取り、Δcumulative / Δtime を除算することで計算されます。
リングバッファは 100 observations 用にサイズ設定されています。各 observation は 40 バイトなので、配列だけで 4,000 バイト。完全な ObservationState PDA は周囲のフィールドと判別器の後で約 4,100 バイトです。 2 つのコンシューマルール:
  • 単一の observation を価格として使用しないでください。 これは 累積 であり、スポット価格ではありません。2 つを使用して TWAP を計算します。
  • 少なくとも 1 ブロック離れた observation を選択してください。 同じブロック内のスワップは新しい observation を生成しない可能性があります。バックツーバックで読み取ると同じレコードが返される可能性があります。
詳細な数学については products/clmm/accounts を参照してください。

アカウントライフサイクル

CPMM プールとその PDA は 決して閉じられません。流動性がゼロでも poolState は残ります。これは意図的です:後で同じプールを再シードすることで、その履歴 observation バッファが保持され、その PDA 導出は安定したままです。

どこで何を読むか

ソース: