Esta página describe la estructura y el papel de cada cuenta. Las seeds son canónicas y aparecen listadas en
reference/program-addresses. Un pool de CLMM tiene más cuentas que uno de CPMM, porque la liquidez se almacena de forma dispersa a lo largo del rango de ticks; entender esa dispersión es la parte principal de esta página.Inventario de cuentas
Un pool de CLMM activo se describe mediante las siguientes familias de cuentas. Todas son propiedad del programa de CLMM, salvo las dos mints y sus vaults.PoolState
El estado en vivo del pool, que se lee en cada swap y en cada cambio de posición.
sqrt_price_x64ytick_currentconstituyen el estado de precio del pool. Se actualizan juntos en cada swap.tick_currentes el suelo delog_{1.0001}(precio).liquidityes la liquidez activa: la suma de los valores deLde todas las posiciones cuyo rango contienetick_current. Cambia cada vez que un swap cruza un tick y cada vez que una posición se abre, se cierra o se redimensiona.fee_growth_global_{0,1}_x64son las comisiones acumuladas por unidad de liquidez a lo largo de todo el historial del pool. Las posiciones las leen para calcular lo que se les debe.tick_spacingqueda fijado alAmmConfigen la inicialización y nunca cambia. Determina qué índices de tick pueden usarse como extremos de una posición.tick_array_bitmapes un mapa de bits en línea que cubre el rango de ticks habitual alrededor del precio spot. En pools cuyas posiciones se alejan mucho, el seguimiento de desbordamiento se encuentra en la cuenta independienteTickArrayBitmapExtension.fee_onse fija al crear el pool.0(FromInput) reproduce el comportamiento clásico de Uniswap-V3.1y2dirigen la comisión del swap a un único lado del pool; consultaproducts/clmm/feespara conocer las ventajas y desventajas de cada opción.seed_indexes[0, 0]en todos los pools creados medianteCreatePool/CreateCustomizablePool(un pool canónico por par). Un valor distinto de cero indica que el pool se creó conCreateCustomizablePoolV2(llamadaCreatePermissionedPoolantes del 22/10/2026) y que el índice forma parte de las seeds de la PDA, lo que permite que varios pools coexistan para el mismo(config, mint0, mint1). Para recalcular la dirección de un pool así necesitas conocer suseed_index.dynamic_fee_infocontiene el estado de volatilidad para el recargo de comisiones dinámicas. Cuando está activado, cada swap recalcula undynamic_fee_componentsobreAmmConfig.trade_fee_rate. La estructura se documenta enDynamicFeeInfo, más abajo; los pools sin comisiones dinámicas dejan toda la estructura a cero.
AmmConfig
CreateAmmConfig escribe la clave codificada en el programa protocol_fee_owner::ID en owner, y fund_fee_owner::ID en fund_owner. Antes de esa fecha, copiaba en ambos campos la clave del firmante administrador. Las configuraciones existentes conservan los valores con los que se crearon o a los que se rotaron, así que lee ambos campos directamente de la cuenta. Los parámetros 3 / 4 de UpdateAmmConfig siguen permitiendo rotarlos. Las direcciones están en reference/program-addresses.
Un conjunto típico de niveles de comisiones de CLMM publicado (confírmalo consultando GET https://api-v3.raydium.io/main/clmm-config):
protocol_fee_rate y fund_fee_rate son fracciones de la comisión de trading, con la misma convención que en CPMM. Consulta products/clmm/fees.
TickArrayState
CLMM no guarda un registro por cada tick, porque eso supondría miles de millones de cuentas. En su lugar, agrupa TICK_ARRAY_SIZE ticks contiguos, inicializados o no (normalmente 60 u 88, según la versión del programa) en un TickArrayState que se crea de forma perezosa en el primer uso.
order_phasees el identificador de la cohorte. Se incrementa cada vez que una cohorte pasa de «totalmente sin ejecutar» a «parcialmente ejecutada».orders_amountes el total de tokens de entrada de la cohorte actual (la más reciente).part_filled_orders_remainingregistra la cohorte anterior, que se sigue ejecutando con los swaps en curso.unfilled_ratio_x64es un multiplicador Q64.64 asociado a la cohorte: cuando un swap ejecuta el X % de la cohorte, el ratio se multiplica por(1 − X). Cada orden abierta guarda su propia instantánea(order_phase, unfilled_ratio_x64)en el momento de abrirse, de modo que el cálculo de liquidación se reduce a comparar instantáneas.
- Un extremo de posición t debe cumplir
t % tick_spacing == 0. El programa rechaza las posiciones que no se ajusten al espaciado. - El array del tick se encuentra en
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Un tick array se inicializa de forma perezosa: la primera posición o swap que toque un array sin inicializar lo crea y paga la renta.
- El programa nunca cierra un tick array. Una vez asignado, permanece durante toda la vida del pool, incluso cuando todos sus ticks vuelven a
liquidity_gross == 0. Las posiciones y swaps posteriores reutilizan la cuenta existente sin coste adicional de renta. No existe una ruta de limpieza de tick arrays asociada aClosePosition.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (en línea) cubre el rango «cercano al precio spot»: ±512 tick arrays (TICK_ARRAY_BITMAP_SIZE = 512; el campo [u64; 16] tiene 1.024 bits repartidos por igual entre índices de inicio negativos y positivos, de modo que los índices de array van de −512 a +511). Fuera de ese rango (para valores de tick extremos), el programa mantiene una cuenta de extensión:
(MIN_TICK, MAX_TICK)) sí la necesitan, pero el SDK la resuelve por ti.
Posiciones
Una posición de CLMM es un conjunto de tres cuentas más un mint:Mint del NFT de posición
Un mint de SPL Token o Token-2022 con supply 1. El NFT de posición en la cartera del propietario es un ATA que contiene ese único token. El programa asocia la autorización al titular actual del saldo del ATA del NFT, no a una Pubkey almacenada en el estado. Los nuevos mints de NFT de posición establecenpool_state como su autoridad de congelación antes de acuñar el único token y de eliminar la autoridad de mint. Establecer una autoridad de congelación no congela por sí mismo la cuenta del NFT. La cuenta permanece descongelada y transferible, salvo que se cumplan ambas condiciones: el llamador usa OpenPositionV2 u OpenPositionWithToken22Nft, y la autoridad de congelación de al menos un mint de los vaults subyacentes aparece en la lista de emisores restringidos de CLMM. Solo entonces CLMM congela la cuenta del NFT tras acuñarlo. Esto no modifica ningún byte de PersonalPositionState ni de PoolState.
PersonalPositionState
Una por cada posición abierta. Se indexa a partir del mint del NFT.
ProtocolPositionState (obsoleto)
Las versiones anteriores de CLMM guardaban una contabilidad agregada por
(pool, tick_lower, tick_upper) en una PDA ProtocolPositionState. Las versiones más recientes ya no crean ni leen esta cuenta. El slot sigue apareciendo en las listas de cuentas de OpenPosition, IncreaseLiquidity y DecreaseLiquidity como UncheckedAccount por compatibilidad con la ABI, pero el programa no escribe en él. Las cuentas existentes en la cadena son vestigiales; el administrador puede llamar a CloseProtocolPosition para recuperar la renta de ellas.La contabilidad agregada del rango ahora se deriva directamente de los dos ticks extremos (liquidity_gross, liquidity_net y los campos fee_growth_outside_* / reward_growths_outside_x64 de cada tick) en TickArrayState. La fórmula de crecimiento de comisiones dentro del rango, fee_growth_inside = global − outside_lower − outside_upper, sigue funcionando sin una cuenta de posición agregada.Observación
(tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) y después price = 1.0001 ** tick. Véase algorithms/clmm-math.
DynamicFeeConfig y DynamicFeeInfo
Los parámetros de comisión dinámica viven en dos lugares. La plantilla reutilizable, DynamicFeeConfig, es gestionada por el administrador y se comparte entre los pools que la activan. El estado de ejecución de cada pool, DynamicFeeInfo, va incrustado en PoolState y se actualiza en cada swap.
DynamicFeeConfig
["dynamic_fee_config", index.to_be_bytes()]. Se crea mediante create_dynamic_fee_config (restringido al administrador) y se modifica mediante update_dynamic_fee_config. Un pool creado con enable_dynamic_fee = true copia los cinco parámetros de calibración de la configuración (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) en su propio DynamicFeeInfo en el momento de la creación; las ediciones posteriores de DynamicFeeConfig no afectan retroactivamente a los pools existentes.
DynamicFeeInfo (incrustado en PoolState)
DynamicFeeConfig. La fórmula de comisiones y las reglas de decaimiento se documentan en products/clmm/math y products/clmm/fees.
Constantes usadas por la fórmula:
LimitOrderState
Una cuenta por cada orden límite abierta.
- Apertura: el usuario llama a
open_limit_ordery depositatotal_amountdel token de entrada; la orden queda vinculada a una cohorte deTickState. - (Opcional) Aumentar / reducir:
increase_limit_orderañade altotal_amount;decrease_limit_orderdevuelve los tokens no ejecutados (y cualquier salida liquidada hasta ese momento). - Liquidación: cuando la cohorte se ejecuta total o parcialmente, el propietario o el keeper operativo llama a
settle_limit_orderpara enviar los tokens de salida al ATA del propietario. - Cierre: una vez que
unfilled_amount == 0, la cuenta puede cerrarse. La renta siempre se devuelve aowner.
[owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. Por tanto, la PDA de la orden es única para cada combinación (owner, nonce_index, order_nonce).
LimitOrderNonce
Contador por (wallet, nonce_index) que permite a un mismo usuario ejecutar varias canalizaciones paralelas de órdenes límite sin que se produzcan colisiones de PDA.
[user_wallet.as_ref(), &[nonce_index]]. La mayoría de los clientes usan nonce_index = 0 y dejan que order_nonce lleve la cuenta de las órdenes.
Permission (retirada)
La cuenta Permission se eliminó con la actualización del 2026-10-22. Antes se usaba para restringir CreatePermissionedPool, que ahora es CreateCustomizablePoolV2, sin permisos previos. El programa ya no lee ni cierra estas cuentas, y las instrucciones CreatePermissionPda y ClosePermissionPda han desaparecido. Los PDA creados antes de la actualización (["permission", authority], 280 bytes) siguen en la cadena como datos inertes; ignórelos al revisar las cuentas propiedad de CLMM.
Derivación de las cuentas clave
reference/program-addresses.
Guía rápida del ciclo de vida
Las cuentas
TickArrayState nunca las cierra el programa: persisten durante toda la vida del pool. Una vez inicializado un tick array, permanece en la cadena aunque todos los ticks que contiene vuelvan a liquidity_gross == 0. Reutilizar un tick array existente no tiene coste; solo la primera posición que toca un array nunca inicializado paga su renta.
Dónde leer cada tema
- Matemáticas de ticks y mecánica de rangos:
products/clmm/ticks-and-positions. - Recorrido de swaps y matemáticas de crecimiento de comisiones:
products/clmm/math. - Listas de cuentas de cada instrucción:
products/clmm/instructions. - Comisiones y acumulación de recompensas:
products/clmm/fees. - IDs canónicos de programa y semillas:
reference/program-addresses.

