Skip to main content
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 é a referência de instrução autoritativa. Para código que realmente compõe essas instruções, veja products/cpmm/code-demos. Para significados de códigos de erro, veja reference/error-codes.A atualização do programa 2026-09 reconstruiu o CPMM no Anchor 1.0.2 / Solana 3.1.10, adicionou a instrução de admin CollectExcessLamports, removeu a whitelist de mint Token-2022 codificada, e alterou o que CreateAmmConfig escreve em protocol_owner / fund_owner. Nenhuma instrução voltada para o usuário alterou suas contas, argumentos ou matemática. Veja a entrada do changelog de 2026-09-09.
Ambas as instruções de coleta de taxa de criador alteraram suas listas de contas em 2026-09-19. CollectCreatorFee ganha creator_fee_share; CollectCreatorFeePermissionless ganha amm_config e creator_fee_share. Ambas são anexadas após system_program, então cada conta que um cliente existente já passa mantém seu índice — mas as novas contas são obrigatórias, então uma transação construída contra o layout antigo fica com contas a menos e é rejeitada com AccountNotEnoughKeys (3005) do Anchor. Duas instruções de admin — CreateCreatorFeeShare e CloseCreatorFeeShare — são adicionadas, e UpdateAmmConfig recebe um novo param = 8. Veja a entrada do changelog de 2026-09-19.

Resumo de instruções

Bitmask de status: o status de cada pool é um u8 onde bit 0 = depósito desabilitado, bit 1 = saque desabilitado, bit 2 = swap desabilitado (PoolStatusBitIndex { Deposit, Withdraw, Swap } no programa). Um bit claro significa que a operação é permitida; um bit definido significa que está pausada. UpdatePoolStatus recebe um u8 bruto e sobrescreve o valor existente. As próximas seções passam por cada uma em detalhes. A ordenação de contas segue o IDL do CPMM; o SDK e o cliente Rust em raydium-cp-swap/programs/cp-swap/src/instructions correspondem a essa ordem.

Initialize

Cria um novo pool CPMM. Argumentos
Contas (W = gravável, S = assinante) * pool_state assina apenas no caminho de keypair aleatória; o caminho PDA canônico executa sem pool_state assinando. Pré-condições
  • Mints são ordenados (token_0_mint < token_1_mint por ordem de byte).
  • Nenhum mint usa uma extensão fora da lista de permissões CPMM (TransferFeeConfig, MetadataPointer, TokenMetadata, InterestBearingConfig, ScaledUiAmount) — veja products/cpmm/accounts. Um mint cuja PDA SupportMintAssociated (seed [b"support_mint", mint]) existe pula a verificação de extensão — mas você deve anexar esse PDA a remaining_accounts. O programa apenas verifica as contas que você passa e nunca carrega o PDA em si, então confiar no registro sem fornecer a conta ainda falha com NotSupportMint (6007). A ordem não importa (correspondência é por chave); passe uma entrada por mint que precisa do bypass. Esse registro é o único bypass desde que a atualização 2026-09 removeu a whitelist de quatro mints codificada.
  • creator tem pelo menos init_amount_0 e init_amount_1 nos respectivos ATAs.
  • amm_config.disable_create_pool == false.
Pós-condições
  • pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1) — a raiz quadrada completa. O criador é cunhado com lp_supply − 100; as 100 unidades base bloqueadas são contadas em lp_supply mas nunca cunhadas.
  • Então lp_mint.supply == pool_state.lp_supply − 100 pela vida do pool. Toda matemática de compartilhamento LP (depósito, saque) divide por lp_supply, então use esse campo e não substitua o fornecimento on-chain do mint. Reverte com InitLpAmountTooLess se sqrt(...) < 100.
  • observation_state é inicializado; observation_index = 0 e pool_id = pool_state.key().
  • Lamports de create_pool_fee são transferidos do criador para o receptor e sincronizados como SOL nativo (é um ATA wSOL).
  • O bitmask de status do pool é 0 (depósito / saque / swap todos habilitados).
  • enable_creator_fee = false e creator_fee_on = BothToken. Initialize não suporta habilitar a taxa de criador — esse caminho é InitializeWithPermission.
  • open_time é aumentado para block_timestamp + 1 se o chamador passou um valor <= block_timestamp. Swaps são rejeitados antes de open_time; depósitos e saques funcionam imediatamente.
Erros comuns (lista completa em reference/error-codes)
  • InvalidInput — mints desordenados ou mints idênticos.
  • NotSupportMint — extensão Token-2022 bloqueada.
  • ExceededSlippage — raramente; se init_amount_0/1 resultarem em zero LP devido a incompatibilidade de decimais.

Deposit

Adiciona liquidez em ambos os tokens proporcionais ao pool. Argumentos
Contas Matemática
Dois detalhes que valem a pena fixar: a base pro-rata é o total do vault excluindo taxas (vault_amount_without_fee, ou seja, o saldo bruto menos os contadores acumulados de protocolo, fundo e criador), não o saldo bruto do vault; e o limite de slippage é verificado contra o que o pagador realmente transfere, após a taxa de transferência Token-2022 ser adicionada, não contra o movimento bruto do vault. Nenhuma mudança na proporcionalidade de k — ambos os totais e lp_supply escalam pelo mesmo fator. Pós-condições
  • lp_supply += lp_token_amount.
  • vault_0 += needed_token_0 (líquido de qualquer taxa de transferência Token-2022 na entrada).
  • vault_1 += needed_token_1 (líquido de qualquer taxa de transferência Token-2022 na entrada).
Erros comuns — ExceededSlippage, ZeroTradingTokens, InvalidStatus se depósito está pausado.

Withdraw

Queima tokens LP e recebe ambos os tokens subjacentes pro-rata. Argumentos
Contas As primeiras 13 contas são idênticas a Deposit, e lp_mint é gravável porque os tokens LP são queimados. Withdraw adicionalmente recebe uma 14ª conta, memo_program (restrita address = memo::ID) — Deposit não. Um Withdraw de 13 contas falha na desserialização do Anchor, então o LP não pode sair. Matemática
Pós-condições
  • lp_supply -= lp_token_amount.
  • Vaults enviam out_token_0 / out_token_1 (bruto; o usuário recebe líquido de qualquer taxa de transferência Token-2022).

SwapBaseInput

Swap de entrada exata. Argumentos
Contas A ordenação entrada → saída é pela direção do usuário, não pelo token_0 / token_1 canônico do pool. O programa descobre qual vault é qual combinando mints. Matemática — veja products/cpmm/math. Pré-condições
  • open_time <= now.
  • pool_status permite swap.
  • Nenhum mint pausado ou congelado para essa autoridade.
  • amount_in > 0.
Erros comuns
  • ExceededSlippage — amount_out < minimum_amount_out.
  • ZeroTradingTokens — o trade arredonda para zero.
  • NotApproved — pool está pausado para swaps via UpdatePoolStatus.
  • InvalidInput — mints não correspondem a nenhum dos mints do vault do pool.

SwapBaseOutput

Swap de saída exata. Argumentos
Contas — mesmas que SwapBaseInput. Matemática — curva inversa com teto, veja products/cpmm/math. Erros comuns — ExceededSlippage (gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.

CollectProtocolFee

Coleta taxas de protocolo acumuladas dos vaults para o destino do protocolo. Argumentos — nenhum. Contas Efeito
Nenhuma mudança nos saldos efetivos da curva (taxas acumuladas já foram excluídas). Erro comum — InvalidOwner (6001) se o assinante não é nem amm_config.protocol_owner nem o admin do programa. (Não há NotApproved nesse caminho.)

CollectFundFee

Mesma forma que CollectProtocolFee mas assinado por amm_config.fund_owner — ou, novamente, o admin do programa — e zerando os contadores fund_fees_*. Mesmo InvalidOwner em um assinante errado.

CollectCreatorFee

Assinado por pool_state.pool_creator. Ele liquida a taxa de criador acumulada e transfere a parte do criador para as contas de token do criador. Argumentos — nenhum. Contas Efeito
A participação do protocolo nunca sai do vault aqui — é re-rotulada como uma taxa de protocolo e aguarda CollectProtocolFee. Ambos os contadores já foram excluídos da visão da curva do vault, então o preço do pool não se move. Derivação completa em products/cpmm/fees. Erros comuns — NoFeeCollect quando ambos os contadores de criador são zero (verificado antes da divisão), InvalidInput (6003) se o share_rate resolvido excede 1_000_000, MathOverflow (6011) se registrar a participação causaria overflow em protocol_fees_token_*, e erro ConstraintSeeds do Anchor se creator_fee_share não é o PDA canônico.

CollectCreatorFeePermissionless

Qualquer um pode disparar a coleta de taxa de criador. A instrução sempre envia a parte do criador para as contas de token associadas canônicas possuídas por pool_state.pool_creator; o chamador não pode escolher outro criador ou destino. Se qualquer ATA estiver faltando, o pagador financia sua criação. O CollectCreatorFee original permanece chamável, então um criador que quer assinar sua própria coleta ainda pode. Argumentos — nenhum. Contas
As duas novas contas são anexadas após system_program, não inseridas. Cada conta de payer até system_program mantém a posição que tinha antes da atualização, então a quebra é limpa: uma transação construída contra o layout de quatorze contas anterior à atualização não malinterpreta um vault como um config — ela simplesmente passa contas de menos e o Anchor a rejeita com AccountNotEnoughKeys (3005) antes de qualquer restrição ser executada. As contas continuam obrigatórias, então anexe ambas e atualize o IDL; não há caminho de compatibilidade para o layout antigo.
Efeito — idêntico a CollectCreatorFee acima: a participação é resolvida de creator_fee_share ou amm_config, a parte do protocolo é registrada em protocol_fees_token_{0,1}, a parte do criador é transferida para os ATAs do criador, ambos os contadores de criador são zerados, e recent_epoch é atualizado. Retorna NoFeeCollect quando ambos os contadores são zero.

UpdatePoolStatus

Pausa ou retoma operações individuais em um pool. O campo status é um bitmask: Argumentos
Contas A chave de admin é uma pubkey compilada no programa (crate::admin::ID), não a autoridade de upgrade BPF — alterá-la requer uma atualização de programa. Veja reference/program-addresses para o valor e security/admin-and-multisig para quem a mantém.

CreateAmmConfig

Cria um novo nível de taxa. Argumentos
Contas Pré-condições
  • Nenhuma AmmConfig existente com o mesmo index.
  • protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
Alterado em 2026-09: os proprietários de taxa da nova config não vêm mais do assinante. create_amm_config agora escreve o protocol_fee_owner::ID codificado do programa em protocol_owner e fund_fee_owner::ID em fund_owner, em vez de copiar a chave do assinante de admin em ambos. Os endereços estão em reference/program-addresses.Consequências: taxas em uma AmmConfig recém-criada vão para as carteiras de taxa dedicadas em vez da do admin. O admin permanece um assinante aceito para coleta — CollectProtocolFee / CollectFundFee aceitam amm_config.protocol_owner / fund_owner ou crate::admin::ID — então nada tem que ser rotacionado para varrer; o que mudou é apenas para onde os rendimentos vão por padrão. Contas AmmConfig existentes não são reescritas — o que quer que esteja armazenado nelas ainda governa, então sempre leia protocol_owner / fund_owner da conta em vez de assumir qualquer valor. Os parâmetros 3 e 4 de UpdateAmmConfig ainda os rotacionam.

UpdateAmmConfig

Altera taxas ou propriedade em uma AmmConfig existente. Recebe um param: u8 (qual campo atualizar) e um value: u64. A tabela de despacho completa:
  • param = 0 → trade_fee_rate (afirma trade_fee_rate + creator_fee_rate < 1_000_000)
  • param = 1 → protocol_fee_rate (afirma ≤ 1_000_000 e + fund_fee_rate ≤ 1_000_000)
  • param = 2 → fund_fee_rate (afirma ≤ 1_000_000 e + protocol_fee_rate ≤ 1_000_000)
  • param = 3 → protocol_owner. A nova chave não está em value: anexe-a como remaining_accounts[0] (somente leitura é ok). Não deve ser a pubkey padrão, e omitir a conta entra em pânico em um unwrap().
  • param = 4 → fund_owner. Mesmo mecanismo que 3.
  • param = 5 → create_pool_fee
  • param = 6 → disable_create_pool (qualquer value não-zero desabilita)
  • param = 7 → creator_fee_rate (afirma creator_fee_rate + trade_fee_rate < 1_000_000)
  • param = 8 → creator_fee_share_rate (afirma ≤ 1_000_000). Adicionado em 2026-09-19. A participação padrão do protocolo da taxa de criador nesse nível; veja products/cpmm/fees. Não está relacionado a protocol_fee_rate, que divide a taxa de trade.
Qualquer outro param retorna InvalidInput. As mudanças são assinadas pelo admin e afetam cada pool vinculado a essa AmmConfig no próximo swap. Sem migração; pools simplesmente leem os novos valores.

CreateCreatorFeeShare

Define uma participação de protocolo personalizada da taxa de criador para um par (creator, amm_config), substituindo AmmConfig.creator_fee_share_rate para cada pool que esse criador possui nesse nível de taxa. Adicionado na atualização de compartilhamento de taxa de criador 2026-09-19. Argumentos
Contas Pré-condições
  • share_rate <= 1_000_000, caso contrário InvalidInput (6003).
  • O PDA não deve existir já — o init do Anchor falha em uma segunda chamada para o mesmo par. Para alterar uma taxa, feche a conta e crie-a novamente.
Pós-condições
  • creator_fee_share armazena bump, creator, amm_config e share_rate.
  • Cada CollectCreatorFee / CollectCreatorFeePermissionless subsequente em um pool criado por creator sob amm_config resolve a participação dessa conta em vez da config.
O criador do pool não é parte dessa instrução e não a assina. A taxa é lida no momento da coleta, então uma substituição criada após as taxas já terem acumulado se aplica a esse saldo acumulado também.

CloseCreatorFeeShare

Remove a substituição. O par volta para AmmConfig.creator_fee_share_rate. Argumentos — nenhum. Contas Pós-condições
  • A conta é fechada e seus lamports vão para owner.
  • Coletas para esse par resolvem a participação de amm_config.creator_fee_share_rate novamente — que é 0 a menos que um admin tenha definido o parâmetro 8 de UpdateAmmConfig.

CollectExcessLamports

Varredura de admin de lamports sentados acima do mínimo isento de aluguel em contas que CPMM controla. Adicionado na atualização 2026-09 para que o protocolo possa recuperar o sobre-financiamento que a redução de aluguel SIMD-0437 deixa para trás em contas criadas antes de cada passo. Apenas o excesso se move. Saldos de token, dados de conta, proprietários, estado do pool e a curva não são tocados, e a instrução é um no-op contra uma conta já em seu mínimo — então é seguro re-executar após cada passo de rollout. Argumentos — nenhum. Contas
Correção de ordenação, 2026-09-19. O programa agora faz duas passagens sobre remaining_accounts — cada CPI do programa de token primeiro, depois os débitos diretos de PDAs de propriedade de CPMM. Intercalá-los abortava com o UnbalancedInstruction do runtime (“soma dos saldos de conta antes e depois da instrução não correspondem”) sempre que um PDA era debitado antes de um CPI, porque as mudanças de lamport pendentes do chamador são apenas liberadas em contas que um CPI realmente carrega. Chamadores não têm que agrupar ou ordenar a lista eles mesmos.
Como cada conta de origem é tratada O programa despacha no owner da conta de origem: Porque recebe uma lista remaining_accounts ilimitada, o tamanho da transação é o limite real — a mesma restrição que a varredura do lado da carteira descrita em solana-fundamentals/rent-and-reclaimable-rent. Erros comuns — InvalidOwner (6001, assinante errado), LamportsCalculateError (6015, a volta redonda wSOL não resultou em zero), e InsufficientFunds do caminho de propriedade do programa quando uma conta mantém menos que seu próprio mínimo de aluguel. Sem builder SDK. @raydium-io/raydium-sdk-v2 não envia um builder para essa instrução, e nem o repo raydium-sdk-V2-demo — é um caminho de admin. Codifique-a à mão, da forma que a varredura do lado da carteira em solana-fundamentals/rent-and-reclaimable-rent faz para a instrução do programa de token.

Matriz de mudança de estado

Para onde ir a seguir

Fontes: