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

منحنى جدول البحث

يستبدل Stable AMM الصيغة x·y=k بـ جدول بحث متفرق يحتوي على صفوف (x, y, price). عند تسعير مبادلة، يقوم البرنامج بـ:
  1. حساب النسبة الحالية للمجموعة من الاحتياطيات.
  2. البحث الثنائي في الجدول للعثور على الإدخالين اللذين يحيطان بتلك النسبة.
  3. الاستيفاء الخطي بينهما للحصول على سعر وسيط.
  4. تطبيق الرسوم وإرجاع السعر.
يتبادل هذا النهج حتمية الصيغة مقابل مرونة المسؤول في تشكيل الأسعار، وهو فعال بما يكفي ليناسب ميزانية الحوسبة في Solana.

تخطيط الجدول والبحث الثنائي

يحتفظ ModelDataInfo بما يصل إلى 50,000 إدخال DataElement، مفهرسة من قبل المسؤول. فقط أول valid_data_count نشطة. كل إدخال:
DataElement {
  x: u64,      // إحداثي X (مبلغ جانب العملة، مقياس)
  y: u64,      // إحداثي Y (مبلغ جانب PC، مقياس)
  price: u64,  // السعر = x/y، مقياس بواسطة المضروب
}
للعثور على سعر عند احتياطيات المجموعة الحالية (x_real, y_real):
  1. احسب النسبة: target_ratio = (x_real * multiplier) / y_real.
  2. ابحث ثنائياً عن إدخالات حيث (element.x * multiplier) / element.y يحيط بـ target_ratio.
  3. عند العثور على قوس [min_idx, max_idx]، قم بالاستيفاء.
يمتد كود البحث الثنائي للبرنامج على حوالي 150 سطر في state.rs::ModelDataInfo::get_mininum_range_by_xy_real. الثابت الرئيسي: يجب أن تكون الإدخالات مرتبة (x تصاعدي، y تنازلي، السعر تصاعدي) لكي يعمل البحث.

الاستيفاء الخطي

بمجرد أن تحيط نقطتا جدول بالنسبة، يحسب الاستيفاء سعراً وسيطاً وزوج احتياطيات:
target = (x_real * multiplier) / y_real

[x1, y1, p1] = table[min_idx]
[x2, y2, p2] = table[max_idx]

// استيفاء السعر
p = p1 + (p2 - p1) * (target - ratio1) / (ratio2 - ratio1)

// استيفاء الاحتياطي
x = x1 + (x2 - x1) * (target - ratio1) / (ratio2 - ratio1)
y = y1 + (y2 - y1) * (target - ratio1) / (ratio2 - ratio1)
النتيجة منحنى خطي متعدد الأجزاء يربط نقاط الجدول بسلاسة.

المقياس: المضروب

يتم تخزين احتياطيات المجموعة والأسعار بمقاييس مختلفة. حقل multiplier على ModelDataInfo يأخذ هذا في الاعتبار. نمط شائع:
  • العملة لها 6 منازل عشرية، PC لها 18 منزلة عشرية.
  • المضروب = 10^6 (أو ما شابه).
  • يتم تخزين إدخالات الجدول بمقياس مخفض ليناسب حدود u64.
يعيد البرنامج المقياس عند القراءة/الكتابة عبر:
real_value = table_value * ratio / multiplier
table_value = real_value * multiplier / ratio

تسعير المبادلة: SwapBaseIn و SwapBaseOut

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

بالنظر إلى مبلغ الإدخال amount_in:
  1. احصل على النسبة الحالية من (coin_vault, pc_vault).
  2. ابحث عن إدخالات الجدول المحيطة واستيفاء للحصول على نسبة مساحة الجدول.
  3. تحويل الإدخال إلى مساحة الجدول: dx_table = amount_in * multiplier / ratio.
  4. استعلم الجدول عند إحداثي X الجديد للعثور على Y الجديد.
  5. dy_table = y_old - y_new.
  6. تحويل للخلف: dy_real = dy_table * ratio / multiplier.
  7. تطبيق رسم التجارة: dy_output = dy_real - (dy_real * trade_fee_numerator / trade_fee_denominator).
  8. إرجاع dy_output.

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

متماثل: بالنظر إلى amount_out المطلوب، حل للحصول على amount_in المطلوب. كلا المسارين يقرآن الاحتياطيات الفعلية مباشرة من خزائن المجموعة. لم تحتفظ المجموعة بأوامر OpenBook المفتوحة لسنوات، لذا لا يوجد شيء لتسويته أولاً — أرصدة الخزينة هي القصة كاملة. (ترقية 2026-06-22 أزالت كود السوق المتبقي.)

تطبيق الرسوم

مطابق لـ AMM v4: انظر products/amm-v4/math للاشتقاق الكامل.
gross_fee = amount_in * (swap_fee_numerator / swap_fee_denominator)    // مثلاً، 0.25%
lp_portion = gross_fee - (gross_fee * pnl_numerator / pnl_denominator) // مثلاً، 0.22%
pnl_portion = gross_fee * (pnl_numerator / pnl_denominator)            // مثلاً، 0.03%
يذهب pnl_portion إلى need_take_pnl_* ويتم مسحه بواسطة المسؤول عبر WithdrawPnl. يبقى lp_portion في الخزينة، مما يزيد من k ويفيد حاملي رموز LP.

محاسبة أصول المجموعة

أضافت الصيغة تاريخياً الأموال التي احتفظت بها المجموعة كأوامر مفتوحة في حسابها OpenOrders في OpenBook. كان هذا الحد صفراً عملياً منذ توقفت المجموعة عن نشر الأوامر، وأزالته ترقية 2026-06-22 من الصيغة بالكامل، تاركة حساب الخزينة فقط:
القديم: إجمالي الأصول = أرصدة الخزينة + أموال الأوامر المفتوحة (native_coin_total / native_pc_total) − PnL المعلقة (need_take_pnl)
الجديد: إجمالي الأصول = أرصدة الخزينة − PnL المعلقة (need_take_pnl)
هذه هي القيمة التي تعاملها رياضيات المنحنى كاحتياطيات فعلية (جزء need_take_pnl المتراكم لكن غير المكتسح يجلس فعلياً في الخزينة لكن يتم استبعاده من التسعير). يجب على كود الاقتباس والفهارس التي قرأت سابقاً أرصدة OpenOrders أن تسقط هذا الحد.

MonitorStep (تم حذفه)

كان MonitorStep هو تعليمات الكرنك التي سوت عمليات OpenBook المعلقة، أعادت حساب AmmInfo.target_orders، وأعادت نشر شبكة الأوامر المحدودة المشتقة من جدول البحث. توقفت المجموعة عن نشر الأوامر إلى OpenBook منذ سنوات، لذا لم يكن لدى الكرنك شيء يفعله؛ تم حذفه في ترقية 2026-06-22. لا يحتاج المدمجون إلى كرنك مجموعات Stable.

الملخص: لماذا يعمل هذا

تصميم جدول البحث + الاستيفاء فعال ومرن:
  • الكفاءة: البحث الثنائي هو O(log 50,000) ≈ 16 تكرار، كل واحد ~ 300–500 CU. الاستيفاء هو بضع عمليات ضرب/قسمة. إجمالي تكلفة الاقتباس حوالي 5k–15k CU، أرخص بكثير من إعادة حساب صيغة على كل مبادلة.
  • المرونة: يمكن للمسؤول ترميز أي منحنى خطي متعدد الأجزاء. أزواج العملات المستقرة تحصل على كثافة عالية حول 1:1؛ الأزواج المضمونة تحصل على منحنيات مخصصة.
  • السيولة المكتفية ذاتياً: تعيش جميع الأموال في خزائن المجموعة والتسعير يقرأها مباشرة — لا كرنك، لا كتاب أوامر خارجي، حسابات أقل لكل معاملة.
للغوص العميق في منطق الاستيفاء، انظر raydium-stable/program/src/state.rs، الطرق get_data_by_x، get_data_by_y، get_dy_by_dx_base_in، إلخ.

أين تذهب بعد ذلك

  • الحسابات — مرجع حقول ModelDataInfo و DataElement.
  • التعليمات — المجموعة القابلة للاستدعاء (swap, deposit, withdraw, WithdrawPnl) والتعليمات المحذوفة.
  • الرسوم — تطبيق الرسوم و WithdrawPnl.
  • products/amm-v4/math — لمنطق تسعير الأوامر الشامل للرسوم في OpenBook.
المصادر:
  • raydium-stable/program/src/state.rs (تطبيقات الاستيفاء والبحث الثنائي)
  • raydium-stable/program/src/math.rs (أدوات الحاسبة)