الانتقال إلى المحتوى الرئيسي
هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.عرض النسخة الإنجليزية →
Stable AMM هو برنامج مستقل؛ هيكل حساباته على جانب المجمع يشبه AMM v4 (AmmInfo والخزائن والسلطة)، وبالإضافة إلى ذلك يحتوي على حساب ModelDataInfo يخزن جدول البحث. تغطي هذه الصفحة كليهما.

الجرد

AMM خالص. يحتفظ Stable AMM بكل السيولة في خزائنه الخاصة ولا يعتمد على OpenBook. كان لديه مسار صنع السوق على OpenBook في بداية حياته، لكن هذا المسار ظل خاملاً لسنوات، وترقية 2026-06-22 أزالت الكود المتبقي. حسابات السوق serum_* و amm_open_orders أدناه هي بالتالي إرث قديم: قد تظهر لا تزال في معاملات التخطيط القديم للتوافقية العكسية، لكن البرنامج لا يتحقق منها أو يقرأها، والتعليمات ذات التخطيط الجديد تحذفها بالكامل.
الجرد النشط الآن على جانب المجمع بالكامل:
الفئةالحسابالمالكالدور
المجمعAmmInfoبرنامج Stableحالة المجمع والمراجع إلى الخزائن وحساب بيانات النموذج.
المجمعamm_authorityبرنامج StablePDA مملوك للبرنامج يوقّع حركات الخزائن. مشترك بين جميع مجمعات Stable AMM.
المجمعamm_target_ordersبرنامج Stableحساب الشبكة على جانب المجمع (محتفظ به في التخطيطات؛ لم يعد يدفع أوامر OpenBook).
المجمعpool_coin_token_accountSPL Tokenخزينة جانب العملة للمجمع.
المجمعpool_pc_token_accountSPL Tokenخزينة جانب pc للمجمع.
المجمعlp_mintSPL Tokenعملة LP قابلة للاستبدال.
النموذجmodel_data_accountبرنامج Stableجدول البحث: 50,000 × DataElement.
إرث قديمamm_open_ordersOpenBookحساب OpenOrders القديم للمجمع على OpenBook. غير مستخدم.
إرث قديمserum_marketOpenBookسوق OpenBook. غير مستخدم.
إرث قديمserum_bids, serum_asksOpenBookطوابير العروض والطلبات. غير مستخدمة.
إرث قديمserum_event_queueOpenBookقائمة الأحداث. غير مستخدمة.
إرث قديمserum_coin_vault, serum_pc_vaultSPL Tokenخزائن السوق على مستوى OpenBook. غير مستخدمة.
إرث قديمserum_vault_signerOpenBookموقّع الخزينة على مستوى السوق. غير مستخدم.

AmmInfo

حساب الحالة الجذري. التخطيط متطابق تقريباً مع AMM v4 — معاملات المجمع والعشريات والرسوم والمراجع إلى الخزائن والعملات — مع إضافة واحدة: حقل model_data_key يشير إلى جدول البحث.
// raydium-stable/program/src/state.rs (abridged)
pub struct AmmInfo {
    pub account_type: u64,              // = 0 (AmmAccount)
    pub status: u64,                    // bitmask: swap/deposit/withdraw/crank enabled
    pub nonce: u64,                     // bump for amm_authority
    pub order_num: u64,
    pub depth: u64,
    pub coin_decimals: u64,
    pub pc_decimals: u64,
    pub state: u64,                     // state machine (IdleState, etc.)
    pub reset_flag: u64,
    pub min_size: u64,
    pub vol_max_cut_ratio: u64,
    pub amount_wave: u64,
    pub coin_lot_size: u64,             // mirrors OpenBook
    pub pc_lot_size: u64,
    pub min_price_multiplier: u64,
    pub max_price_multiplier: u64,
    pub sys_decimal_value: u64,
    pub abort_trade_factor: u64,
    pub price_tick_multiplier: u64,
    pub price_tick: u64,
    
    pub fees: Fees,                     // see below
    pub out_put: OutPutData,            // PnL, swaps, punish amounts
    
    pub coin_vault: Pubkey,
    pub pc_vault: Pubkey,
    pub coin_mint: Pubkey,
    pub pc_mint: Pubkey,
    pub lp_mint: Pubkey,
    pub model_data_key: Pubkey,         // ← THE LOOKUP TABLE
    pub open_orders: Pubkey,            // legacy: OpenBook OpenOrders (unused post-decoupling)
    pub serum_market: Pubkey,           // legacy: unused post-decoupling
    pub serum_program: Pubkey,          // legacy: unused post-decoupling
    pub target_orders: Pubkey,
    pub amm_admin: Pubkey,              // admin key
    pub client_order_id: u64,
    pub lp_amount: u64,                 // LP supply
    pub lp_net: u64,                    // LP value metric
    pub padding: [u64; 61],
}

pub struct Fees {
    pub min_separate_numerator: u64,
    pub min_separate_denominator: u64,
    pub trade_fee_numerator: u64,       // 25
    pub trade_fee_denominator: u64,     // 10_000 → 0.25%
    pub pnl_numerator: u64,             // 12
    pub pnl_denominator: u64,           // 100 → 12% of fee = 0.03% of volume
    pub swap_fee_numerator: u64,        // 25
    pub swap_fee_denominator: u64,      // 10_000
}

pub struct OutPutData {
    pub need_take_pnl_coin: u64,        // accrued protocol fee (coin)
    pub need_take_pnl_pc: u64,          // accrued protocol fee (pc)
    pub total_pnl_pc: u64,
    pub total_pnl_coin: u64,
    pub pool_open_time: u64,
    pub punish_pc_amount: u64,
    pub punish_coin_amount: u64,
    pub orderbook_to_init_time: u64,
    pub swap_coin_in_amount: u128,
    pub swap_pc_out_amount: u128,
    pub swap_pc_in_amount: u128,
    pub swap_coin_out_amount: u128,
    pub swap_pc_fee: u64,
    pub swap_coin_fee: u64,
}
الحقول الرئيسية الموجهة للمدمجين:
  • model_data_key — عنوان جدول البحث. يجب تمريره إلى كل تعليمة.
  • fees — هيكل متطابق مع AMM v4. الافتراضي هو رسم تجارة 0.25%، تقسيم LP 0.22% / بروتوكول 0.03%.
  • coin_vault, pc_vault — خزائن المجمعات.
  • status — bitmask يتحكم في swap/deposit/withdraw/crank.
  • out_put.need_take_pnl_* — يتم مسحها بواسطة WithdrawPnl.

ModelDataInfo

جدول البحث. مصفوفة متفرقة كبيرة من نقاط السعر والكمية.
// raydium-stable/program/src/state.rs
pub const ELEMENT_SIZE: usize = 50000;

pub struct DataElement {
    pub x: u64,         // table X (e.g., coin amount)
    pub y: u64,         // table Y (e.g., pc amount)
    pub price: u64,     // price at (x, y)
}

pub struct ModelDataInfo {
    pub account_type: u64,              // = 2 (ModleDataAccount)
    pub status: u64,                    // Initialized or Uninitialized
    pub multiplier: u64,                // scale factor for x, y (e.g., 10^6)
    pub valid_data_count: u64,          // how many elements are populated
    pub elements: [DataElement; 50000], // the table itself
}
دورة الحياة: تم حذف التعليمات الإعدادية التي بنت هذه الجداول — InitModelData (أنشأت الحساب) و UpdateModelData (ملأت العناصر، وضبط valid_data_count) — في ترقية 2026-06-22. الجداول في المجمعات الموجودة الآن ثابتة. في وقت التشغيل، التعليمات القابلة للاستدعاء المتبقية لا تزال تستهلكها:
  • Swap / deposit / withdraw تستدعي دوال البحث التي تبحث ثنائياً وتقحم داخل elements[0..valid_data_count].

DataElement

الإدخال الذري في الجدول. يجب أن يكون مرتباً (x تصاعدي، y تنازلي، السعر تصاعدي) لكي يعمل البحث الثنائي.
pub struct DataElement {
    pub x: u64,         // X coordinate (e.g., token_a balance, scaled by multiplier)
    pub y: u64,         // Y coordinate (e.g., token_b balance, scaled by multiplier)
    pub price: u64,     // price (x/y in scaled form, scaled by multiplier)
}
عند ملء الجدول، يحدد المسؤول هذه مقاسة مسبقاً. البرنامج لا يتحقق من ترتيب الفرز على السلسلة (للسرعة)، لذا الترتيب الخاطئ يسبب اقتباسات غير صحيحة.

السلطة والخزائن

نفس AMM v4:
  • amm_authority هو PDA واحد على مستوى البرنامج مشتق بـ seed ["amm authority"]. يمتلك جميع خزائن المجمع ويوقّع حركاتها.
  • الخزائن هي حسابات SPL Token يملكها amm_authority، وليست ATAs.
Token-2022 غير مدعوم.

bitmask الحالة

متطابق مع AMM v4. يتحكم في ما إذا كانت swap/deposit/withdraw/crank مفعلة.

تتبع الرسوم و PnL

يتتبع هيكل out_put:
  • need_take_pnl_coin, need_take_pnl_pc — رسوم البروتوكول المتراكمة لكن لم يتم مسحها بعد. WithdrawPnl ينقلها للخارج.
  • swap_coin_in_amount, swap_pc_in_amount، إلخ. — عدادات التحليلات.
حساب أصول المجمع (بعد الفصل). لأنه لا توجد أموال مرهونة كأوامر مفتوحة على OpenBook بعد الآن، يتم حساب إجمالي أصول المجمع الآن بالكامل من الخزائن:
Old: total assets = vault balances + open-order funds (native_coin_total / native_pc_total) − pending PnL (need_take_pnl)
New: total assets = vault balances − pending PnL (need_take_pnl)
يجب على المفهرسات وكود الاقتباس الذي أعاد بناء قيمة المجمع من أرصدة OpenOrders أن يحذف هذا الحد.

حجم الحساب

ModelDataInfo كبير (~1.2 MB، لأن 50,000 عنصر × 24 بايت لكل عنصر). هذا هو السبب في أن إنشاء مجمع Stable يتطلب تخصيص إيجار وحساب صريح. SDK و أدوات Raydium تتعامل مع هذا بشفافية؛ المدمجون نادراً ما يحتاجون إلى تخصيص يدوي.

اشتقاق الحسابات من الصفر

مثل AMM v4، يستخدم Stable AMM مفاتيح مزروعة (وليست PDAs خالصة). هوية المجمع الكنسية مشتقة عبر:
ammId = createWithSeed(
  owner: ammAuthority,
  seed: marketPubkey.toBase58().slice(0, 32),
  programId: STABLE_PROGRAM_ID,
)
وبالمثل للخزائن وعملة LP والأوامر المستهدفة، إلخ. في الممارسة العملية، استخدم SDK أو API لجلب العناوين المحسوبة مسبقاً.

ما يجب قراءته أين

المصادر: