Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →
Esta página descreve o layout e o papel de cada conta. As seeds são canônicas e estão listadas em
reference/program-addresses. Um pool CLMM é mais pesado em contas do que um pool CPMM porque a liquidez é armazenada de forma esparsa ao longo do intervalo de ticks; entender essa esparsidade é a maior parte desta página.Inventário de contas
Um pool CLMM ativo é descrito pelas seguintes famílias de contas. Todas são de propriedade do programa CLMM, exceto os dois mints e seus vaults.PoolState
O estado ativo do pool, lido em cada swap e em cada mudança de posição.
sqrt_price_x64etick_currentsão o estado de preço do pool. Eles são atualizados juntos em cada swap.tick_currenté o piso delog_{1.0001}(price).liquidityé a liquidez ativa — a soma dos valoresLpara todas as posições cujo intervalo contémtick_current. Muda toda vez que um swap cruza um tick e toda vez que uma posição é aberta/fechada/redimensionada.fee_growth_global_{0,1}_x64são as taxas cumulativas ganhas por unidade de liquidez em todo o histórico do pool. As posições leem isso para calcular o que lhes é devido.tick_spacingé bloqueado noAmmConfigna inicialização e nunca muda. Determina quais índices de tick são permitidos como endpoints de posição.tick_array_bitmapé um bitmap inline cobrindo o intervalo comumente usado ao redor do preço spot. Para pools cujas posições alcançam muito longe, o rastreamento de overflow vive na conta separadaTickArrayBitmapExtension.fee_oné fixo na criação do pool.0(FromInput) reproduz o comportamento clássico do Uniswap-V3.1e2roteiam a taxa de swap para um único lado do livro — vejaproducts/clmm/feespara trade-offs.seed_indexé[0, 0]para cada pool criado através deCreatePool/CreateCustomizablePool(um pool canônico por par). Um valor não-zero significa que o pool foi criado viaCreatePermissionedPoole o índice faz parte das seeds do PDA do pool, permitindo que vários pools coexistam para o mesmo(config, mint0, mint1). Para re-derivar o endereço de tal pool você deve conhecer seuseed_index.dynamic_fee_infocarrega o estado de volatilidade para a sobretaxa de taxa dinâmica. Quando habilitado, cada swap recalcula umdynamic_fee_componentno topo deAmmConfig.trade_fee_rate. O layout é documentado sobDynamicFeeInfoabaixo; pools sem taxa dinâmica deixam toda a struct em zero.
AmmConfig
GET https://api-v3.raydium.io/main/clmm-config):
protocol_fee_rate e fund_fee_rate são frações da taxa de negociação; mesma convenção que CPMM. Veja products/clmm/fees.
TickArrayState
CLMM não armazena um único registro por tick. Isso seria bilhões de contas. Em vez disso, agrupa TICK_ARRAY_SIZE ticks adjacentes inicializados ou não (tipicamente 60 ou 88 dependendo da versão do programa) em um TickArrayState que é criado preguiçosamente no primeiro uso.
order_phaseé o id da coorte. Incrementa toda vez que uma coorte faz a transição de “totalmente não preenchida” para “parcialmente preenchida”.orders_amounté o total de token de entrada da coorte atual (mais nova).part_filled_orders_remainingrastreia a coorte anterior que está sendo preenchida por swaps contínuos.unfilled_ratio_x64é um multiplicador Q64.64 carregado na coorte: quando um swap preenche X% da coorte, a razão é multiplicada por(1 − X). Cada ordem aberta armazena seu próprio snapshot(order_phase, unfilled_ratio_x64)no momento da abertura, então a matemática de liquidação se reduz a comparar snapshots.
- Um tick de endpoint de posição t deve satisfazer
t % tick_spacing == 0. O programa rejeita posições fora do espaçamento. - O array do tick está localizado em
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Um array de tick é inicializado preguiçosamente: a primeira posição ou swap que toca um array não inicializado o cria, pagando o aluguel.
- Um array de tick é nunca fechado pelo programa. Uma vez alocado, persiste pela vida do pool, mesmo depois que cada tick dentro dele retorna a
liquidity_gross == 0. Posições e swaps subsequentes reutilizam a conta existente sem aluguel extra. Não há caminho de limpeza acionado porClosePositionpara arrays de tick.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (inline) cobre o intervalo “próximo ao spot” — ±1.024 arrays de tick. Fora desse intervalo (para valores de tick extremos), o programa mantém uma conta de extensão:
(MIN_TICK, MAX_TICK)) a requerem; o SDK a resolve para você.
Posições
Uma posição CLMM é um pacote de três contas mais um mint:Mint de NFT de posição
Um mint SPL Token ou Token-2022 com suprimento 1. O NFT de posição na carteira do proprietário é um ATA mantendo esse único token. O programa vincula a autorização ao detentor atual do saldo ATA do NFT, não a um Pubkey armazenado no estado. Novos mints de NFT de posição definempool_state como sua autoridade de congelamento antes de cunhar o único token e remover a autoridade de mint. Definir uma autoridade de congelamento não congela a conta do NFT em si. A conta permanece descongelada e transferível a menos que ambas as condições se mantenham: o chamador usa OpenPositionV2 ou OpenPositionWithToken22Nft, e a autoridade de congelamento de pelo menos um mint de vault subjacente aparece na lista de emissores restritos do CLMM. Apenas então o CLMM congela a conta do NFT após cunhar. Isso não muda nenhum byte de PersonalPositionState ou PoolState.
PersonalPositionState
Um por posição aberta. Chaveado no mint do NFT.
ProtocolPositionState (descontinuado)
Versões mais antigas do CLMM armazenavam agregação por
(pool, tick_lower, tick_upper) em um PDA ProtocolPositionState. Versões mais recentes não criam ou leem mais essa conta. O slot ainda aparece nas listas de contas OpenPosition / IncreaseLiquidity / DecreaseLiquidity como um UncheckedAccount para compatibilidade ABI, mas o programa não escreve nela. Contas existentes on-chain são vestigiais; o admin pode chamar CloseProtocolPosition para recuperar aluguel para elas.A agregação de bookkeeping de intervalo agora é derivada diretamente dos dois ticks de endpoint (liquidity_gross, liquidity_net e os fee_growth_outside_* / reward_growths_outside_x64 por tick) em TickArrayState. A fórmula de crescimento de taxa dentro fee_growth_inside = global − outside_lower − outside_upper continua funcionando sem uma conta de posição agregada.Observation
(tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) e então price = 1.0001 ** tick. Veja algorithms/clmm-math.
DynamicFeeConfig e DynamicFeeInfo
Os parâmetros de taxa dinâmica vivem em dois lugares. O template reutilizável — DynamicFeeConfig — é gerenciado por admin e compartilhado entre pools que optam por participar. O estado de tempo de execução por pool — DynamicFeeInfo — é incorporado em PoolState e atualizado por cada swap.
DynamicFeeConfig
["dynamic_fee_config", index.to_be_bytes()]. Criado via create_dynamic_fee_config (gated por admin) e modificado via update_dynamic_fee_config. Um pool criado com enable_dynamic_fee = true captura os cinco parâmetros de calibração da config (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) em seu próprio DynamicFeeInfo no momento da criação; edições posteriores ao DynamicFeeConfig não afetam retroativamente pools existentes.
DynamicFeeInfo (incorporado em PoolState)
DynamicFeeConfig. A matemática de taxa e as regras de decaimento são documentadas sob products/clmm/math e products/clmm/fees.
Constantes usadas pela fórmula:
LimitOrderState
Uma conta por ordem de limite aberta.
- Abrir — usuário chama
open_limit_order, depositatotal_amountdo token de entrada, a ordem é vinculada a uma coorteTickState. - (opcional) Aumentar / Diminuir —
increase_limit_orderadiciona atotal_amount;decrease_limit_orderretorna tokens não preenchidos (e qualquer saída liquidada até esse ponto). - Liquidar — quando a coorte é totalmente ou parcialmente preenchida, o proprietário ou o operador chamador chama
settle_limit_orderpara enviar tokens de saída para o ATA do proprietário. - Fechar — uma vez que
unfilled_amount == 0, a conta é fechável. O aluguel sempre retorna paraowner.
[owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. O PDA de ordem é portanto único por (owner, nonce_index, order_nonce).
LimitOrderNonce
Contador por (wallet, nonce_index) que permite que um único usuário execute múltiplos pipelines paralelos de ordens de limite sem colidir em PDAs.
[user_wallet.as_ref(), &[nonce_index]]. A maioria dos clientes usa nonce_index = 0 e deixa order_nonce carregar a cardinalidade.
Permission
Uma conta de capacidade cuja existência é a concessão: se um PDA Permission é derivado para uma determinada autoridade, essa autoridade pode chamar CreatePermissionedPool. Ele não armazena nada além da autoridade para a qual foi criado.
["permission", authority.as_ref()]. Criado por um admin via CreatePermissionPda e destruído via ClosePermissionPda (aluguel reembolsado ao chamador). Ambas as instruções de admin aceitam a admin do programa ou uma chave dedicada permission_pda_admin. Fechar o PDA revoga a concessão — a autoridade não pode mais criar pools adicionais, mas pools que já criou não são afetados.
Derivando as contas-chave
reference/program-addresses.
Referência rápida de ciclo de vida
Contas
TickArrayState são nunca fechadas pelo programa — elas persistem pela vida do pool. Uma vez que um array de tick foi inicializado, ele permanece on-chain mesmo quando cada tick dentro dele retorna a liquidity_gross == 0. Reutilizar um array de tick existente é gratuito; apenas a primeira posição a tocar um array nunca inicializado paga seu aluguel.
O que ler onde
- Matemática de tick e mecânica de intervalo:
products/clmm/ticks-and-positions. - Caminhada de swap e matemática de crescimento de taxa:
products/clmm/math. - Listas de contas de instrução:
products/clmm/instructions. - Taxas e acúmulo de recompensa:
products/clmm/fees. - IDs de programa canônicos e seeds:
reference/program-addresses.

