Zum Hauptinhalt springen
Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Stable AMM ist ein eigenständiges Programm; seine Pool-seitige Kontenstruktur ähnelt AMM v4 (AmmInfo, Vaults, Authority), und es verfügt zusätzlich über ein ModelDataInfo-Konto, das die Nachschlagetabelle speichert. Diese Seite behandelt beide.

Inventar

Reines AMM. Stable AMM hält alle Liquidität in seinen eigenen Vaults und ist nicht von OpenBook abhängig. Es hatte früh in seiner Existenz einen OpenBook-Market-Making-Pfad, aber dieser Pfad ist seit Jahren inaktiv, und das Upgrade vom 2026-06-22 hat den verbleibenden Code entfernt. Die serum_*-Market-Konten und amm_open_orders unten sind daher veraltet: Sie können in alten Layout-Transaktionen aus Gründen der Rückwärtskompatibilität noch erscheinen, aber das Programm validiert oder liest sie nicht, und neue Layout-Anweisungen lassen sie ganz weg.
Das aktive Inventar ist nun vollständig Pool-seitig:
KategorieKontoBesitzerRolle
PoolAmmInfoStable-ProgrammPool-Status, Verweise auf Vaults und das Model-Data-Konto.
Poolamm_authorityStable-ProgrammProgramm-eigene PDA, die Vault-Bewegungen signiert. Wird über alle Stable AMM-Pools hinweg geteilt.
Poolamm_target_ordersStable-ProgrammPool-seitiges Grid-Konto (in Layouts beibehalten; treibt nicht mehr OpenBook-Bestellungen an).
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.
Veraltetamm_open_ordersOpenBookDas alte OpenBook-OpenOrders-Konto des Pools. Ungenutzt.
Veraltetserum_marketOpenBookOpenBook-Market. Ungenutzt.
Veraltetserum_bids, serum_asksOpenBookGeld-/Briefwarteschlangen. Ungenutzt.
Veraltetserum_event_queueOpenBookEvent-Warteschlange. Ungenutzt.
Veraltetserum_coin_vault, serum_pc_vaultSPL TokenOpenBook-Market-Level-Vaults. Ungenutzt.
Veraltetserum_vault_signerOpenBookMarket-Level-Vault-Signer. Ungenutzt.

AmmInfo

Root-State-Konto. Das Layout ist fast identisch mit AMM v4 — Pool-Parameter, Dezimalstellen, Gebühren, Vault-/Mint-Verweise — mit einer Ergänzung: ein model_data_key-Feld, das auf die Nachschlagetabelle verweist.
// 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,
}
Wichtige Felder für Integratoren:
  • model_data_key — die Adresse der Nachschlagetabelle. Muss an jede Anweisung übergeben werden.
  • fees — identische Struktur wie AMM v4. Standard ist 0,25% Handelsgebühr, 0,22% LP / 0,03% Protokoll-Aufteilung.
  • coin_vault, pc_vault — die Pool-Vaults.
  • status — Bitmask, das Swap/Deposit/Withdraw/Crank steuert.
  • out_put.need_take_pnl_* — wird von WithdrawPnl geleert.

ModelDataInfo

Die Nachschlagetabelle. Ein großes spärliches Array von Preis-/Mengenpunkten.
// 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
}
Lebenszyklus: Die Setup-Anweisungen, die diese Tabellen erstellten — InitModelData (erstellte das Konto) und UpdateModelData (füllte Elemente auf und setzte valid_data_count) — wurden im Upgrade vom 2026-06-22 entfernt. Die Tabellen in bestehenden Pools sind nun fest. Zur Laufzeit verbrauchen die verbleibenden aufrufbaren Anweisungen sie immer noch:
  • Swap / Deposit / Withdraw rufen Nachschlagefunktionen auf, die binär suchen und innerhalb von elements[0..valid_data_count] 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 vorskaliert an. Das Programm validiert die Sortierreihenfolge nicht on-chain (aus Geschwindigkeitsgründen), daher führt Fehlsortierung zu falschen Angeboten.

Authority und Vaults

Identisch mit AMM v4:
  • amm_authority ist eine einzelne programmweite PDA, die mit dem Seed ["amm authority"] abgeleitet wird. Sie besitzt alle Pool-Vaults und signiert ihre Bewegungen.
  • Vaults sind SPL Token-Konten, deren Besitzer amm_authority ist, nicht 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-Verfolgung

Die out_put-Struktur verfolgt:
  • need_take_pnl_coin, need_take_pnl_pc — Protokollgebühren, die aufgelaufen sind, aber noch nicht geleert wurden. WithdrawPnl bewegt diese heraus.
  • swap_coin_in_amount, swap_pc_in_amount, usw. — Analyse-Zähler.
Pool-Asset-Berechnung (nach Entkopplung). Da keine Mittel mehr als OpenBook-Open-Orders hinterlegt sind, werden die Gesamtvermögenswerte des Pools nun vollständig aus den Vaults berechnet:
Alt: Gesamtvermögen = Vault-Guthaben + Open-Order-Mittel (native_coin_total / native_pc_total) − ausstehende PnL (need_take_pnl)
Neu: Gesamtvermögen = Vault-Guthaben − ausstehende PnL (need_take_pnl)
Indexer und Quoting-Code, die den Pool-Wert aus OpenOrders-Guthaben rekonstruierten, müssen diesen Term streichen.

Kontogröße

Das ModelDataInfo ist groß (~1,2 MB, da 50.000 Elemente × 24 Bytes pro Element). Deshalb erfordert das Erstellen eines Stable-Pools explizite Miete und Konten-Vorabzuweisung. Das Raydium SDK und die 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 usw. In der Praxis verwenden Sie das SDK oder die API, um vorgefertigte Adressen abzurufen.

Was wo zu lesen ist

Quellen: