Saltar al contenido principal
Esta página fue traducida automáticamente por IA. La versión en inglés es la fuente autorizada.Ver versión en inglés →
Stable AMM es su propio programa; su estructura de cuentas del lado del pool se parece a AMM v4 (AmmInfo, bóvedas, autoridad), y además tiene una cuenta ModelDataInfo que almacena la tabla de búsqueda. Esta página cubre ambas.

Inventario

AMM puro. Stable AMM mantiene toda la liquidez en sus propias bóvedas y no depende de OpenBook. Llevaba una ruta de creación de mercado de OpenBook al principio de su vida, pero esa ruta ha estado inactiva durante años, y la actualización del 2026-06-22 eliminó el código residual. Las cuentas de mercado serum_* y amm_open_orders a continuación son por lo tanto heredadas: pueden seguir apareciendo en transacciones de diseño antiguo para compatibilidad hacia atrás, pero el programa no las valida ni las lee, e las instrucciones de nuevo diseño las omiten completamente.
El inventario activo ahora es completamente del lado del pool:
CategoríaCuentaPropietarioRol
PoolAmmInfoPrograma StableEstado del pool, referencias a bóvedas y la cuenta de datos del modelo.
Poolamm_authorityPrograma StablePDA propiedad del programa que firma los movimientos de bóvedas. Compartido entre todos los pools de Stable AMM.
Poolamm_target_ordersPrograma StableCuenta de cuadrícula del lado del pool (retenida en diseños; ya no impulsa órdenes de OpenBook).
Poolpool_coin_token_accountSPL TokenBóveda del lado de la moneda del pool.
Poolpool_pc_token_accountSPL TokenBóveda del lado de pc del pool.
Poollp_mintSPL TokenAcuñación de LP fungible.
Modelomodel_data_accountPrograma StableLa tabla de búsqueda: 50.000 × DataElement.
Heredadaamm_open_ordersOpenBookLa antigua cuenta OpenOrders de OpenBook del pool. Sin usar.
Heredadaserum_marketOpenBookMercado de OpenBook. Sin usar.
Heredadaserum_bids, serum_asksOpenBookColas de oferta/demanda. Sin usar.
Heredadaserum_event_queueOpenBookCola de eventos. Sin usar.
Heredadaserum_coin_vault, serum_pc_vaultSPL TokenBóvedas a nivel de mercado de OpenBook. Sin usar.
Heredadaserum_vault_signerOpenBookFirmante de bóveda a nivel de mercado. Sin usar.

AmmInfo

Cuenta de estado raíz. El diseño es casi idéntico a AMM v4 — parámetros del pool, decimales, comisiones, referencias de bóvedas/acuñaciones — con una adición: un campo model_data_key que apunta a la tabla de búsqueda.
// 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,
}
Campos clave orientados al integrador:
  • model_data_key — la dirección de la tabla de búsqueda. Debe pasarse a cada instrucción.
  • fees — estructura idéntica a AMM v4. Por defecto, comisión de intercambio del 0,25%, división LP / protocolo del 0,22% / 0,03%.
  • coin_vault, pc_vault — las bóvedas del pool.
  • status — máscara de bits que controla swap/depósito/retiro/crank.
  • out_put.need_take_pnl_* — barridas por WithdrawPnl.

ModelDataInfo

La tabla de búsqueda. Una matriz dispersa grande de puntos de precio/cantidad.
// 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
}
Ciclo de vida: Las instrucciones de configuración que construyeron estas tablas — InitModelData (creó la cuenta) y UpdateModelData (poblaron elementos, estableciendo valid_data_count) — fueron eliminadas en la actualización del 2026-06-22. Las tablas en pools existentes ahora son fijas. En tiempo de ejecución, las instrucciones invocables restantes aún las consumen:
  • Swap / depósito / retiro llaman a funciones de búsqueda que buscan binariamente e interpolan dentro de elements[0..valid_data_count].

DataElement

La entrada atómica en la tabla. Debe estar ordenada (x ascendente, y descendente, precio ascendente) para que la búsqueda binaria funcione.
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)
}
Al poblar la tabla, el administrador especifica estos pre-escalados. El programa no valida el orden de clasificación en cadena (por velocidad), por lo que un ordenamiento incorrecto causa cotizaciones incorrectas.

Autoridad y bóvedas

Igual que AMM v4:
  • amm_authority es un PDA de programa único derivado con semilla ["amm authority"]. Posee todas las bóvedas del pool y firma sus movimientos.
  • Bóvedas son cuentas de SPL Token cuyo propietario es amm_authority, no ATAs.
Token-2022 no es compatible.

Máscara de bits de estado

Idéntica a AMM v4. Controla si swap/depósito/retiro/crank están habilitados.

Seguimiento de comisiones y PnL

La estructura out_put rastrea:
  • need_take_pnl_coin, need_take_pnl_pc — comisiones de protocolo acumuladas pero aún no barridas. WithdrawPnl las saca.
  • swap_coin_in_amount, swap_pc_in_amount, etc. — contadores de análisis.
Cálculo de activos del pool (post-desacoplamiento). Debido a que ya no hay fondos en depósito como órdenes abiertas de OpenBook, los activos totales del pool ahora se calculan completamente a partir de las bóvedas:
Antiguo: activos totales = saldos de bóveda + fondos de orden abierta (native_coin_total / native_pc_total) − PnL pendiente (need_take_pnl)
Nuevo: activos totales = saldos de bóveda − PnL pendiente (need_take_pnl)
Los indexadores y el código de cotización que reconstruyeron el valor del pool a partir de saldos de OpenOrders deben descartar ese término.

Tamaño de cuenta

El ModelDataInfo es grande (~1,2 MB, ya que 50.000 elementos × 24 bytes por elemento). Por eso crear un pool de Stable requiere asignación explícita de renta y pre-asignación de cuenta. El SDK de Raydium y las herramientas manejan esto de manera transparente; los integradores rara vez necesitan asignar manualmente.

Derivación de cuentas desde cero

Como AMM v4, Stable AMM usa claves con semilla (no PDAs puras). La identidad canónica del pool se deriva mediante:
ammId = createWithSeed(
  owner: ammAuthority,
  seed: marketPubkey.toBase58().slice(0, 32),
  programId: STABLE_PROGRAM_ID,
)
De manera similar para bóvedas, acuñación de LP, órdenes objetivo, etc. En la práctica, usa el SDK o API para obtener direcciones pre-calculadas.

Qué leer dónde

Fuentes: