Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →
O ID do programa e as seeds das PDAs para CPMM estão listados canonicamente em
reference/program-addresses. Esta página se concentra em para que serve cada conta e os invariantes que ela mantém, não nos endereços codificados.As seis contas de um pool CPMM
Cada pool CPMM é totalmente descrito por seis endereços derivados do programa (PDAs) sob o programa CPMM, mais uma contaAmmConfig compartilhada que ele referencia. Uma vez que você tenha os dois mints, pode derivar tudo deterministicamente sem tocar na rede.
E a configuração compartilhada:
E uma conta opcional por criador:
Derivando um pool a partir de nada além de dois mints
O ID do pool nem sempre é a PDA canônica.
Initialize aceita um keypair signatário arbitrário como pool_state além da PDA acima. Se a conta passada não corresponder à PDA canônica, o programa exige que seja um signatário — ou seja, o criador passa um keypair novo que assina. Esta é a defesa contra front-run: qualquer terceiro correndo para pegar a PDA canônica pode ser contornado pelo criador legítimo usando um keypair aleatório. As PDAs downstream (lpMint, vault0, vault1, observation) ainda são derivadas de poolState.key(), então permanecem únicas para qualquer endereço usado. Quando você indexa pools, sempre descubra o ID do pool a partir do estado on-chain (por exemplo, contas PoolState sob o programa CPMM), não derivando a PDA canônica — a última perderá pools com keypair aleatório.Layouts de conta
As definições completas em Rust vivem na fonteraydium-cp-swap. Os campos abaixo são os que você lerá de uma integração.
PoolState
lp_supply— o total de LP interno do pool. Não é igual ao suprimento do mint de LP: é exatamente 100 unidades base mais alto, porque as 100 unidades bloqueadas são contadas aqui mas nunca são mintadas. Toda a matemática de compartilhamento de LP (depósito, saque) divide porlp_supply, então use este campo e não substitua o suprimento on-chain do mint.protocol_fees_token{0,1},fund_fees_token{0,1}— taxas acumuladas ainda não varridas. Estas não afetam o preço do swap; ficam nos vaults até queCollectProtocolFee/CollectFundFeeseja chamado.protocol_fees_token{0,1}também recebe a parte do protocolo da taxa de criador quando uma taxa de criador é coletada, então cresce fora dos swaps — vejaproducts/cpmm/fees.status— um bitmask controlando seSwap,Deposit,Withdrawsão permitidos. Atualizado pelo admin viaUpdatePoolStatus. O SDK verifica isso antes de construir uma transação; se você está fazendo CPI diretamente, verifique você mesmo.token0_program/token1_program— o programa de token para fazer CPI para cada vault. Um pode ser SPL Token clássico e o outro Token-2022; são independentes.open_time— um timestamp Unix. Swaps antes desta hora falham. Depósitos são permitidos antes deopen_timepara que o pool possa ser semeado.creator_fee_on/enable_creator_fee— juntos controlam se a taxa de criador opcional está ativa para este pool e de qual lado do swap ela é coletada.enable_creator_fee == falsezera o caminho de taxa de criador inteiramente. Quando habilitado,creator_fee_onseleciona:0= pegar taxa de qualquer token que seja a entrada do swap (BothToken);1= pegar taxa detoken_0apenas (pular em swapstoken_1 → token_0);2= pegar taxa detoken_1apenas. Definido na criação do pool viaInitializeWithPermission; não pode mudar depois.creator_fees_token_{0,1}— taxas de criador acumuladas, varridas porCollectCreatorFeeouCollectCreatorFeePermissionless. Ambos os caminhos zeram os contadores completos, mas desde a atualização de compartilhamento de taxa de criador de 2026-09-19 apenas parte do saldo sai do pool: a parte do protocolo é adicionada aprotocol_fees_token_{0,1}e o restante é transferido para o criador. O caminho sem permissão fixa os destinatários para as ATAs canônicas depool_creator.PoolStateem si não mudou — não há contador separado para o valor compartilhado.
AmmConfig
trade_fee_rateecreator_fee_ratesão frações do volume, ambas denominadas em unidades de1/1_000_000.2500significa 0,25% do volume de trade.protocol_fee_rateefund_fee_ratesão frações da taxa de trade (não do volume), no mesmo denominador1/1_000_000. A taxa de criador não é uma fração da taxa de trade — é sua própria taxa independente. A aritmética completa está emproducts/cpmm/fees.indexé umu16, então a seed hash usa 2 bytes big-endian. Erro de um byte na ordem de bytes é um bug de integração comum.AmmConfigé imutável no nível do pool. Um pool aponta para umAmmConfigna criação e nunca muda. Mudanças de taxa se propagam porque o pool lê a configuração a cada swap — mas o pool não pode ser movido entre tiers de taxa.
creator_fee_rate) vive em AmmConfig e é compartilhada entre o tier de taxa. Se um pool particular realmente a cobra (enable_creator_fee) e de qual lado do swap ela cai (creator_fee_on) vivem em PoolState. A taxa de criador é independente da taxa de trade — é sua própria taxa, acumulada em seus próprios contadores (creator_fees_token_{0,1}), e nunca reduz as partes de LP / protocolo / fundo da taxa de trade. A varredura é via CollectCreatorFee ou a CollectCreatorFeePermissionless restrita por destino, e ambos os caminhos entregam uma parte do saldo acumulado ao protocolo no caminho — em creator_fee_share_rate, ou na taxa em uma PDA CreatorFeeShare quando uma existe para esse par (creator, amm_config). Veja products/cpmm/fees para a mecânica completa.
Permission
Uma pequena conta de controle de acesso usada por InitializeWithPermission. O programa CPMM suporta um caminho de criação de pool com permissão para que outros programas (por exemplo, LaunchLab ao graduar um token para CPMM) possam provar que têm direito de criar um pool contra um determinado AmmConfig.
CreatePermissionPda pelo admin do CPMM ou por uma autoridade dedicada de criador de PDA de permissão. Desde a atualização de 2026-09, ClosePermissionPda aceita os mesmos dois signatários; antes era apenas admin. Usuários finais não interagem com esta conta diretamente — é encanamento para fluxos entre programas. Veja security/admin-and-multisig para o limite de função e reference/program-addresses para endereços canônicos.
CreatorFeeShare
Uma conta opcional que substitui a parte do protocolo da taxa de criador para um par (criador de pool, AmmConfig). Adicionado pela atualização de compartilhamento de taxa de criador de 2026-09-19.
- É opcional, mas a conta nunca é opcional na instrução.
CollectCreatorFeeeCollectCreatorFeePermissionlessambas declaramcreator_fee_sharecom a restrição de seed acima e a levam em cada chamada. O programa então verifica se a conta está vazia ou de propriedade estrangeira; se assim for, volta paraAmmConfig.creator_fee_share_rate. Então um cliente deve sempre derivar e passar o endereço, independentemente de a conta existir ou não. share_rateé limitado aFEE_RATE_DENOMINATOR_VALUE(1_000_000) na criação, e novamente quando a divisão é executada.1_000_000roteia toda a taxa de criador para o protocolo;0não roteia nada.- Criado e fechado pelo admin ou uma autoridade dedicada através de
CreateCreatorFeeShare/CloseCreatorFeeShare. Fechá-lo retorna o aluguel ao signatário e volta o par para o padrão da configuração; o criador do pool não é um signatário em nenhum caminho. - É codificado no criador, não no pool. Uma conta governa cada pool que o criador tem naquele
AmmConfig. Um criador com pools em dois tiers de taxa precisa de duas contas para ser coberto em ambos.
products/cpmm/fees.
Vaults e Token-2022
vault0 e vault1 são propriedade da PDA de autoridade do CPMM, e seu proprietário de programa de token (token_program) é SPL Token ou Token-2022, determinado na criação do pool pelo programa do mint. O pool lida com os dois casos de forma transparente — você passa o ID correto do programa de token para cada lado nas contas de instrução Swap / Deposit / Withdraw.
CPMM impõe uma lista de permissões de extensão rigorosa na criação do pool (is_supported_mint em utils/token.rs). Um mint Token-2022 pode ser usado em um pool CPMM apenas se cada extensão que ele carrega estiver nesta lista:
TransferFeeConfig. Aplicado pelo mint em cada transferência. O pool está no lado receptor para depósitosSwapBaseInpute no lado de envio para saques. O programa calcula o valor líquido chegando ao vault e define a curva de acordo. Vejaalgorithms/token-2022-transfer-fees.MetadataPointereTokenMetadata. Metadados padrão on-mint. Sem efeito na matemática de swap.InterestBearingConfig. O valor de UI do mint acumula juros. O vault armazena valores brutos; a curva opera apenas em valores brutos. UIs que mostram APR devem chamar os helpers Token-2022 para renderizar o valor de UI.ScaledUiAmount. Extensão de escala de exibição de UI. Mesmo tratamento queInterestBearingConfig— a curva usa valores brutos.
PermanentDelegate, TransferHook, DefaultAccountState, NonTransferable, ConfidentialTransfer, Group/GroupMember, MintCloseAuthority, etc. — causa Initialize rejeitar com NotSupportMint. A única exceção é um registro por mint: se uma PDA SupportMintAssociated existe na seed [b"support_mint", mint], o mint é admitido independentemente de seu conjunto de extensões. Essa PDA é criada e removida pelo admin (ou uma autoridade dedicada de suporte de mint) através de CreateSupportMintAssociated / CloseSupportMintAssociated, então integrar um mint específico não precisa mais de uma atualização de programa.
Mudado em 2026-09. CPMM anteriormente também carregava uma
MINT_WHITELIST de quatro endereços codificada que contornava a verificação de extensão. Esse array foi removido; a PDA de registro é agora o único bypass. Qualquer mint que estava contando com a lista codificada precisa de uma PDA SupportMintAssociated antes que um novo pool possa ser criado para ele — pools existentes não são afetados, porque a verificação é executada apenas na criação do pool.programs/cp-swap/src/utils/token.rs e pode mudar com futuras atualizações de programa. Veja reference/token-2022-support para a matriz entre programas.
Observation
A conta de observação é um ring buffer de entradasObservationState, cada uma armazenando um block_timestamp e um preço cumulativo. Em cada swap, o programa anexa uma nova observação se tempo suficiente passou desde a última. TWAPs são calculados lendo duas observações e dividindo Δcumulative / Δtime.
8 + 16 + 16), então o array sozinho tem 4.000 bytes; ObservationState::LEN é exatamente 4.075 bytes (8 + 1 + 2 + 32 + 4.000 + 8 × 4).
Duas regras de consumidor:
- Não use uma única observação como preço. É um cumulativo, não um preço spot. Use duas delas para calcular um TWAP.
- Escolha observações com pelo menos um bloco de distância. Swaps dentro do mesmo bloco podem não produzir uma nova observação; ler de volta a trás pode retornar o mesmo registro.
products/clmm/accounts.
Ciclo de vida da conta
Pools CPMM e suas PDAs nunca são fechados.
Permission, SupportMintAssociated e CreatorFeeShare são as exceções — são registros autônomos gerenciados por admin, não estado do pool, e cada um tem uma instrução de fechamento explícita. Mesmo com liquidez zero, o poolState permanece. Isto é deliberado: resemear o mesmo pool depois preserva seu buffer de observação histórico e sua derivação de PDA permanece estável.
O que ler onde
- Listas de contas de instrução (qual dos acima é gravável/signatário para cada instrução):
products/cpmm/instructions. - Semântica de acúmulo de taxa:
products/cpmm/fees. - Matemática de swap / regra de atualização de observação:
products/cpmm/math. - Seeds canônicas / IDs de programa:
reference/program-addresses.

