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 →
Por qué existen los ticks
La liquidez de CLMM se concentra en rangos de precio. Para hacer que los rangos sean manejables en cadena, los precios se cuantizan en ticks enteros, donde cada tick es un múltiplo constante del anterior: Un tick corresponde a un movimiento de precio del 0.01%, o aproximadamente 1 punto base. El mapeo es:MIN_TICK y MAX_TICK se eligen de modo que sqrt_price_x64 quepa en un u128 en ambos extremos. Cada pool garantiza que tick_lower >= MIN_TICK y tick_upper <= MAX_TICK. En la práctica, la interfaz web limita el rango a algo mucho más estrecho para evitar que los usuarios bloqueen liquidez en ticks inaccesibles.
Espaciado de ticks
ElAmmConfig de un pool fija un espaciado de ticks — los únicos ticks que una posición puede usar como puntos finales. Si tick_spacing = 60, solo los ticks …, −120, −60, 0, 60, 120, … son válidos. Un intento de abrir una posición con punto final 31 revierte con InvalidTickIndex.
Espaciados publicados comunes:
Cuanto más grueso sea el espaciado, menos tick arrays hay que inicializar, más barato es abrir una posición amplia, y más borroso es el límite de precio. Los pares volátiles típicamente viven en niveles de espaciado 120; los estables viven en niveles de espaciado 1.
Tick arrays
El pool no almacena estado por tick en cuentas separadas. En su lugar,TICK_ARRAY_SIZE ticks adyacentes (60 en el CLMM actual de Raydium) se empaquetan en un único TickArrayState. El primer tick del array es su start_tick_index, y cubre exactamente TICK_ARRAY_SIZE * tick_spacing unidades de tick entero.
Para tick_spacing = 60 y TICK_ARRAY_SIZE = 60:
- Cada tick array abarca
60 × 60 = 3600ticks enteros. start_tick_indexes un múltiplo de 3600:…, -7200, -3600, 0, 3600, 7200, ….
t = 2040 con tick_spacing = 60 vive en el tick array con start_tick_index = 0. Un punto final de posición t = 4200 vive en el array con start_tick_index = 3600.
Cuándo se crea un array
Un tick array es perezoso: la primera posición que referencia cualquier tick dentro de él inicializa el array, pagando la renta. Los swaps no inicializan tick arrays — los saltan usando el bitmap. El flujo de apertura de posición del SDK inspecciona el rango elegido, calcula la lista de tick arrays que toca, y añade instruccionesinit_tick_array en la misma transacción que OpenPosition si falta alguno.
Los tick arrays no se cierran
Una vez que un tick array ha sido inicializado, persiste durante la vida del pool. El programa no expone una ruta para cerrar un tick array, incluso después de queinitialized_tick_count vuelva a cero. No hay recuperación de renta para tick arrays; la renta pagada por la primera posición que toca un array se bloquea en esa cuenta permanentemente. Este es un compromiso deliberado: reutilizar un tick array existente es gratis para cada posición posterior, por lo que un pool muy negociado solo paga el costo de renta una vez por slot (pool, start_tick_index) independientemente de la rotación.
El bitmap
Encontrar “el siguiente tick inicializado a la izquierda/derecha del tick actual” tiene que ser rápido — un swap puede cruzar muchos ticks. El pool almacena un bitmap de 1 bit por tick array en línea enPoolState para el rango ±1,024 arrays alrededor del tick 0. Fuera de ese rango (posiciones de rango completo, configuraciones exóticas), TickArrayBitmapExtension proporciona el desbordamiento.
Un swap camina el bitmap: lowest_set_bit_above(tick_current_array_index) da el siguiente array con un tick inicializado en el lado hacia el que el swap está cruzando. Dentro de ese array, un escaneo de bits similar localiza el siguiente tick inicializado.
liquidity_gross y liquidity_net
Cada tick inicializado almacena dos valores de liquidez:
liquidity_gross— la suma deLsobre todas las posiciones que referencian este tick como punto final. Cuandoliquidity_grossllega a cero, el tick se desinicia y puede ser removido del bitmap.liquidity_net— el cambio firmado a laliquiditya nivel de pool cuando el precio cruza este tick moviéndose hacia arriba (de izquierda a derecha en el espacio de ticks). Si este tick es el límite inferior de una posición con tamañoL, contribuye+L; si es el límite superior de esa posición, contribuye−L.
- Posición A:
tick_lower = -120,tick_upper = 0, liquidezL_A = 100. - Posición B:
tick_lower = -60,tick_upper = 60, liquidezL_B = 50.
liquidity a nivel de pool para diferentes valores de tick_current:
tick_current = -180:liquidity = 0(antes de cualquier posición)tick_current = -90:liquidity = 100(dentro de A solamente)tick_current = -30:liquidity = 150(dentro de A y B)tick_current = 30:liquidity = 50(dentro de B solamente)tick_current = 90:liquidity = 0(pasado ambas)
liquidity_net (posiblemente negativo) a PoolState.liquidity. Este es el mecanismo exacto de Uniswap-v3.
Posiciones como NFTs
Una posición CLMM de Raydium es un NFT. Abrir una posición acuña un nuevo mint completamente nuevo con suministro 1 en la billetera del llamador, y la autoridad del mint es el programa CLMM. El programa vincula la propiedad de la posición a quienquiera que tenga un saldo en un ATA de ese mint en el momento de CPI. Consecuencias:- Las posiciones normalmente son transferibles. Una billetera puede vender o airdrops una posición transfiriendo el NFT. El nuevo titular puede entonces llamar a
CollectRewards,IncreaseLiquidity, etc. La excepción es una posición congelada bajo la ruta de emisor restringido a continuación. - Las posiciones son direccionables fuera de CLMM. Los mercados y billeteras muestran posiciones como otros NFTs. El SDK establece un
name/symbolrazonable en los metadatos del mint. - El PDA de una posición se deriva del mint del NFT. Puedes encontrar el
PersonalPositionStatesin saber quién lo sostiene actualmente.
Posiciones de emisor restringido
Cada mint de NFT de posición creado después de la actualización 2026-08 registra supool_state de CLMM como autoridad de congelación. Esto no significa que cada nueva posición esté congelada. Para pools ordinarios y cada posición que no coincida, la cuenta de token NFT permanece descongelada y transferible. El PDA del pool no puede firmar fuera del programa CLMM, y CLMM no expone ninguna instrucción de congelación de propósito general.
La congelación requiere ambas condiciones:
- La posición se abre a través de
OpenPositionV2uOpenPositionWithToken22Nft. - Al menos un mint de bóveda de pool lleva una autoridad de congelación de la lista de emisor restringido codificada del programa.
OpenPosition V1 no aplica este filtro. Consulta reference/program-addresses para la lista actual.
Una posición congelada:
- No puede transferir su NFT a otra cuenta de token.
- No puede cambiar el propietario de la cuenta de token NFT.
- Aún puede aumentar o disminuir liquidez y cobrar comisiones o recompensas cuando el propietario registrado firma.
- Aún puede cerrarse.
ClosePositionusa el PDA del pool para descongelar la cuenta NFT, luego quema el NFT y cierra las cuentas de posición en la misma instrucción.
Posiciones Token-2022
CLMM puede acuñar un NFT de posición bajo Token SPL clásico a través deOpenPositionV2, o bajo Token-2022 a través de OpenPositionWithToken22Nft. Ambas rutas V2 inspeccionan los mints de bóveda del pool y aplican la misma regla de congelación de emisor restringido. OpenPosition V1 es la ruta clásica de token heredada y no puede servir un pool con mints de bóveda Token-2022. La compatibilidad de billetera y mercado difiere; la interfaz de Raydium rastrea ambos programas de NFT.
Reglas de rango permitido
En el momento deOpenPosition, el programa garantiza:
tick_lower < tick_upper.tick_lower % tick_spacing == 0ytick_upper % tick_spacing == 0.MIN_TICK <= tick_lowerytick_upper <= MAX_TICK.- El llamador ha suministrado los tick arrays que contienen
tick_lowerytick_upper— ya inicializados o a través de uninit_tick_arrayen la misma transacción. - La cuenta de extensión de bitmap, si esta posición se extiende al rango de extensión.
InvalidTickIndex, NotApproved, o InsufficientLiquidity dependiendo de qué restricción. Consulta reference/error-codes.
”En rango” vs “fuera de rango”
Una posición está en rango cuandotick_lower <= tick_current < tick_upper. Solo las posiciones en rango contribuyen a PoolState.liquidity y por lo tanto solo ellas ganan comisiones de swap.
Una posición fuera de rango:
- Sostiene el 100% de un token (el que su rango ha pasado). Específicamente, si
tick_current < tick_lower, la posición sostiene solo token1 (ya ha sido “vendida” por el precio moviéndose); sitick_current >= tick_upper, sostiene solo token0. - No gana comisiones de swap.
- Sí continúa acumulando recompensas si los flujos de recompensa del pool emiten a liquidez fuera de rango — pero el comportamiento predeterminado de Raydium es “emitir solo a en rango”, coincidiendo con la convención de Uniswap v3. Consulta
products/clmm/fees.
Trampas comunes de integración
- Puntos finales fuera de espaciado. El código que calcula un tick a partir de un precio objetivo debe ajustarse a un múltiplo de
tick_spacingantes de pasarlo aOpenPosition. Los ayudantes del SDK (TickUtils.getTickWithPriceAndTickspacing) hacen esto; las matemáticas caseras a menudo no. - Tick arrays faltantes. Abrir una posición amplia puede requerir inicializar varios tick arrays; olvidar pasarlos como cuentas escribibles revierte. El
openPositionFromBasedel SDK te devuelve la lista. - Tick obsoleto después de un swap.
tick_currentpuede cruzar muchos ticks en un swap. Si tu UX muestra un “tick actual” de una llamada RPC y luego abre una posición en una posterior, la posición relativa vs el precio en vivo puede estar desviada por docenas de ticks. Vuelve a obtener justo antes de firmar. - NFTs de posición con metadatos adicionales. Si construyes una billetera que reconoce posiciones de Raydium, usa el PDA de posición / datos del programa y no un campo de metadatos codificado. Los nuevos mints de posición usan el PDA del pool como autoridad de mint y congelación en la creación; la autoridad de mint se elimina después de que se acuña el único NFT.
- Asumir que cada posición es transferible. Lee el estado
isFrozende la cuenta de token NFT antes de mostrar acciones de transferencia, mercado, depósito en garantía, o Burn & Earn.
Dónde ir a continuación
- Matemáticas — el paso de swap y la derivación de crecimiento de comisiones en la que participan los límites de ticks.
- Cuentas — los diseños de
TickArrayStateyPositionState. - Comisiones y recompensas — cómo la condición de en-rango controla la acumulación de comisiones.
algorithms/clmm-math— la derivación compartida de las fórmulas de liquidez concentrada.
raydium-io/raydium-clmm— módulostick_array,tick,position- Whitepaper “Uniswap v3 Core”, §6 (ticks), §7 (fee growth)

