Skip to main content
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →

不変量

CPMM は、2 つのボールトに対して古典的な定価公式の不変量を維持しています: xy=kx \cdot y = k ここで x はボール0の残高の Token-2022 転送手数料、y も同様です。すべてのスワップは、LP に付与されたトレード手数料を考慮した後、k' ≥ k を保つ必要があります。プロトコル、ファンド、およびクリエイター バケットはカウントされません(ボール内に存在しますが、曲線ビューから除外されます。下記の 曲線上の手数料 を参照)。したがって、k は LP が手数料を蓄積するにつれて、時間とともに単調に増加します。 LP シェアは k ではなく、プールの準備金によって価格設定されます: LP price in token0=xlpSupply,LP price in token1=ylpSupply\text{LP price in token0} = \frac{x}{\text{lpSupply}}, \qquad \text{LP price in token1} = \frac{y}{\text{lpSupply}} ΔLP の LP トークンを焼却すると、正確に ΔLP × x / lpSupply の token0 および ΔLP × y / lpSupply の token1 が返されます。デポジットまたはウィズドローアルではいずれも曲線も k も動きません。価格を変更するのはスワップのみです。

スワップパスのフィー モデル

CPMM は、すべてのスワップに対して2 つの独立した手数料レートを適用します:
  • トレード手数料はインプット側で取られ、AmmConfig.trade_fee_rate で請求されます。その後、LP、プロトコル、およびファンド シェアに分割されます。LP シェアはボール内に留まり、k が増加します。プロトコル シェアとファンド シェアはボール アカウンティングから抽出されます)。
  • クリエイター手数料enable_creator_fee == true の場合のみアクティブ)は AmmConfig.creator_fee_rate で請求されます。スワップの方向に応じて、インプット側またはアウトプット側で取られます(products/cpmm/fees を参照)。これはトレード手数料のスライスではなく、独自のバケットです。
以下を定義します:
  • FEE_RATE_DENOMINATOR = 1_000_000
  • trade_fee_rateAmmConfig から、例えば 2500 = 関連するボリューム側の 0.25%
  • creator_fee_rateAmmConfig から、例えば 1000 = 関連するボリューム側の 0.10%
  • protocol_fee_ratefund_fee_rate — ボリュームではなく、トレード手数料の 1/FEE_RATE_DENOMINATOR の単位で表示
クリエイター手数料がインプット側の場合:
クリエイター手数料がアウトプット側の場合:
どちらの場合でも、トレード手数料は同じ方法で分割されます:
protocol_fee + fund_fee + creator_fee の金額はボール内に保持されていますが、プール状態(protocol_fees_token*fund_fees_token*creator_fees_token*)で個別に追跡されます。定価公式の不変量が k' ≥ k をチェックするとき、ボール残高マイナスすべての 3 つの蓄積されたが未回収の手数料を使用します。したがって、LP は lp_fee のみを取得します。 徴収指示および計算例については、products/cpmm/fees を参照してください。

SwapBaseInput (入力確定)

「ユーザーが入力ミントの正確に amount_in をくれて、アウトプット ミントの少なくとも minimum_amount_out を受け取ります。」 当分の間 Token-2022 を無視すると:
代数的には: amount_out=yΔxnetx+Δxnet\text{amount\_out} = \frac{y \cdot \Delta x_{\text{net}}}{x + \Delta x_{\text{net}}} ここで Δx_net = amount_in_after_trade_fee です。 プログラムは次にボール アカウンティングを更新して、プロトコル/ファンド/クリエイターが負う trade_fee の部分は「蓄積」バケットに存在します(次の x の曲線に含まれない)。一方、LP シェアは次のスワップに向けて x に参加します。

インプット側の Token-2022

入力ミントに転送手数料の拡張機能がある場合、ミントはユーザー → ボール への転送時に手数料を控除します。したがって、ボールは実際に amount_in − transfer_fee_in(amount_in) を受け取ります。CPMM プログラムは以下を計算します:
そして、amount_in_after_trade_fee に対して曲線を実行します。これは重要です。曲線の価格はボール内に到着したネット金額から計算されるため、ユーザーの見出し金額ではありません。

アウトプット側の Token-2022

アウトプット ミントに転送手数料がある場合、プールはボール内の amount_out をユーザーに送信します。その後、ミントは出時に手数料をスキムするため、ユーザーは amount_out − transfer_fee_out(amount_out) を受け取ります。プログラムは通常通り曲線から amount_out を計算しますが、見積もりを表示するときにボールの「ボール送信」数をユーザーの「ユーザー受取」数に変換するのは、インテグレーターの責任です。

スリッページ チェック

amount_out を計算した後:
アウトプット ミントが転送手数料を請求する場合、SDK はスリッページ定数がボールが送信するものではなく、ユーザーが実際に受け取るもので表示されるように、minimum_amount_out を設定する前に転送手数料を適用します。

SwapBaseOutput (出力確定)

「ユーザーはアウトプット ミントの正確に amount_out を受け取り、入力ミントの最大 maximum_amount_in まで支払う意思があります。」 Δx_net の曲線を反転します: Δxnet=xamount_outyamount_out\Delta x_{\text{net}} = \left\lceil \frac{x \cdot \text{amount\_out}}{y - \text{amount\_out}} \right\rceil 上限は重要です。整数の切り詰めの後、k' ≥ k が保証されます。その後:
Token-2022 インプットで、以下でラップします:
ユーザーが十分に支払うため、ミントの転送手数料控除後、プールは依然として gross_needed を受け取ります。

スリッページ チェック

計算例

プール状態、Token-2022 を無視:
  • x = 1_000_000_000_000 (token0 の 1,000,000.000000、6 小数点)
  • y = 2_000_000_000_000 (token1 の 2,000,000.000000、6 小数点)
  • AmmConfig: trade_fee_rate = 2500protocol_fee_rate = 120_000fund_fee_rate = 40_000creator_fee_rate = 0
ユーザー:SwapBaseInputamount_in = 1_000_000_000 (token0 の 1,000.000000)。クリエイター手数料は無効です(enable_creator_fee = false)。
同じプールが enable_creator_fee = truecreator_fee_rate = 1000 (0.10%) をインプット側に持っていた場合、プログラムは total_input_fee = ceil(1_000_000_000 * 3500 / 1_000_000) = 3_500_000 を請求し、次に creator_fee = 1_000_000 および trade_fee = 2_500_000 に分割します。上記の例から trade_fee のプロトコル/ファンド/LP 算術は変わりません。クリエイター手数料は独自のバケットで、creator_fees_token0 に蓄積され、プロトコルおよびファンド バケットとともに curve_x から除外されます。 入力ミントに 1% の Token-2022 転送手数料がある場合、ボールは 1_000_000_000 トークンではなく 990_000_000 トークンを受け取り、以降のすべての計算はそのネット金額を使用します。

オブザベーション更新ルール

すべてのスワップで、プログラムは新しいオブザベーションをリング バッファにプッシュするかどうかを評価します:
2 つのプロパティ:
  • 累積価格、スポット価格ではない。 単一のオブザベーションは価格ではありません。時刻 t0 から t1 まで TWAP を取得するには、各端に最も近いオブザベーションを読み、(cumulative(t1) − cumulative(t0)) / (t1 − t0) を計算します。
  • サンプルはレート制限されます。 同じスロット内のバック・ツー・バック スワップは 1 つのオブザベーションを共有できます。スワップの直後にオブザベーションを読むと、1 スロット古い可能性があります。これは正常です。
詳細は products/clmm/accounts を参照してください。

曲線上の手数料

これは微妙な部分で、呼び出す価値があります。曲線の算術はネットボール残高に対して機能します。つまり、生の SPL 残高からプロトコル、ファンド、およびクリエイター手数料を蓄積したもの(3 つすべて独立したバケットです。products/cpmm/fees を参照)を差し引いたもの。具体的なイメージ:
インテグレーターの結果:
  • 生の残高から見積もらないでください。 最初に蓄積手数料フィールドを差し引くか、SwapBaseInput をシミュレーションとして呼び出してその戻り値を取得してください。
  • CollectProtocolFee がトークンをボール外に移動します。 徴収後、raw_vault_balance が低下しますが、curve_balance は変わりません。プールの価格は移動しません。これは意図的です。

精度およびオーバーフロー

  • すべての曲線算術は x * y でオーバーフローを防ぐために u128 中間値を使用します。
  • 除算はゼロに向かって丸められます。ただし、SwapBaseOutputΔx_net は切り上げ、手数料計算では trade_fee で切り上げ、部分分割で切り下げされます。これらの丸め方向は、不変量が整数の切り詰めのため減少しないよう選択されています。
  • 極端なボール比率(数十億:1)を持つプール は、小さなトレードで精度の床にヒットしてください。その場合、プログラムは ZeroTradingTokens を返します。reference/error-codes を参照してください。

次に進むこと

出典: