Zum Hauptinhalt springen

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.

Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Stable AMM teilt die Pool-seitige Kontenstruktur von AMM v4 (AmmInfo, Vaults, Authority) und benötigt zusätzlich ein ModelDataInfo-Konto, das die Nachschlagetabelle speichert. Diese Seite behandelt beide.

Bestandsaufnahme

Ein Stable AMM Pool ist an genau einen OpenBook-Markt gebunden. Das vollständige Inventar ähnelt AMM v4 stark:
KategorieKontoOwnerRolle
PoolAmmInfoStable-ProgrammPool-Status, Verweise auf Vaults, OpenBook und Model-Data-Konto.
Poolamm_authorityStable-ProgrammVom Programm verwalteter PDA, der Vault-Bewegungen signiert. Gemeinsam für alle Stable AMM Pools.
Poolamm_open_ordersOpenBookDas OpenBook-Konto OpenOrders des Pools.
Poolamm_target_ordersStable-ProgrammPool-seitiges Gitter für Limit-Orders.
Poolpool_coin_token_accountSPL TokenCoin-seitiger Vault des Pools.
Poolpool_pc_token_accountSPL TokenPC-seitiger Vault des Pools.
Poollp_mintSPL TokenFungible LP Mint.
Modellmodel_data_accountStable-ProgrammDie Nachschlagetabelle: 50.000 × DataElement.
Marktserum_marketOpenBookOpenBook-Markt.
Marktserum_bids, serum_asksOpenBookGeld-/Briefschlangen.
Marktserum_event_queueOpenBookEvent-Queue.
Marktserum_coin_vault, serum_pc_vaultSPL TokenVaults auf Marktebene von OpenBook.
Marktserum_vault_signerOpenBookVault-Signer auf Marktebene.

AmmInfo

Root-Status-Konto. Das Layout ist fast identisch mit AMM v4 – Pool-Parameter, Dezimalen, Gebühren, Vault-/Mint-Verweise – mit einer Ergänzung: ein model_data_key-Feld, das auf die Nachschlagetabelle zeigt.
// 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,            // OpenBook OpenOrders
    pub serum_market: Pubkey,
    pub serum_program: Pubkey,
    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,
}
Wichtige Felder für Integratoren:
  • model_data_key — die Adresse der Nachschlagetabelle. Muss bei jeder Anweisung übergeben werden.
  • fees — identische Struktur mit AMM v4. Standardmäßig 0,25% Handelsgebühr, 0,22% LP / 0,03% Protokoll-Aufteilung.
  • coin_vault, pc_vault — die Vaults des Pools.
  • status — Bitmask, das Swap/Deposit/Withdraw/Crank steuert.
  • out_put.need_take_pnl_* — wird durch WithdrawPnl geleert.

ModelDataInfo

Die Nachschlagetabelle. Ein großes, spärlich verteiltes Array von Preis-/Mengen-Punkten.
// 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
}
Lebenszyklusablauf:
  1. InitModelData erstellt das Konto und setzt status = Initialized, multiplier = <admin-provided>, valid_data_count = 0.
  2. UpdateModelData (wird bis zu 5-mal pro Transaktion aufgerufen) füllt Elemente durch:
    • Eingabe: Array von (index: u64, DataElement)-Paaren.
    • Schreibt jeden in elements[index].
    • Erhöht valid_data_count, falls index >= valid_data_count.
  3. Swap/Deposit/Withdraw rufen Nachschlage-Funktionen auf, die innerhalb von elements[0..valid_data_count] binär suchen und interpolieren.

DataElement

Der atomare Eintrag in der Tabelle. Muss sortiert sein (x aufsteigend, y absteigend, Preis aufsteigend), damit die binäre Suche funktioniert.
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)
}
Bei der Befüllung der Tabelle gibt der Admin diese bereits skaliert an. Das Programm validiert die Sortierreihenfolge auf der Blockchain nicht (aus Leistungsgründen), daher führt fehlerhaftes Sortieren zu falschen Kursangaben.

Authority und Vaults

Gleich wie AMM v4:
  • amm_authority ist ein einzelner programm-weiter PDA, der mit dem Seed ["amm authority"] abgeleitet wird. Er besitzt alle Pool-Vaults und signiert deren Bewegungen.
  • Vaults sind SPL Token-Konten, deren Owner amm_authority ist, keine ATAs.
Token-2022 wird nicht unterstützt.

Status-Bitmask

Identisch mit AMM v4. Steuert, ob Swap/Deposit/Withdraw/Crank aktiviert sind.

Gebühren- und PnL-Tracking

Gleich wie AMM v4. Die out_put-Struktur verfolgt:
  • need_take_pnl_coin, need_take_pnl_pc — Protokollgebühren, die aufgelaufen sind, aber noch nicht geleert wurden. WithdrawPnl räumt diese.
  • swap_coin_in_amount, swap_pc_in_amount, etc. — Analyse-Zähler.

Kontogröße

Das ModelDataInfo ist groß (~1,2 MB, da 50.000 Elemente × 24 Bytes pro Element). Daher erfordert das Erstellen eines Stable Pools explizite Miete und Kontovorzuteilung. Das Raydium SDK und Tools handhaben dies transparent; Integratoren müssen selten manuell zuweisen.

Konten von Grund auf ableiten

Wie AMM v4 verwendet Stable AMM gesäte Schlüssel (keine reinen PDAs). Die kanonische Pool-Identität wird wie folgt abgeleitet:
ammId = createWithSeed(
  owner: ammAuthority,
  seed: marketPubkey.toBase58().slice(0, 32),
  programId: STABLE_PROGRAM_ID,
)
Ähnlich für Vaults, LP Mint, Target Orders, etc. In der Praxis verwenden Sie das SDK oder die API, um vorgefertigte Adressen abzurufen.

Was wo gelesen werden sollte

Quellen: