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.
هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.عرض النسخة الإنجليزية →
تمثيل الجذر التربيعي للسعر
يخزّن CLMM السعر بصيغةsqrt_price_x64 — الجذر التربيعي لسعر token1 لكل token0، كرقم ثابت القيمة Q64.64:
حيث p = token1_amount / token0_amount. العمل بالجذر التربيعي بدلاً من p يخطّي رياضيات المبادلة (تصبح الفروقات في مبالغ الرموز خطية بالنسبة إلى Δ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 بهذا. الصيغة للحالة داخل النطاق:
أيهما يقيد الجانب يحدد النسبة المستهلكة فعلاً؛ قد يكون للجانب الآخر بقايا.
خطوة المبادلة أحادية التك
تتقدم المبادلة في خطوات. تستهلك كل خطوة إما (أ) كل المدخلات المتاحة داخل نطاق التك الحالي دون عبور تك، أو (ب) تحرك السعر بالضبط إلى التك المهيأ التالي. بمعرفة الحالة الحالية(sqrt_c, L) ومبادلة صعوداً (token0 داخل، token1 خارج، sqrt_price يزداد)، المسافة إلى التك المهيأ التالي هي sqrt_t. داخل هذا الفترة الجزئية، العلاقة بين المدخل والسعر هي:
و
يقوم البرنامج بأحد أمرين:
-
هل يناسب المدخل بأكمله؟ إذا كان المدخل المتبقي (بعد الرسم) أقل من
Δamount0للوصول إلىsqrt_t، حل من أجل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.
المكافآت
تستخدم كل من تدفقات المكافآت الثلاثة للمجموعة نفس آلية نمو-داخل، في مجموعها الخاصreward_growth_global_x64. وقت الانبعاث:
— الانبعاثات تتناسب عكسياً مع السيولة النشطة، لذا مجموعة أكثر كثافة تدفع لكل موضع أقل نسبياً في الثانية، لكن على مواضع أكثر إجمالاً. المكافأة المستحقة لكل موضع هي
ويتم المطالبة بها عبر CollectReward. انظر /ar/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,000 token0.
الخطوة 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، بسعر التك بالضبط. المطابقة FIFO داخل التك بـorder_phase cohort.
الحالة لكل cohort على TickState
orders_amount وترث order_phase التالي؛ لا يمكنها الملء حتى يتم استهلاك الـ cohort السابق بالكامل.
خطوة المطابقة
شبه-كود للمطابقة التي تحدث عند كل عبور تك أثناء المبادلة:SettleLimitOrder (أو DecreaseLimitOrder). تتتبع المجموعة ببساطة كم من الـ cohort مملوء الآن عبر 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
تحديث المراكم
يتم تطبيق قاعدتين لكل مبادلة، بالترتيب: التحلل. الطابق المرجعي يتحلل بناءً على الوقت منذ آخر تحديث: التراكم. المراكم الجديد هو المرجع زائد مسافة التك المقطوعة منذ مؤشر المرجع السابق:tick_spacing_index_reference () بوحدات التك-المسافة، ليس التكات الخام: .
لماذا مكافئ في مسافة التك
تربيع المراكم يعني أن الرسم يرتفع كـ مربع كم بعيداً السعر قد يسير بعيداً عن نقطة المرجع. من الناحية العملية هذا يطابق تحجيم التباين للسعر تحت ضغط المشي العشوائي: حركة تك 2× تعني 4× التقلب الضمني، لذا تفرض 4× الرسم الإضافي. معاملdynamic_fee_control يعايّر المستوى المطلق.
نافذة filter_period تمنع التذبذبات الجزئية الصغيرة (على سبيل المثال، MEV bots) من الإضرار بالمراكم. نافذة decay_period تمنع قمة نشطة واحدة من فرض رسوم إلى الأبد بعد هدوء السوق.
متانة عددية
- جميع المنتجات الوسيطة تمر عبر حسابي
u128أوu256-على شكل. يستخدم CLMM مساعديU128SqrtونمطFullMath::mulDivمباشرة من Uniswap v3. - تقريب القسمة يُختار لكل خطوة لفرض الثابت
k' ≥ kمحلياً.SwapBaseInputيقرّب المخرج نزولاً؛SwapBaseOutputيقرّب المدخل صعوداً. - عبور التكات التي تسقط
PoolState.liquidityإلى صفر مسموح به (السعر يمكنه أن يسير عبر “حفرة سيولة”) لكن المبادلة ببساطة تتقدم إلى التك المهيأ التالي دون استهلاك المدخل، بلا رسم. - حماية الفيض:
sqrt_price_x64يُحفظ في النطاق الشامل[MIN_SQRT_PRICE_X64, MAX_SQRT_PRICE_X64]المقابل لـ[MIN_TICK, MAX_TICK]. مبادلة ستدفع ماضية أي حد ترجع معSqrtPriceLimitOverflow.
إلى أين بعد
/ar/products/clmm/ticks-and-positionsلكيفية المشاركة خريطة التك في المشي./ar/products/clmm/feesلجانب الرسم/المكافآت من الرياضيات بالتفصيل./ar/algorithms/clmm-mathللاشتقاقات خلفL = sqrt(x · y)وصيغ النطاق-مقابل-السيولة.
raydium-io/raydium-clmm—libraries/swap_math.rs,libraries/tick_math.rs- ورقة عمل “Uniswap v3 Core”، §6–7


