Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →
Por que ticks existem
A liquidez do CLMM é concentrada em faixas de preço. Para tornar as faixas viáveis on-chain, os preços são quantizados em ticks inteiros, onde cada tick é um múltiplo constante do anterior: Um tick corresponde a um movimento de preço de 0,01%, ou ~1 basis point. O mapeamento é:MIN_TICK e MAX_TICK são escolhidos para que sqrt_price_x64 caiba em um u128 em ambas as extremidades. Cada pool garante que tick_lower >= MIN_TICK e tick_upper <= MAX_TICK. Na prática, a interface web limita o intervalo a algo muito mais estreito para evitar que os usuários travem liquidez em ticks inacessíveis.
Espaçamento de ticks
OAmmConfig de um pool define um espaçamento de ticks — os únicos ticks que uma posição pode usar como endpoints. Se tick_spacing = 60, apenas ticks …, −120, −60, 0, 60, 120, … são válidos. Uma tentativa de abrir uma posição com endpoint 31 reverte com InvalidTickIndex.
Espaçamentos publicados comuns:
Quanto mais grosseiro o espaçamento, menos tick arrays para inicializar, mais barato abrir uma posição ampla, e mais borrada a fronteira de preço. Pares voláteis normalmente vivem em camadas de espaçamento 120; stablecoins vivem em camadas de espaçamento 1.
Tick arrays
O pool não armazena estado por-tick em contas separadas. Em vez disso,TICK_ARRAY_SIZE ticks adjacentes (60 no CLMM atual do Raydium) são empacotados em um único TickArrayState. O primeiro tick do array é seu start_tick_index, e ele cobre exatamente TICK_ARRAY_SIZE * tick_spacing unidades de tick inteiro.
Para tick_spacing = 60 e TICK_ARRAY_SIZE = 60:
- Cada tick array abrange
60 × 60 = 3600ticks inteiros. start_tick_indexé um múltiplo de 3600:…, -7200, -3600, 0, 3600, 7200, ….
t = 2040 em tick_spacing = 60 vive no tick array com start_tick_index = 0. Um endpoint de posição t = 4200 vive no array com start_tick_index = 3600.
Quando um array é criado
Um tick array é lazy: a primeira posição que referencia qualquer tick dentro dele inicializa o array, pagando o aluguel. Swaps não inicializam tick arrays — eles pulam sobre arrays não inicializados usando o bitmap. O fluxo de abertura de posição do SDK inspeciona o intervalo escolhido, calcula a lista de tick arrays que ele toca, e adiciona instruçõesinit_tick_array na mesma transação que OpenPosition se algum estiver faltando.
Tick arrays não são fechados
Uma vez que um tick array foi inicializado, ele persiste pela vida do pool. O programa não expõe um caminho para fechar um tick array, mesmo depois queinitialized_tick_count retorna a zero. Não há recuperação de aluguel para tick arrays; o aluguel pago pela primeira posição que toca um array é travado naquela conta permanentemente. Esta é uma troca deliberada: reutilizar um tick array existente é gratuito para cada posição subsequente, então um pool muito negociado paga o custo de aluguel apenas uma vez por slot (pool, start_tick_index) independentemente da rotatividade.
O bitmap
Encontrar “o próximo tick inicializado à esquerda/direita do tick atual” tem que ser rápido — um swap pode cruzar muitos ticks. O pool armazena um bitmap de 1-bit-por-tick-array inline emPoolState para o intervalo ±1.024 arrays ao redor do tick 0. Fora desse intervalo (posições de intervalo completo, configurações exóticas), TickArrayBitmapExtension fornece o overflow.
Um swap caminha pelo bitmap: lowest_set_bit_above(tick_current_array_index) fornece o próximo array com um tick inicializado no lado para o qual o swap está se movendo. Dentro desse array, um bit-scan similar localiza o próximo tick inicializado.
liquidity_gross e liquidity_net
Todo tick inicializado armazena dois valores de liquidez:
liquidity_gross— a soma deLsobre todas as posições que referenciam este tick como endpoint. Quandoliquidity_grossatinge zero, o tick se torna não inicializado e pode ser removido do bitmap.liquidity_net— a mudança assinada para aliquidityde nível de pool quando o preço cruza este tick se movendo para cima (esquerda-para-direita no espaço de ticks). Se este tick é o limite inferior de uma posição com tamanhoL, ele contribui+L; se é o limite superior dessa posição, ele contribui−L.
- Posição A:
tick_lower = -120,tick_upper = 0, liquidezL_A = 100. - Posição B:
tick_lower = -60,tick_upper = 60, liquidezL_B = 50.
liquidity de nível de pool para diferentes valores de tick_current:
tick_current = -180:liquidity = 0(antes de qualquer posição)tick_current = -90:liquidity = 100(dentro de A apenas)tick_current = -30:liquidity = 150(dentro de A e B)tick_current = 30:liquidity = 50(dentro de B apenas)tick_current = 90:liquidity = 0(após ambas)
liquidity_net (possivelmente negativo) a PoolState.liquidity. Este é o mecanismo exato do Uniswap-v3.
Posições como NFTs
Uma posição CLMM do Raydium é um NFT. Abrir uma posição cria um novo mint com suprimento 1 na carteira do chamador, e a autoridade do mint é o programa CLMM. O programa vincula a propriedade da posição a quem quer que tenha um saldo em um ATA daquele mint no momento do CPI. Consequências:- Posições são normalmente transferíveis. Uma carteira pode vender ou fazer airdrop de uma posição transferindo o NFT. O novo detentor pode então chamar
CollectRewards,IncreaseLiquidity, etc. A exceção é uma posição congelada sob o caminho de emissor restrito abaixo. - Posições são endereçáveis fora do CLMM. Marketplaces e carteiras exibem posições como outros NFTs. O SDK define um
name/symbolrazoável nos metadados do mint. - O PDA de uma posição é derivado do mint do NFT. Você pode encontrar o
PersonalPositionStatesem saber quem o detém atualmente.
Posições de emissor restrito
Todo mint de NFT de posição criado após a atualização de 2026-08 registra seupool_state do CLMM como autoridade de congelamento. Isto não significa que toda nova posição está congelada. Para pools ordinários e toda posição não correspondente, a conta de token do NFT permanece descongelada e transferível. O PDA do pool não pode assinar fora do programa CLMM, e o CLMM não expõe nenhuma instrução de congelamento de propósito geral.
O congelamento requer ambas estas condições:
- A posição é aberta através de
OpenPositionV2ouOpenPositionWithToken22Nft. - Pelo menos um mint de vault do pool carrega uma autoridade de congelamento da lista de emissor restrito codificada do programa.
OpenPosition V1 não aplica este filtro. Veja reference/program-addresses para a lista atual.
Uma posição congelada:
- Não pode transferir seu NFT para outra conta de token.
- Não pode mudar o proprietário da conta de token do NFT.
- Ainda pode aumentar ou diminuir liquidez e coletar taxas ou recompensas quando o proprietário registrado assina.
- Ainda pode fechar.
ClosePositionusa o PDA do pool para descongelar a conta do NFT, depois queima o NFT e fecha as contas de posição na mesma instrução.
Posições Token-2022
O CLMM pode cunhar um NFT de posição sob Token SPL clássico através deOpenPositionV2, ou sob Token-2022 através de OpenPositionWithToken22Nft. Ambos os caminhos V2 inspecionam os mints de vault do pool e aplicam a mesma regra de congelamento de emissor restrito. OpenPosition V1 é o caminho clássico de token legado e não pode servir um pool com mints de vault Token-2022. A compatibilidade de carteira e marketplace difere; a interface do Raydium rastreia ambos os programas de NFT.
Regras de intervalo permitido
No momento deOpenPosition o programa garante:
tick_lower < tick_upper.tick_lower % tick_spacing == 0etick_upper % tick_spacing == 0.MIN_TICK <= tick_loweretick_upper <= MAX_TICK.- O chamador forneceu os tick arrays contendo
tick_loweretick_upper— já inicializados ou via uminit_tick_arrayna mesma transação. - A conta de extensão de bitmap, se esta posição se estende para o intervalo de extensão.
InvalidTickIndex, NotApproved, ou InsufficientLiquidity dependendo de qual restrição. Veja reference/error-codes.
”In-range” vs “out-of-range”
Uma posição está in-range quandotick_lower <= tick_current < tick_upper. Apenas posições in-range contribuem para PoolState.liquidity e portanto apenas elas ganham taxas de swap.
Uma posição out-of-range:
- Detém 100% de um token (aquele para o qual seu intervalo caminhou). Especificamente, se
tick_current < tick_lower, a posição detém apenas token1 (já foi “vendida” pelo preço se movendo para longe); setick_current >= tick_upper, detém apenas token0. - Não ganha taxas de swap.
- Continua a acumular recompensas se os fluxos de recompensa do pool emitem para liquidez out-of-range — mas o comportamento padrão do Raydium é “emitir apenas para in-range”, correspondendo à convenção do Uniswap v3. Veja
products/clmm/fees.
Armadilhas comuns de integração
- Endpoints fora do espaçamento. Código que calcula um tick a partir de um preço alvo deve se ajustar a um múltiplo de
tick_spacingantes de passá-lo paraOpenPosition. Os auxiliares do SDK (TickUtils.getTickWithPriceAndTickspacing) fazem isso; matemática caseira frequentemente não. - Tick arrays faltando. Abrir uma posição ampla pode exigir inicializar vários tick arrays; esquecer de passá-los como contas graváveis reverte. O
openPositionFromBasedo SDK retorna a lista para você. - Tick obsoleto após um swap.
tick_currentpode cruzar muitos ticks em um swap. Se sua UX mostra um “tick atual” de uma chamada RPC e depois abre uma posição em uma posterior, a posição relativa vs o preço ao vivo pode estar desligada por dezenas de ticks. Re-busque logo antes de assinar. - NFTs de posição com metadados extras. Se você construir uma carteira que reconheça posições do Raydium, use o PDA de posição / dados do programa e não um campo de metadados codificado. Novos mints de posição usam o PDA do pool como autoridade de mint e congelamento na criação; a autoridade de mint é removida após o único NFT ser cunhado.
- Assumindo que toda posição é transferível. Leia o estado
isFrozenda conta de token do NFT antes de mostrar transferência, marketplace, escrow, ou ações de Burn & Earn.
Próximos passos
- Math — o passo de swap e derivação de crescimento de taxa que limites de ticks participam.
- Accounts — os layouts
TickArrayStateePositionState. - Fees and rewards — como in-range-ness controla acúmulo de taxa.
algorithms/clmm-math— a derivação compartilhada das fórmulas de liquidez concentrada.
raydium-io/raydium-clmm— módulostick_array,tick,position- “Uniswap v3 Core” whitepaper, §6 (ticks), §7 (fee growth)

