Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →
products/clmm/accounts (o que são as contas) e products/clmm/math (o que é a matemática). É autoritativa para argumentos e ordenação de contas; layouts de bytes específicos vêm do IDL.
Inventário de instruções
A maioria das instruções apenas para admin (
CreateAmmConfig, UpdateAmmConfig, UpdatePoolStatus, CreateSupportMintAssociated, CreateOperationAccount, UpdateOperationAccount, CloseProtocolPosition) é controlada pela chave admin codificada do programa. CreatePermissionPda / ClosePermissionPda aceitam a chave admin ou uma chave permission_pda_admin dedicada. Instruções de admin de fluxo de recompensa (TransferRewardOwner, CollectRemainingRewards) são controladas pelo financiador de recompensa, não pelo admin do programa.
Sufixo V2 significa “suporta Token-2022 em cofres / NFT, requer slot de extensão bitmap”. O SDK escolhe V2 por padrão para novos pools.
CreatePool
Argumentos
Pré-condições
token_mint_0 < token_mint_1por ordem de bytes.amm_config.disable_create_pool == false.- Mints não são rejeitados pela lista de permissões de extensão Token-2022.
pool_state.sqrt_price_x64 = sqrt_price_x64,tick_current = floor(log_{1.0001}(price)).pool_state.liquidity = 0(sem posições ainda).pool_state.fee_on = FromInput(padrão legado).pool_state.dynamic_fee_infoé zerado (taxa dinâmica desabilitada).
CreateCustomizablePool
Recomendado para novos pools. Mesmo efeito que CreatePool mais modo de coleta de taxa por pool e um opt-in de taxa dinâmica opcional.
Argumentos
CreatePool mais, quando enable_dynamic_fee = true:
Pré-condições — mesmas que
CreatePool. Se enable_dynamic_fee = false, dynamic_fee_config é ignorado.
Pós-condições
pool_state.fee_ondefinido para a varianteCollectFeeOnescolhida.- Se taxa dinâmica foi habilitada:
pool_state.dynamic_fee_infoé inicializado a partir doDynamicFeeConfigfornecido (cinco parâmetros de calibração copiados; campos de estado zerados). - Caso contrário:
pool_state.dynamic_fee_infoé zerado (= taxa dinâmica inativa para sempre para este pool).
fee_on e o bit de habilitação de taxa dinâmica são definidos apenas na criação do pool. Não há atualização in-place — pools criados via CreatePool legado não podem ganhar retroativamente taxa dinâmica ou taxa unilateral. Novas implantações devem usar esta instrução como padrão.
CreatePermissionedPool
Tanto CreatePool quanto CreateCustomizablePool derivam o PDA do pool de ["pool", amm_config, token_mint_0, token_mint_1], então há exatamente um endereço de pool canônico por tripla (config, mint0, mint1) — um segundo init nas mesmas sementes falha. CreatePermissionedPool remove essa restrição dobrando um seed_index: u16 fornecido pelo cliente nas sementes do PDA do pool, permitindo múltiplos pools para o mesmo par e nível de taxa — cada um em seu próprio endereço. Como um endereço de pool arbitrário é uma capacidade privilegiada, o pagador deve ter um PDA Permission que o autorize.
Tudo mais sobre o pool é idêntico a CreateCustomizablePool: ele leva os mesmos CreateCustomizableParams e suporta taxa unilateral e o opt-in de taxa dinâmica.
Argumentos
CreateCustomizablePool mais, na frente:
O PDA
pool_state é derivado de ["pool", amm_config, token_mint_0, token_mint_1, seed_index.to_le_bytes()].
Pré-condições
seed_index != 0. Umseed_indexde0é reservado para pools legados e é rejeitado aqui; o componente de semente[0, 0]é o que faz um endereço de pool legado colapsar para a forma clássica de quatro sementes.- O PDA
permissionparapayerexiste (criado por um admin viaCreatePermissionPda). - Mesmas regras de mint / lista de permissões que
CreatePool.
- Um novo
pool_stateexiste no endereço derivado deseed_index, compool_state.seed_index = seed_index. - Todo outro pós-estado corresponde a
CreateCustomizablePool(modo de taxa, taxa dinâmica opcional).
Esta instrução não amplia o acesso geral de criação de pool — a criação sem permissão continua através de
CreatePool / CreateCustomizablePool, que permanecem um-pool-por-par. CreatePermissionedPool existe para o caso específico em que um operador na lista de permissões precisa de vários pools para o mesmo par (por exemplo, preços iniciais diferentes ou coortes de lançamento) e tem um PDA Permission concedido pelo admin.OpenPositionV2 / OpenPositionWithToken22Nft
Cria uma nova posição dentro de um pool existente.
Argumentos
Matemática — veja
products/clmm/math. Dado base_flag, o programa resolve liquidity ou (amount_0_max, amount_1_max) em L real e os valores de token reais consumidos.
Pré-condições
tick_lower < tick_upper, ambos múltiplos depool.tick_spacing, dentro de[MIN_TICK, MAX_TICK].- Tick arrays necessários passados e inicializados (ou criados aqui via CPI
InitTickArrayna transação). - Usuário tem pelo menos
amount_0_maxeamount_1_maxnas ATAs de origem.
personal_positionexiste,liquiditydefinido,fee_growth_inside_lastcapturado.- Entradas de tick-array em
tick_loweretick_upperatualizadas (liquidity_gross += L,liquidity_net ± L, snapshots de crescimento de taxa mantidos). pool_state.liquidity += Lse a posição está no intervalo (tick_lower ≤ tick_current < tick_upper).- O mint NFT de posição registra
pool_statecomo autoridade de congelamento. A autoridade de mint é removida após o único NFT ser cunhado. Registrar a autoridade de congelamento não altera o estado da conta de token NFT. - A conta de token NFT permanece descongelada a menos que a instrução seja
OpenPositionV2ouOpenPositionWithToken22Nfte a autoridade de congelamento de qualquer mint de cofre corresponda à lista de emissores restritos do CLMM. Apenas esse caminho V2 correspondente congela a conta.OpenPositionV1 não congela.
InvalidTickIndex, NotApproved, ZeroAmountSpecified, TransactionTooLarge (se muitos tick arrays).
O congelamento de posição não adiciona contas de instrução declaradas ou argumentos. Clientes podem abrir essas posições com os layouts V2 existentes. O comportamento é selecionado on-chain a partir de
vault_0_mint e vault_1_mint.IncreaseLiquidityV2
Adiciona liquidez a uma posição já aberta.
Argumentos
OpenPosition menos o mint NFT (posição já existe; o NFT é passado como a ATA do proprietário segurando 1 token).
Efeito
- Transfere
amount_0_actual/amount_1_actualdo usuário → cofres. - Incrementa
personal_position.liquidityepool_state.liquidity(se no intervalo), e oliquidity_gross/liquidity_netdo tick de ponto final de acordo. - Coleta taxas e recompensas devidas desde o último toque e as credita a
tokens_fees_owed_{0,1}/reward_amount_owed. Aquelas são pagas apenas emDecreaseLiquidityouCollectReward, não em aumento.
DecreaseLiquidityV2
Remove liquidez de uma posição.
Argumentos
IncreaseLiquidity.
Efeito
- Computa
(amount_0, amount_1)para oLremovido dadosqrt_price_x64atual. - Liquida taxas/recompensas acumuladas desde o último toque, mesmo que
IncreaseLiquidity. - Transfere
amount_0 + fees_owed_0eamount_1 + fees_owed_1dos cofres para o usuário. - Decrementa contadores de liquidez; se o novo
personal_position.liquidity == 0, a posição é elegível paraClosePosition.
amount_0_min e amount_1_min são os mínimos que o usuário aceita líquido de taxas de transferência Token-2022 no lado de saída.
ClosePosition
Queima o NFT de posição e fecha PersonalPositionState.
Contas declaradas
Contas restantes
- NFT descongelado: nenhum necessário; uma conta de pool extra é inofensiva porque o manipulador não a lê.
- NFT congelado: anexa
personal_position.pool_idcomo a primeira conta restante. O programa a carrega comoPoolStatee usa suas sementes de PDA para assinar o descongelamento.
personal_position.liquidity == 0.tokens_fees_owed_{0,1} == 0.- Todos os contadores de recompensa
reward_amount_owed == 0.
- Se a conta de token NFT estiver congelada, verifica se a primeira conta restante é igual a
personal_position.pool_id, então a descongela com o PDA do pool. - Queima o NFT.
- Fecha a conta de token NFT e
personal_position, reembolsando aluguel paranft_owner. Se o NFT de posição usar Token-2022, também fecha o mint NFT; mints Token SPL clássicos não podem ser fechados e permanecem com fornecimento zero.
AccountLack ao fechar uma posição congelada. Passar o pool para cada fechamento é a estratégia compatível mais simples.
SwapV2
Caminha pela curva de liquidez; entrada exata ou saída exata dependendo de is_base_input.
Argumentos
Chamadores passam uma lista classificada de tick arrays cobrindo a caminhada de swap esperada; o programa usa quantos precisar. O SDK computa esta lista via
PoolUtils.computeAmountOutFormat ou o endpoint de cotação da API.
Pré-condições
pool_state.statuspermite swap.now >= open_time.sqrt_price_limit_x64está no lado correto desqrt_price_x64para a direção.
ExceededSlippage, SqrtPriceLimitOverflow, TickArrayNotFound, LiquidityInsufficient.
O que SwapV2 faz internamente que chamadores devem saber (lançamento pós-2025):
- Sobretaxa de taxa dinâmica — se
pool.dynamic_fee_infoé diferente de zero, o programa atualiza o acumulador de volatilidade usando a distância de tick percorrida desde o último swap (com as regras de filtro/decaimento deproducts/clmm/fees) e adiciona umdynamic_fee_componentem cima deAmmConfig.trade_fee_rate. Taxa total é limitada a 10% (MAX_FEE_RATE_NUMERATOR / 1_000_000). - Correspondência de ordem limitada — quando a caminhada de preço cruza um tick que contém ordens limitadas abertas, o programa primeiro preenche liquidez de ordem limitada disponível naquele tick (FIFO por
order_phase), depois prossegue ao longo da curva de liquidez LP. Quantidades preenchidas atualizamtick.unfilled_ratio_x64etick.part_filled_orders_remainingpara liquidação posterior; as próprias ordens permanecem não gastas até que seu proprietário chameSettleLimitOrder. - Roteamento de taxa unilateral — quando
pool.fee_on = Token0OnlyouToken1Only, a etapa de swap ainda computa o mesmo comércio entrada-saída; a taxa é então roteada para o lado configurado. Para direções onde o lado de taxa configurado é a saída, a taxa é deduzida da saída de swap (o usuário recebeout − fee); para direções onde é a entrada, o comportamento corresponde aFromInput. Vejais_fee_on_input(zero_for_one)eis_fee_on_token0(zero_for_one)emPoolState.
Swap (V1) implementa a mesma taxa dinâmica, roteamento de taxa unilateral e correspondência de ordem limitada que SwapV2; o único recurso que falta é suporte Token-2022 — ambos os cofres devem ser Token SPL clássico. Pools com qualquer mint Token-2022 devem ser trocados via SwapV2. O agregador e SDK já preferem V2 para cada perna CLMM então chamadores não precisam ramificar no tipo de mint.
OpenLimitOrder
Coloca uma ordem de venda em um tick específico. A ordem fica em uma coorte FIFO por tick e é preenchida conforme o preço passa.
Argumentos
Mudança de lista de contas (lançamento 2026-07).
OpenLimitOrder agora também leva as contas do lado de saída — output_token_account, output_vault e output_vault_mint — além do lado de entrada. Elas são usadas apenas para validação: o programa rejeita a ordem se a conta de token de entrada ou saída do proprietário estiver congelada. Isso garante que um preenchimento possa realmente ser liquidado para a ATA de saída do proprietário, o que importa para mints Token-2022 de lista de permissões / congelados por padrão (por exemplo, tokens permissionados) onde uma conta pode ainda não estar descongelada. Clientes construídos contra a lista de contas unilateral mais antiga devem adicionar as três contas de saída.- Nem
input_token_accountnemoutput_token_accountestá congelado (senãoNotApproved). pool_state.statuspermite tanto swap (bit 4) quanto operações de ordem limitada (bit 5) (senãoNotApproved).tick_index % pool.tick_spacing == 0e dentro de[MIN_TICK, MAX_TICK].tick_indexestá no lado direito depool.tick_currentpara a direção escolhida (vender token0 → tick deve estar acima do atual, e vice-versa). Vender em um tick já cruzado seria correspondido imediatamente e é rejeitado.
limit_orderexiste, capturandotick.order_phaseetick.unfilled_ratio_x64no tempo de abertura.tick.orders_amount += amount(na coorte atual).limit_order_nonce.order_nonce += 1.OpenLimitOrderEventemitido.
NotApproved (conta de token de entrada ou saída congelada, ou o pool tem swap / ordem limitada desabilitado), InvalidLimitOrderAmount (zero ou abaixo do mínimo do pool), InvalidTickIndex (fora de [MIN_TICK, MAX_TICK], ou no lado errado de tick_current para a direção escolhida), TickAndSpacingNotMatch (tick_index % pool.tick_spacing != 0), OrderPhaseSaturated.
IncreaseLimitOrder
Adiciona a uma ordem aberta existente. Apenas chamável pelo owner da ordem.
Argumentos
OpenLimitOrder menos a conta nonce; o PDA limit_order é passado diretamente.
Pré-condições
limit_order.owner == signer.- A ordem ainda está na mesma coorte (
tick.order_phase == limit_order.order_phase). Se a coorte já começou a ser preenchida, a ordem é parcialmente liquidada — o chamador deve chamarDecreaseLimitOrderouSettleLimitOrderprimeiro para avançar.
- Transfere
amountda ATA do proprietário parainput_vault. limit_order.total_amount += amount;tick.orders_amount += amount.
DecreaseLimitOrder
Reduz ou cancela completamente uma ordem aberta. Paga o restante não preenchido de volta ao proprietário, mais qualquer saída já liquidada por preenchimentos parciais anteriores.
Argumentos
Efeito
- Recomputa a quantidade preenchida da ordem a partir de
unfilled_ratio_x64da coorte desde a abertura. - Envia saída preenchida para
output_token_account. - Envia
amountde entrada não preenchida de volta parainput_token_account. - Atualiza
limit_orderde acordo. Se o novo restante não preenchido for zero, o programa fecha a conta e reembolsa aluguel paraowner.
SettleLimitOrder
Envia tokens de saída preenchidos para o proprietário sem alterar o restante não preenchido da ordem. Útil quando keepers auto_withdraw querem pagar gradualmente preenchimentos parciais de longa duração.
Chamador — ou o owner da ordem, ou o limit_order_admin do programa (uma carteira quente operacional off-chain que executa um loop de keeper automatizado). O keeper não tem outra autoridade — não pode mover fundos do usuário fora de enviar saída preenchida para a ATA owner.
Contas
Efeito
- Computa a saída cumulativa devida usando
(limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64). - Transfere o delta para
output_token_account. - Atualiza
limit_order.settled_output. - Não fecha a ordem; ela ainda está aberta contra qualquer entrada restante.
CloseLimitOrder
Fecha uma conta de ordem totalmente consumida. Aluguel é sempre retornado a limit_order.owner independentemente de quem assina.
Chamador — ou owner ou limit_order_admin.
Pré-condições
- A ordem tem zero restante não preenchido (ou
amount == total_amountfoi preenchido e liquidado, ou o proprietário diminuiu anteriormente a ordem para zero e esqueceu de fechar).
- Fecha
limit_order; aluguel é enviado paralimit_order.owner.
CreateDynamicFeeConfig (admin)
Cria um conjunto de parâmetros reutilizável sob um índice u16.
Argumentos
Erros comuns —
InvalidDynamicFeeConfigParams se decay_period <= filter_period ou qualquer campo com valor 0 estiver fora dos limites.
UpdateDynamicFeeConfig (admin)
Modifica um DynamicFeeConfig existente. Pools que já capturaram a configuração no tempo de criação não são atualizados retroativamente; apenas pools recém-criados que referenciam esta configuração pegarão os novos valores.
Argumentos — mesmos cinco campos de calibração que CreateDynamicFeeConfig (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator); index é fixo na criação e não é re-passado aqui.
CollectProtocolFee / CollectFundFee
Forma idêntica a CollectProtocolFee / CollectFundFee do CPMM. O signatário deve corresponder a AmmConfig.owner / AmmConfig.fund_owner. Varre taxas de protocolo/fundo acumuladas dos cofres do pool para um destinatário, zera os campos correspondentes PoolState.protocol_fees_* / fund_fees_*.
InitializeReward
Adiciona um novo fluxo de recompensa a um pool. Até 3 fluxos podem estar ativos por vez.
Argumentos
Pré-condições
- Menos de 3 fluxos atualmente ativos no pool.
- Financiador deposita
total_emission = emissions_per_second × (end_time − open_time)de token de recompensa no cofre como parte desta instrução. - Mint de recompensa na lista de permissões por
operation_state.
SetRewardParams
Estende, reabastece ou altera taxa de emissão em um fluxo de recompensa existente. Tipicamente chamado por um criador de pool ou o multisig Raydium. Restrições vivem on-chain: você geralmente pode estender end_time ou aumentar emissões, não encolhê-las retroativamente. Verifique a lista de proprietários de operation_state.
UpdateRewardInfos
Pura contabilidade — liquida reward_growth_global_x64 até o tempo atual multiplicando emissions_per_second × Δt / liquidity. Chamado internamente por cada instrução que toca liquidez. Exposto como instrução autônoma porque atores externos (UIs, cranks) às vezes querem acioná-lo.
CollectReward
Proprietário de posição reivindica tokens de recompensa devidos.
Contas
Efeito
- Liquida crescimento de recompensa (mesmo padrão que taxas).
- Transfere a quantidade devida para a ATA do destinatário, zera
reward_amount_owed[i].
Matriz de mudança de estado
Próximos passos
products/clmm/code-demos— amostras TypeScript executáveis.products/clmm/fees— detalhes sobre acúmulo de taxa e recompensa.reference/error-codes— tabela de erro Anchor CLMM completa.
raydium-io/raydium-clmm—programs/amm/src/instructions- Raydium SDK v2 —
@raydium-io/raydium-sdk-v2

