Documentation Index
Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
Use this file to discover all available pages before exploring further.
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
スクエアルート価格表現
CLMMは価格をsqrt_price_x64 として保存します。これはトークン1あたりのトークン0の価格のスクエアルートを、Q64.64固定小数点数で表したものです。
ここで p = token1_amount / token0_amount です。sqrt を使用することで、スワップ数学が線形化されます(トークン量のデルタは Δsqrt_price について線形になります)。また、x64 固定小数点により、多数のティックを跨ぐスワップでも精度が保たれます。
ティック ↔ スクエアルート価格の変換は、bit-by-bit ログ近似により事前計算されます。
これは tick_math::get_sqrt_price_at_tick のルックアップベースの指数関数として実装されています。
正規単位としての流動性
範囲[sqrt_a, sqrt_b](sqrt_a < sqrt_b)内の流動性 L を持つポジションは、以下のようにトークン量にマップされます。ここで sqrt_c = sqrt_price_x64 はプールの現在の価格です。
| ケース | amount0 | amount1 |
|---|---|---|
sqrt_c <= sqrt_a(プール価格が範囲以下) | L · (sqrt_b - sqrt_a) / (sqrt_a · sqrt_b) | 0 |
sqrt_a < sqrt_c < sqrt_b(範囲内) | L · (sqrt_b - sqrt_c) / (sqrt_c · sqrt_b) | L · (sqrt_c - sqrt_a) |
sqrt_c >= sqrt_b(プール価格が範囲以上) | 0 | L · (sqrt_b - sqrt_a) |
x = L / sqrt_p、y = L · sqrt_p から導出されます。
インテグレーターは通常、逆の計算を望みます。amount0 / amount1 のデポジットが与えられたとき、範囲内に収まる最大の L を計算することです。SDKの LiquidityMath.getLiquidityFromTokenAmounts がこれを行います。範囲内のケースの公式は以下の通りです。
どちらのサイドが制約になるかによって、実際に消費される比率が決まります。もう一方のサイドには残金が残る場合があります。
シングルティックスワップステップ
スワップはステップで進みます。各ステップは、(a)現在のティック範囲内で利用可能なすべてのインプットを消費しティックを越えずに進む、または(b)価格を次の初期化されたティックに正確に移動させるかのいずれかです。 現在の状態(sqrt_c, L) と上向きの スワップ(トークン0イン、トークン1アウト、sqrt_price が増加)が与えられたとき、次の初期化されたティックまでの距離を sqrt_t とします。このマイクロ区間内で、インプットと価格の関係は以下の通りです。
および
プログラムは以下の2つの処理のいずれかを実行します。
-
全インプットがフィットする? 手数料差引後の残りインプットが
sqrt_tに到達するためのΔamount0より少ない場合、新しいsqrt_c'を正確に解きます。 (正確入力token0 → token1スワップの場合)。スワップはこのステップで完了し、ティックを越えることはありません。 -
インプットが
Δamount0を超える?sqrt_c' = sqrt_tを設定し、ティックを越えます(liquidity_netを適用)。残りインプットをΔamount0だけ減らし、アウトプットをΔamount1だけ増やして、繰り返します。
token1 → token0、価格が下がる)の場合、公式で sqrt_c と sqrt_t が入れ替わり、反転が別のスロットで起こります。
完全なRust実装は raydium-clmm/programs/amm/src/libraries/swap_math.rs にあります。そこのロジックはUniswap v3の SwapMath.computeSwapStep と一致しています。
各ステップの手数料
取引手数料はインプット量から各ステップで差し引かれます。これはCPMMと同じ規約です。L_i のポジションは、後で L_i · Δfee_growth_global / 2^{64} の返却トークンを読み取ることができます。
プロトコル部分とファンド部分は、それぞれ PoolState.protocol_fees_token_{0,1} と PoolState.fund_fees_token_{0,1} に蓄積され、CPMMと同じです。これらは CollectProtocolFee / CollectFundFee によってクリアされます。
範囲外および範囲内の手数料成長
CLMM手数料アカウンティングの難しい部分は、ポジションが範囲内に あるときのみ手数料を得るという点です。プールはグローバルな累積手数料を追跡しますが、ポジションはその特定の範囲内の累積手数料を知る必要があります。 解決策はティックベースアキュムレーターです。各ティックは以下を保存します。- プールの価格がこのティック上に ある場合(
tick_current >= this_tick)、fee_growth_outside = fee_growth_global。(これまで稼いだすべてが「外側」、つまり現在の価格に対してこのティック「下」にあります) - それ以外の場合
fee_growth_outside = 0。
fee_growth_outside をフリップします。
この不変式が保証するもの:任意のティック t について、fee_growth_outside(t) は tick_current が t の反対側にあったときに蓄積した手数料と等しいです。
範囲 [tick_lower, tick_upper] 内の手数料成長は、以下のように導出されます。
ポジションが保存するもの、読み取るもの
PersonalPositionState は fee_growth_inside_0_last_x64 と fee_growth_inside_1_last_x64 を保存します。これらはポジションが最後にタッチされたときの fee_growth_inside 値です。
その後のタッチ(増加、減少、収集)では、プログラムは以下を行います。
- 上記の公式を使用して、現在の
fee_growth_inside_{0,1}_x64を計算します。 Δ = fee_growth_inside_now − fee_growth_inside_last(u128上のモジュラ減算)を計算します。Δ × position.liquidity / 2^{64}をtokens_fees_owed_{0,1}に追加します。fee_growth_inside_lastを新しい値に更新します。
CollectFees / DecreaseLiquidity 時で、tokens_fees_owed に対してのみです。
リワード
プールの最大3つのリワードストリームのそれぞれは、独自のreward_growth_global_x64 アキュムレーターで同じ成長内機構を使用します。排出時に:
—排出はアクティブ流動性に反比例するスケーリングされるため、より密なプールは各ポジションに1秒あたりより少ないリワードを支払いますが、全体では複数のポジションにまたがります。ポジションあたりの返却リワードは
で、CollectReward 経由で請求されます。products/clmm/fees を参照してください。
実例:正確入力スワップ
仮定:tick_spacing = 60sqrt_price_x64 = 1 × 2^{64}—価格 = 1.0、つまりtick_current = 0。- アクティブ流動性
L = 1_000_000 × 2^{64}。 - 上の次の初期化ティック:
t = 60(sqrt_price_b ≈1.003004 × 2^{64})。 - 取引手数料率:500(0.05%)。
SwapBaseInput。
ステップ1 —手数料:
999 < 2995.5 なので、全インプットはティックを越えずに収まります。
ステップ3 —新しい価格:
sqrt_c' は sqrt_c よりやや下。ここで上記の公式は token1 → token0 スワップ用です。ここの例は token0 → token1 で、価格は上向きではなく下向きに駆動されます。そのため、token0 in に対応するフォームを使用します。
token0 → token1 の予想されるスワップ方向と一致します。sqrt_c は価格とともに上昇します)
ステップ4 —アウト量:
trade_fee_rate × protocol_fee_rate / 1e6(ファンドについても同様)で分割されます。LP部分は fee_growth_global_0_x64 にフローします。
スワップ中のリミットオーダーマッチング
スワップステップがオープンなリミットオーダーを保有するティックを越えるとき、これらのオーダーはティックの正確な価格で、LP曲線前に スワップインプットを消費します。マッチングはティック内でorder_phase コホート別のFIFOです。
TickState のコホートごとの状態
orders_amount に参加し、次の order_phase を継承します。前のコホートが完全に消費されるまで、フィルできません。
マッチングステップ
スワップ中の各ティック交差で発生するマッチングの疑似コード:SettleLimitOrder(または DecreaseLimitOrder)を呼び出すまで、プールのアウトプットボルト内に仮想的に座っています。プールは unfilled_ratio_x64 経由でコホートのフィル量だけを追跡します。各 LimitOrderState はオープン時に独自の (order_phase, unfilled_ratio_x64) スナップショットを保存するため、セットルメントは以下に減少します。
LP曲線との相互作用
スワップステップで、リミットオーダーマッチングはティックで起こります(ゼロΔsqrt_price)。LP曲線消費はティック間で起こります。したがって順序は:
- ティック
t_crossを越えます(LPliquidity_net変更を最初に適用します。これはUniswap-V3がする方法です)。 t_crossに座っているリミットオーダーをフィルします。- LP曲線に沿って次の初期化ティックまたは
swap_input枯渇まで続行します。
動的手数料導出
PoolState.dynamic_fee_info はボラティリティ状態を保持します。各スワップステップは、ステップ単位の手数料率を以下のように計算します。
ここで:
- —
DYNAMIC_FEE_CONTROL_DENOMINATOR - —
VOLATILITY_ACCUMULATOR_SCALE vol_accは以下の更新ルール後のステップあたりアキュムレーターtick_spacingはPoolState.tick_spacingから
アキュムレーター更新
2つのルールが各スワップで順番に適用されます。 減衰。 リファレンスフロアは最後の更新以降の時間に基づいて減衰します。 蓄積。 新しいアキュムレーターはリファレンスプラス前のリファレンスインデックス以来のティック距離です。tick_spacing_index_reference()はティック単位で、生ティックではありません。。
ティック距離で放物線である理由
アキュムレーターを二乗することは、手数料が価格がリファレンスポイントから歩んできた距離の二乗に応じて上昇することを意味します。経験的にこれはランダムウォーク圧力下での価格の分散スケーリングと一致します。2×ティック遠隔は4×暗黙のボラティリティを意味するため、4×サージを請求します。dynamic_fee_control パラメーターは絶対レベルを調整します。
filter_period ウィンドウは、小さなサブセカンド振動(例えば、MEVボット サンドイッチング)がアキュムレーターを膨らませることを防ぎます。decay_period ウィンドウは、単一の過去スパイクが市場が静まった後に無期限に手数料を請求することを防ぎます。
数値堅牢性
- すべての中間生成物は
u128またはu256形状の算術を通過します。CLMMはU128SqrtヘルパーとFullMath::mulDivパターンを直接Uniswap v3から移植しています。 - 除算丸めは、不変式
k' ≥ kをローカルに強制するためにステップごとに選択されます。SwapBaseInputはアウトプットを下にラウンドします。SwapBaseOutputはインプットを上にラウンドします。 PoolState.liquidityをゼロに落とすティック交差は許可されます(価格は「流動性ホール」を走行できます)が、スワップは単に次の初期化ティックに進んで入力を消費せず、手数料を請求しません。- オーバーフローガード:
sqrt_price_x64は[MIN_TICK, MAX_TICK]に対応する[MIN_SQRT_PRICE_X64, MAX_SQRT_PRICE_X64]の包括的範囲内に保たれます。どちらかのバウンドを超えて押されるスワップはSqrtPriceLimitOverflowで差し戻されます。
次に進むべきこと
products/clmm/ticks-and-positionsティックマップがウォークにどのように参加するかについて。products/clmm/fees数学の手数料/リワード側の詳細について。algorithms/clmm-mathL = sqrt(x · y)及び範囲対流動性公式の背後にある導出について。
raydium-io/raydium-clmm—libraries/swap_math.rs,libraries/tick_math.rs- “Uniswap v3 Core” ホワイトペーパー、§6–7


