Saltar al contenido principal

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.

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 →

El invariante

El pool mantiene coin_reserve × pc_reserve = k, donde:
coin_reserve = coin_vault_balance
             + orders_posted_on_openbook.base
             + pending_coin_fill_not_yet_settled
pc_reserve   = pc_vault_balance
             + orders_posted_on_openbook.quote
             + pending_pc_fill_not_yet_settled
             - accrued_pnl_pc
Hay dos cosas importantes que notar:
  1. Las reservas incluyen cantidades comprometidas en OpenBook. Las órdenes limitadas del AMM siguen siendo parte de su liquidez — no se “pierden” en el libro de órdenes, solo se custodian allí. Calcular k únicamente con los saldos de bóveda en cadena subestima las reservas.
  2. El acúmulo de PnL (need_take_pnl_*) se resta para que la curva se conserve cuando el administrador retira las comisiones. El mismo principio que la exclusión de protocol_fees_* de CPMM.
Cada operación Swap* garantiza que k' ≥ k después de volver a añadir la cuota de comisión del proveedor de liquidez a las reservas.

Convención de comisiones

AMM v4 utiliza comisiones de razón (pares numerador/denominador) en lugar de la convención 1/1_000_000 de CPMM / CLMM. La estructura Fees en cadena (ver Fees::initialize en el código fuente del programa) tiene estos valores predeterminados:
Fees {
  min_separate_numerator:    5,
  min_separate_denominator:  10_000,   //  5/10_000 = 0.05%

  trade_fee_numerator:      25,
  trade_fee_denominator:    10_000,    // 25/10_000 = 0.25% — usado para precios de órdenes limitadas en OpenBook

  pnl_numerator:            12,
  pnl_denominator:          100,       // 12/100   = 12%   — cuota del protocolo DEL swap fee

  swap_fee_numerator:       25,
  swap_fee_denominator:     10_000,    // 25/10_000 = 0.25% — comisión bruta en swaps por ruta AMM
}
Interpretación (valores predeterminados publicados en mainnet):
  • Comisión total del swap: swap_fee = amount_in × 25 / 10_000 = 0.25% de la entrada bruta.
  • Cuota del protocolo: pnl_numerator / pnl_denominator = 12 / 100 = 12% de la comisión de swap, lo que resulta en 0.25% × 12% = 0.03% del volumen. Esta cuota se acumula en los contadores de PnL y se retira mediante WithdrawPnl.
  • Cuota del LP: el 88% restante de la comisión de swap, lo que resulta en 0.25% × 88% = 0.22% del volumen. Se queda en el pool e infla k.
  • Sin cuota de fondo. AMM v4 no tiene la división de comisiones de fondo de CPMM/CLMM.
Nota que pnl_numerator / pnl_denominator es una fracción de la comisión, no del volumen de trading — una confusión común con estos nombres de campos. trade_fee_numerator / trade_fee_denominator (también 25 / 10_000) es un campo separado utilizado por la integración con OpenBook al calcular precios inclusive de comisiones para la cuadrícula de órdenes limitadas del AMM; es igual a swap_fee por defecto pero se lee desde una ruta de código diferente. Las desviaciones de estos valores predeterminados son raras pero existen en algunos pools heredados; siempre lee las comisiones desde AmmInfo.fees antes de hacer una cotización.

Matemática directa del swap (ruta AMM)

El caso más simple: el usuario realiza un swap contra las bóvedas del pool sin interactuar con OpenBook. Las reservas internas del pool (incluidas las asignaciones en el libro) son el denominador. SwapBaseIn (entrada exacta):
amount_after_fee = amount_in − ceil(amount_in × swap_fee_numerator / swap_fee_denominator)
amount_out = amount_after_fee × out_reserve
           / (in_reserve + amount_after_fee)
require(amount_out >= minimum_amount_out)
Las reservas utilizadas aquí son las reservas efectivas. Históricamente esto era coin_vault_balance + coin_posted_on_openbook + ... (la bóveda del AMM más los tokens que tenía bloqueados en órdenes de OpenBook). Desde la desactivación de OpenBook, el saldo en el libro es cero, así que las reservas efectivas son iguales a los saldos brutos de la bóveda. La ruta MonitorStep / liquidación implícita que solía refrescar el lado de OpenBook ya no es necesaria en la práctica. SwapBaseOut (salida exacta):
amount_in_after_fee = ceil(in_reserve × amount_out / (out_reserve − amount_out))
amount_in_gross     = ceil(amount_in_after_fee × swap_fee_denominator
                            / (swap_fee_denominator − swap_fee_numerator))
require(amount_in_gross <= maximum_amount_in)

Interacción con el libro de órdenes (histórico)

Ya no está activo. La construcción de la cuadrícula descrita en esta sección refleja cómo AMM v4 originalmente reflejaba la curva en un mercado de OpenBook. La integración con OpenBook ha sido desactivada; los pools ya no publican ni mantienen órdenes en OpenBook. La matemática a continuación se preserva para contexto — explica para qué se dimensionaban las cuentas target_orders / amm_open_orders en cadena y por qué el programa aún valida los parámetros relacionados con MonitorStep aunque el keeper ya no los ejecute.
Aparte de los swaps de usuarios, AMM v4 históricamente colocaba una cuadrícula de órdenes limitadas en el mercado OpenBook. La cuadrícula se calculaba a partir de los parámetros de AmmInfo:
  • depth — número de niveles de precio por lado.
  • amount_wave — unidad base de tamaño por nivel.
  • min_size, coin_lot_size, pc_lot_size — restricciones del mercado OpenBook.
  • state_data.swap_acc_coin_fee, swap_acc_pc_fee — contadores de comisiones acumuladas desde el último TakePnl.
El programa deriva los precios por nivel caminando desde el precio actual de la curva en pasos de razón constante:
price_level(k) = curve_price × (1.0001 ^ k)       # conceptualmente
size_level(k)  = amount_wave × f(depth, k)        # disminuido por depth
Los precios y tamaños exactos se determinan mediante target_orders calculado en build_orders y comparado con amm_open_orders en cada MonitorStep. Cualquier divergencia resulta en cancelaciones + nuevas publicaciones. Las órdenes recién completadas en OpenBook se liquidan en las bóvedas del pool en la siguiente operación que refresca el lado de OpenBook. Los integradores raramente necesitan calcular la cuadrícula — el keeper de Raydium la mantiene — pero es útil saber que:
  • Un pool con liquidez significativa en el libro tiene esa liquidez contribuyendo a k, no sentada sin hacer nada.
  • Un mercado OpenBook obsoleto (cola de eventos llena, cranks bloqueados) impide actualizaciones de la cuadrícula; el AMM entonces puede cotizar precios que divergen del libro de órdenes visible hasta el siguiente crank.

Paso de liquidación (PnL)

La cuota del protocolo del 0.03% se acumula en state_data.need_take_pnl_coin y state_data.need_take_pnl_pc. TakePnl mueve estos montos fuera de las bóvedas al destino especificado por el administrador, luego pone a cero los contadores. Propiedad crucial: las reservas en el invariante siempre se calculan menos PnL acumulado, así que TakePnl no mueve la curva. Esto coincide con la convención de CPMM.

Ejemplo trabajado

Estado del pool:
  • coin_reserve = 1_000_000_000_000 (1.000.000 lado coin; 6 decimales)
  • pc_reserve = 2_000_000_000_000 (2.000.000 lado pc; 6 decimales)
  • Comisiones: swap = 25/10_000 predeterminado, pnl = 3/10_000.
Usuario: SwapBaseIn entrada exacta 1_000_000_000 coin (1.000 coin).
swap_fee        = ceil(1_000_000_000 * 25 / 10_000)    = 2_500_000
amount_after_fee =                                      997_500_000

amount_out = amount_after_fee * pc_reserve
           / (coin_reserve + amount_after_fee)
           = 997_500_000 * 2_000_000_000_000
           / (1_000_000_000_000 + 997_500_000)
           ≈ 1_995_015_009  (1.995,015 pc)

// De la comisión de swap de 2_500_000:
pnl_share = 2_500_000 * 3 / 25  = 300_000    (va al protocolo vía need_take_pnl_coin)
lp_share  = 2_500_000 * 22 / 25 = 2_200_000  (se queda en coin_reserve)

new coin_reserve = 1_000_000_000_000 + 1_000_000_000                 = 1_001_000_000_000
                   (de la cual 300_000 es PnL acumulado)
  curve coin_reserve = 1_001_000_000_000 − 300_000 = 1_000_999_700_000
new pc_reserve   = 2_000_000_000_000 − 1_995_015_009                 ≈ 1_998_004_984_991

k' = curve_coin_reserve * new_pc_reserve
   ≈ 2.000_002_701E24
k  = 1_000_000_000_000 * 2_000_000_000_000
   = 2.0E24
k' > k   ✓
La cuota del LP (2_200_000) no se desglosa en ningún lugar — es simplemente el residual que eleva k'.

Reglas de precisión

  • Las multiplicaciones de reservas utilizan u128; las divisiones finales redondean hacia cero.
  • swap_fee redondea hacia arriba (así el pool no cobra menos).
  • amount_in para SwapBaseOut redondea hacia arriba (así el usuario no paga menos).
  • Los pools con ratios de reserva extremos pueden golpear ZeroTradingTokens en entradas muy pequeñas; la misma convención que CPMM.

Limitaciones vs CPMM

  • Las reservas de AMM v4 incluyen la porción en custodia de OpenBook, así que un integrador no puede cotizar correctamente desde solo getTokenAccountBalance. Siempre obtén el estado completo (bóvedas + open_orders.free + open_orders.locked), o utiliza el quote del SDK / API.
  • AMM v4 no expone un TWAP estructurado en cadena. Los consumidores externos que quieran un precio respaldado por AMM v4 deben calcularlo por sí mismos a partir de logs de transacciones.
  • Token-2022 no es soportado.

A dónde ir ahora

Fuentes: