Skip to main content
هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.عرض النسخة الإنجليزية →

المتغيّر الثابت

يحافظ CPMM على متغيّر الناتج الثابت الكلاسيكي على خزانتيه: xy=kx \cdot y = k حيث x هو رصيد vault0 بعد أي رسوم نقل Token-2022 عند الاستقبال، وبالمثل لـ y. يجب أن تترك كل مبادلة k' ≥ k بعد احتساب رسوم التداول المُعترف بها للـ LP (بحيث لا تُحتسب دلاء البروتوكول والصندوق والمنشئ نحو k — فهي تجلس في الخزان لكن تُستثنى من عرض المنحنى، انظر الرسوم على المنحنى أدناه). لذلك k ينمو بشكل مطرد بمرور الوقت مع تراكم الرسوم لـ LPs. يتم تسعير حصص LP من خلال احتياطيات المجموعة، وليس من خلال k: سعر LP في token0=xlpSupply,سعر LP في token1=ylpSupply\text{سعر LP في token0} = \frac{x}{\text{lpSupply}}, \qquad \text{سعر LP في token1} = \frac{y}{\text{lpSupply}} حرق ΔLP من رموز LP يرجع بالضبط ΔLP × x / lpSupply من token0 و ΔLP × y / lpSupply من token1. لا المنحنى ولا k يتحرك عند الإيداع أو السحب — فقط المبادلات تغيّر السعر.

نموذج الرسوم على مسار المبادلة

يطبق CPMM رسومًا مستقلة بمعدلات منفصلة على كل مبادلة:
  • رسم التداول يُؤخذ من جانب الإدخال، مُحتسبًا عند AmmConfig.trade_fee_rate. ثم يتم تقسيمه إلى حصص LP والبروتوكول والصندوق (تبقى حصة LP في الخزان وتنمو k؛ حصص البروتوكول والصندوق تُستخرج من محاسبة الخزان).
  • رسم المنشئ (نشط فقط عندما يكون enable_creator_fee == true) يُحتسب عند AmmConfig.creator_fee_rate. يُؤخذ من جانب الإدخال أو جانب الإخراج بناءً على PoolState.creator_fee_on واتجاه المبادلة (انظر products/cpmm/fees). إنه دلو خاص به — ليس أبدًا جزءًا من رسم التداول.
دع:
  • FEE_RATE_DENOMINATOR = 1_000_000
  • trade_fee_rate — من AmmConfig، مثلاً 2500 = 0.25% من الحجم ذي الصلة
  • creator_fee_rate — من AmmConfig، مثلاً 1000 = 0.10% من الحجم ذي الصلة
  • protocol_fee_rate, fund_fee_rate — مقسومة بوحدات 1/FEE_RATE_DENOMINATOR من رسم التداول، وليس من الحجم
عندما يكون رسم المنشئ على جانب الإدخال:
عندما يكون رسم المنشئ على جانب الإخراج:
في كلا الحالتين يتم تقسيم رسم التداول بنفس الطريقة:
يُحتفظ بمبلغ protocol_fee + fund_fee + creator_fee في الخزانات لكن يُتتبع بشكل منفصل في حالة المجموعة (protocol_fees_token*, fund_fees_token*, creator_fees_token*). عندما تتحقق فحوصات متغيّر الناتج الثابت من k' ≥ k، تستخدم أرصدة الخزان ناقصًا جميع الرسوم الثلاثة المتراكمة وغير المجمّعة — لذا يجني LPs فقط lp_fee. انظر products/cpmm/fees لتعليمات الجمع والأمثلة الرقمية المفصلة.

SwapBaseInput (إدخال دقيق)

“المستخدم يعطينا بالضبط amount_in من mint الإدخال ويتلقى على الأقل minimum_amount_out من mint الإخراج.” تجاهل 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 على جانب الإدخال

إذا كان mint الإدخال يحتوي على امتداد رسم النقل، فإن mint يخصم رسمه عند النقل من المستخدم → الخزان. لذا يتلقى الخزان فعليًا amount_in − transfer_fee_in(amount_in). يحسب برنامج CPMM بالتالي:
ويشغّل المنحنى مقابل amount_in_after_trade_fee. هذا مهم لأن سعر المنحنى يُحسب من صافي المبلغ الذي وصل إلى الخزان، وليس من مبلغ المستخدم الإجمالي.

Token-2022 على جانب الإخراج

إذا كان mint الإخراج يفرض رسم نقل، فإن المجموعة ترسل amount_out من خزانها للمستخدم. mint سيقتطع رسمه على الطريق، لذا يتلقى المستخدم amount_out − transfer_fee_out(amount_out). يحسب البرنامج amount_out من المنحنى كالمعتاد، لكن من مسؤولية المُدمج تحويل رقم “إرسال الخزان” الخاص بالمجموعة إلى رقم “استقبال المستخدم” عند عرض العروض الأسعار.

فحص الانزلاق

بعد حساب amount_out:
إذا كان mint الإخراج يفرض رسم نقل، فإن SDK يطبق رسم النقل قبل تعيين minimum_amount_out بحيث يكون ثابت الانزلاق مقسومًا بما سيستقبله المستخدم فعليًا، وليس بما يرسله الخزان.

SwapBaseOutput (إخراج دقيق)

“المستخدم سيتلقى بالضبط amount_out من mint الإخراج وعلى استعداد للدفع بما يصل إلى maximum_amount_in من mint الإدخال.” قلب المنحنى للحصول على Δ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 من جهة الإدخال، اغلفها بـ:
بحيث يدفع المستخدم ما يكفي بحيث بعد خصم رسم النقل الخاص بـ mint يستقبل الخزان gross_needed.

فحص الانزلاق

مثال عملي

حالة المجموعة، تجاهل Token-2022:
  • x = 1_000_000_000_000 (1,000,000.000000 من token0، 6 كسور عشرية)
  • y = 2_000_000_000_000 (2,000,000.000000 من token1، 6 كسور عشرية)
  • AmmConfig: trade_fee_rate = 2500, protocol_fee_rate = 120_000, fund_fee_rate = 40_000, creator_fee_rate = 0
المستخدم: SwapBaseInput مع amount_in = 1_000_000_000 (1,000.000000 من token0). رسم المنشئ معطّل (enable_creator_fee = false).
إذا كانت نفس المجموعة لديها enable_creator_fee = true مع creator_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. حساب البروتوكول والصندوق والـ LP على trade_fee لم يتغير عن المثال أعلاه — رسم المنشئ هو دلو خاص به، متراكم إلى creator_fees_token0 واستُثني من curve_x جنبًا إلى جنب مع دلاء البروتوكول والصندوق. إذا كان mint الإدخال يحتوي على رسم نقل 1% من Token-2022، فإن الخزان يستقبل 990_000_000 رموز بدلاً من 1_000_000_000، وكل عملية حساب لاحقة تستخدم هذا المبلغ الصافي.

قاعدة تحديث الملاحظة

على كل مبادلة، يقيّم البرنامج ما إذا كان يجب دفع ملاحظة جديدة في مخزن مؤقت الحلقة:
خاصيتان:
  • السعر التراكمي، وليس السعر الفوري. ملاحظة واحدة ليست سعرًا. للحصول على TWAP من الوقت t0 إلى t1، اقرأ الملاحظات الأقرب إلى كل نهاية واحسب (cumulative(t1) − cumulative(t0)) / (t1 − t0).
  • العينات محدودة المعدل. قد تشارك المبادلات المتتالية في نفس الفتحة ملاحظة واحدة. قراءة ملاحظة فورًا بعد مبادلة يمكن بالتالي أن تبدو قديمة بفتحة واحدة — هذا أمر طبيعي.
المزيد في products/clmm/accounts.

الرسوم على المنحنى

هذا هو الجزء الدقيق ويستحق الإشارة إليه. يعمل حساب المنحنى مقابل أرصدة الخزان الصافية — أي رصيد SPL الخام ناقصًا رسوم البروتوكول والصندوق والمنشئ المتراكمة (جميعها ثلاثة دلاء مستقلة — انظر products/cpmm/fees). صورة ملموسة:
العواقب للمُدمجين:
  • لا تقتبس من الأرصدة الخام. اطرح حقول الرسوم المتراكمة أولاً، أو استدعِ SwapBaseInput كمحاكاة وخذ عودتها.
  • CollectProtocolFee ينقل الرموز خارج الخزان. بعد الجمع، ينخفض raw_vault_balance لكن curve_balance لم يتغير؛ سعر المجموعة لا يتحرك. هذا متعمد.

الدقة والفيض

  • جميع عمليات حساب المنحنى تستخدم وسطاء u128 لمنع الفيض عند x * y.
  • القسمة تقريب نحو الصفر باستثناء SwapBaseOutput الخاص بـ Δx_net، الذي يقرب لأعلى، وحساب الرسم، الذي يقرب لأعلى على trade_fee ولأسفل على الانقسامات الفرعية. يتم اختيار اتجاهات التقريب هذه بحيث لا ينخفض المتغيّر أبدًا بسبب الاقتطاع الصحيح.
  • قد تضرب المجموعات ذات نسب الخزان المتطرفة (مليارات : 1) أرضيات دقة على التداولات الصغيرة؛ يعود البرنامج ZeroTradingTokens في تلك الحالة. انظر reference/error-codes.

ماذا بعد

المصادر: