> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Contas do CPMM

> Cada PDA e conta compartilhada que um pool CPMM toca: PoolState, AmmConfig, autoridade, mint de LP, vaults de token e o ring buffer de observação.

<Info>
  **Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.**

  [Ver versão em inglês →](/products/cpmm/accounts)
</Info>

A ID do programa e as sementes de PDA para CPMM estão listadas canonicamente em [`reference/program-addresses`](/pt/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 hardcoded.

## As seis contas de um pool CPMM

Cada pool CPMM é totalmente descrito por seis endereços derivados do programa (PDAs) sob o programa CPMM, além de uma conta `AmmConfig` compartilhada que ele referencia. Uma vez que você tenha os dois mints, pode derivar tudo de forma determinística sem tocar na rede.

| Conta         | Seed(s)                                                                                                       | Proprietário           | Propósito                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authority`   | `"vault_and_lp_mint_auth_seed"`                                                                               | CPMM                   | O signatário para cada movimento de vault e cada mint/burn de LP. Compartilhado entre **todos** os pools CPMM.                                                                                                                                                                                                                                                                                                                                                |
| `poolState`   | `"pool"`, `ammConfig`, `token0Mint`, `token1Mint` **ou** qualquer keypair aleatória fornecida pelo signatário | CPMM                   | A struct de estado do pool — par de mints, saldos de vault, fornecimento de LP, acúmulo de taxas, ponteiro de observação. A instrução `Initialize` do CPMM aceita tanto o PDA canônico derivado das quatro sementes **quanto** um keypair arbitrário assinado pelo criador. O caminho de keypair aleatória existe para derrotar um ataque de front-running onde um adversário observa o mempool e corre para ocupar o PDA canônico antes do criador legítimo. |
| `lpMint`      | `"pool_lp_mint"`, `poolState`                                                                                 | SPL Token              | O token LP do pool. Fornecimento = total de LP em aberto. Autoridade de mint = PDA de autoridade CPMM.                                                                                                                                                                                                                                                                                                                                                        |
| `vault0`      | `"pool_vault"`, `poolState`, `token0Mint`                                                                     | SPL Token / Token-2022 | Mantém o saldo token0 do pool. Possuído pelo PDA de autoridade.                                                                                                                                                                                                                                                                                                                                                                                               |
| `vault1`      | `"pool_vault"`, `poolState`, `token1Mint`                                                                     | SPL Token / Token-2022 | Mantém o saldo token1 do pool. Possuído pelo PDA de autoridade.                                                                                                                                                                                                                                                                                                                                                                                               |
| `observation` | `"observation"`, `poolState`                                                                                  | CPMM                   | Ring buffer de amostras de preço usadas para o TWAP. Escrito em cada swap.                                                                                                                                                                                                                                                                                                                                                                                    |

E a configuração compartilhada:

| Conta       | Seed(s)                      | Proprietário | Propósito                                                                                                                                                   |
| ----------- | ---------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ammConfig` | `"amm_config"`, `index: u16` | CPMM         | Mantém as taxas de trade/protocolo/fundo/criador e chaves de admin. Uma por "faixa de taxa". Poolstate vincula-se a uma na criação e não pode mudar depois. |

## Derivando um pool de nada além de dois mints

```ts theme={null}
import { PublicKey } from "@solana/web3.js";
import BN from "bn.js";

const CPMM_PROGRAM_ID = new PublicKey(
  "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"
); // mainnet — see reference/program-addresses

function u16ToBytes(n: number): Buffer {
  const b = Buffer.alloc(2);
  b.writeUInt16BE(n);
  return b;
}

// token0 < token1 by byte order. Getting this wrong yields a valid PDA
// that points at a nonexistent pool.
function sortMints(a: PublicKey, b: PublicKey): [PublicKey, PublicKey] {
  return Buffer.compare(a.toBuffer(), b.toBuffer()) < 0 ? [a, b] : [b, a];
}

export function deriveCpmmAccounts(
  mintA: PublicKey,
  mintB: PublicKey,
  ammConfigIndex = 0,
) {
  const [token0Mint, token1Mint] = sortMints(mintA, mintB);

  const [ammConfig] = PublicKey.findProgramAddressSync(
    [Buffer.from("amm_config"), u16ToBytes(ammConfigIndex)],
    CPMM_PROGRAM_ID,
  );
  const [authority] = PublicKey.findProgramAddressSync(
    [Buffer.from("vault_and_lp_mint_auth_seed")],
    CPMM_PROGRAM_ID,
  );
  const [poolState] = PublicKey.findProgramAddressSync(
    [
      Buffer.from("pool"),
      ammConfig.toBuffer(),
      token0Mint.toBuffer(),
      token1Mint.toBuffer(),
    ],
    CPMM_PROGRAM_ID,
  );
  const [lpMint] = PublicKey.findProgramAddressSync(
    [Buffer.from("pool_lp_mint"), poolState.toBuffer()],
    CPMM_PROGRAM_ID,
  );
  const [vault0] = PublicKey.findProgramAddressSync(
    [Buffer.from("pool_vault"), poolState.toBuffer(), token0Mint.toBuffer()],
    CPMM_PROGRAM_ID,
  );
  const [vault1] = PublicKey.findProgramAddressSync(
    [Buffer.from("pool_vault"), poolState.toBuffer(), token1Mint.toBuffer()],
    CPMM_PROGRAM_ID,
  );
  const [observation] = PublicKey.findProgramAddressSync(
    [Buffer.from("observation"), poolState.toBuffer()],
    CPMM_PROGRAM_ID,
  );

  return {
    ammConfig,
    authority,
    poolState,
    lpMint,
    token0Mint,
    token1Mint,
    vault0,
    vault1,
    observation,
  };
}
```

<Tip>
  **Sempre ordene os mints antes de derivar o PDA do pool.** A seed faz hash dos dois mints em ordem de bytes, não em ordem do usuário. Dois pools com `(A, B)` e `(B, A)` entrariam em colisão na cadeia — a ordenação é como o programa torna o mapeamento canônico.
</Tip>

<Note>
  **Pool ID nem sempre é o PDA canônico.** `Initialize` aceita um keypair signatário arbitrário como `pool_state` além do PDA acima. Se a conta passada não corresponder ao PDA canônico, o programa requer 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 agarrar o PDA canônico pode ser contornado pelo criador legítimo usando um keypair aleatório. Os PDAs posteriores (`lpMint`, `vault0`, `vault1`, `observation`) ainda são derivados de `poolState.key()`, então permanecem únicos para qualquer endereço usado. Ao indexar pools, sempre descubra o pool ID a partir do estado na cadeia (por exemplo, contas `PoolState` sob o programa CPMM), não derivando o PDA canônico — o último perderá pools com keypair aleatório.
</Note>

## Layouts de contas

As definições Rust completas vivem na fonte [`raydium-cp-swap`](https://github.com/raydium-io/raydium-cp-swap). Os campos abaixo são aqueles que você lerá de uma integração.

### `PoolState`

```rust theme={null}
// programs/cp-swap/src/states/pool.rs
pub struct PoolState {
    pub amm_config: Pubkey,               // binds this pool to an AmmConfig
    pub pool_creator: Pubkey,             // who ran initialize
    pub token_0_vault: Pubkey,            // == vault0 PDA
    pub token_1_vault: Pubkey,            // == vault1 PDA

    pub lp_mint: Pubkey,
    pub token_0_mint: Pubkey,
    pub token_1_mint: Pubkey,

    pub token_0_program: Pubkey,          // SPL Token or Token-2022 program
    pub token_1_program: Pubkey,

    pub observation_key: Pubkey,          // == observation PDA
    pub auth_bump: u8,
    pub status: u8,                       // bitmask: deposit | withdraw | swap
    pub lp_mint_decimals: u8,
    pub mint_0_decimals: u8,
    pub mint_1_decimals: u8,

    pub lp_supply: u64,                   // mirrors lp_mint supply
    pub protocol_fees_token_0: u64,
    pub protocol_fees_token_1: u64,
    pub fund_fees_token_0: u64,
    pub fund_fees_token_1: u64,

    pub open_time: u64,                   // unix; swaps rejected before this
    pub recent_epoch: u64,

    // Creator-fee state (added after the original layout):
    pub creator_fee_on: u8,               // 0=BothToken, 1=OnlyToken0, 2=OnlyToken1
    pub enable_creator_fee: bool,
    pub padding1: [u8; 6],
    pub creator_fees_token_0: u64,
    pub creator_fees_token_1: u64,

    pub padding: [u64; 28],
}
```

O que realmente ler:

* **`lp_supply`** — o espelho interno do pool do fornecimento total do mint de LP. Use para matemática de compartilhamento de LP; o valor deve corresponder ao fornecimento na cadeia do mint, mas lê-lo de `PoolState` evita uma busca de conta extra.
* **`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; elas ficam nos vaults até que `CollectProtocolFee` / `CollectFundFee` seja chamado.
* **`status`** — uma máscara de bits controlando se `Swap`, `Deposit`, `Withdraw` são permitidos. Atualizado pelo admin via `UpdatePoolStatus`. O SDK verifica isto antes de construir uma transação; se você estiver CPIando diretamente, verifique por si mesmo.
* **`token0_program` / `token1_program`** — o programa de token para CPI em cada vault. Um pode ser SPL Token clássico e o outro Token-2022; eles são independentes.
* **`open_time`** — um timestamp Unix. Swaps antes desta hora falham. Depósitos são permitidos antes de `open_time` para que o pool possa ser inicializado.
* **`creator_fee_on` / `enable_creator_fee`** — juntos controlam se a taxa de criador opcional está ativa para este pool e de que lado do swap ela é coletada. `enable_creator_fee == false` zera o caminho de taxa do criador completamente. Quando ativado, `creator_fee_on` seleciona: `0` = cobrar taxa de qualquer token que seja a entrada do swap (`BothToken`); `1` = cobrar taxa apenas de `token_0` (pular em swaps `token_1 → token_0`); `2` = cobrar taxa apenas de `token_1`. Definido na criação do pool via `InitializeWithPermission`; não pode mudar depois.
* **`creator_fees_token_{0,1}`** — taxas de criador acumuladas, varridas por `CollectCreatorFee`.

### `AmmConfig`

```rust theme={null}
pub struct AmmConfig {
    pub bump: u8,
    pub disable_create_pool: bool,
    pub index: u16,                       // matches the seed
    pub trade_fee_rate: u64,              // e.g., 2500 = 0.25%
    pub protocol_fee_rate: u64,           // fraction of trade fee to protocol
    pub fund_fee_rate: u64,               // fraction of trade fee to fund
    pub create_pool_fee: u64,             // paid once at init (in SOL or token)
    pub protocol_owner: Pubkey,           // can call CollectProtocolFee
    pub fund_owner: Pubkey,               // can call CollectFundFee
    pub creator_fee_rate: u64,            // optional pool-creator fee rate (1/1_000_000 of volume)
    pub padding: [u64; 15],
}
```

Três coisas para ter cuidado:

1. **`trade_fee_rate` e `creator_fee_rate` são frações de volume**, ambas denominadas em unidades de `1/1_000_000`. `2500` significa 0,25% do volume de trade. **`protocol_fee_rate` e `fund_fee_rate` são frações da *taxa de trade*** (não de volume), no mesmo denominador `1/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á em [`products/cpmm/fees`](/pt/products/cpmm/fees).
2. **`index` é um `u16`**, então a seed hash usa 2 bytes big-endian. Um erro de um byte na ordem dos bytes é um bug de integração comum.
3. **`AmmConfig` é imutável no nível do pool.** Um pool aponta para um `AmmConfig` na criação e nunca muda. As 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 faixas de taxa.

Uma observação sobre taxas de criador: a **taxa** em si (`creator_fee_rate`) vive em `AmmConfig` e é compartilhada entre a faixa de taxa. Se um pool específico realmente a cobra (`enable_creator_fee`) e de que 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 os compartilhamentos LP / protocolo / fundo da taxa de trade. Varrer é via `CollectCreatorFee`. Veja [`products/cpmm/fees`](/pt/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 estão autorizados a criar um pool contra um determinado `AmmConfig`.

```rust theme={null}
pub struct Permission {
    pub authority: Pubkey,    // who is allowed to call InitializeWithPermission
    pub padding: [u64; 8],
}
```

O PDA de Permission é criado pelo admin do CPMM via `CreatePermissionPda` e revogado via `ClosePermissionPda`. Usuários finais não interagem com esta conta diretamente — é encanamento para fluxos entre programas.

### Vaults e Token-2022

`vault0` e `vault1` são possuídos pelo 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`.

O 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 fica no lado receptivo para depósitos `SwapBaseInput` e no lado emissor para saques. O programa calcula o **valor líquido** aterrando no vault e define a curva de acordo. Veja [`algorithms/token-2022-transfer-fees`](/pt/algorithms/token-2022-transfer-fees).
* **`MetadataPointer`** e **`TokenMetadata`.** Metadados padrão de mint. Nenhum efeito na matemática de swap.
* **`InterestBearingConfig`.** O valor de UI do mint acumula juros. O vault armazena quantidades brutas; a curva opera apenas em quantidades brutas. 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 que `InterestBearingConfig` — a curva usa quantidades brutas.

Qualquer outra extensão — `PermanentDelegate`, `TransferHook`, `DefaultAccountState`, `NonTransferable`, `ConfidentialTransfer`, `Group`/`GroupMember`, `MintCloseAuthority`, etc. — causa que `Initialize` rejeite com `NotSupportMint`. A exceção é uma pequena **lista de mints hardcoded** no programa (um punhado de pubkeys específicas) que contorna a verificação de extensão; é usada para integrar mints específicas caso a caso.

A lista de extensões verificadas e a lista de mints whitelist vivem na fonte CP-Swap sob `programs/cp-swap/src/utils/token.rs` e podem mudar com futuras atualizações de programa.

### Observation

A conta de observação é um ring buffer de entradas `ObservationState`, cada uma armazenando um `block_timestamp` e um **preço cumulativo**. Em cada swap o programa adiciona uma nova observação se tempo suficiente passou desde a última. TWAPs são calculados lendo duas observações e dividindo `Δcumulative / Δtime`.

```rust theme={null}
// OBSERVATION_NUM is hardcoded in the program to 100.
pub const OBSERVATION_NUM: usize = 100;

pub struct Observation {
    pub block_timestamp:              u64,
    pub cumulative_token_0_price_x32: u128,   // Q32.32, top 64 bits left for overflow
    pub cumulative_token_1_price_x32: u128,
}

pub struct ObservationState {
    pub initialized:           bool,
    pub observation_index:     u16,                            // circular index
    pub pool_id:               Pubkey,
    pub observations:          [Observation; OBSERVATION_NUM], // 100 entries
    pub last_update_timestamp: u64,                            // timestamp of the most recent append
    pub padding:               [u64; 3],
}
```

O ring buffer é dimensionado para **100 observações**. Cada observação tem 40 bytes, então o array sozinho tem 4.000 bytes; o PDA `ObservationState` completo tem cerca de 4.100 bytes após os campos circundantes e o discriminador.

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 pelo menos um bloco separado.** Swaps no mesmo bloco podem não produzir uma nova observação; leitura back-to-back pode retornar o mesmo registro.

Mais matemática em [`products/clmm/accounts`](/pt/products/clmm/accounts).

## Ciclo de vida da conta

| Evento               | Contas criadas                                           | Contas destruídas |
| -------------------- | -------------------------------------------------------- | ----------------- |
| `Initialize`         | `poolState`, `lpMint`, `vault0`, `vault1`, `observation` | —                 |
| `Deposit`            | — (pode criar ATA de LP do usuário)                      | —                 |
| `Withdraw`           | —                                                        | —                 |
| `Swap`               | — (pode criar ATA de destino do usuário)                 | —                 |
| `CollectProtocolFee` | —                                                        | —                 |
| `CollectFundFee`     | —                                                        | —                 |
| `UpdatePoolStatus`   | —                                                        | —                 |

Pools CPMM e seus PDAs **nunca são fechados**. Mesmo com liquidez zero o `poolState` permanece. Isto é intencional: reinicializar 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`](/pt/products/cpmm/instructions).
* **Semântica de acúmulo de taxas**: [`products/cpmm/fees`](/pt/products/cpmm/fees).
* **Matemática de swap / regra de atualização de observação**: [`products/cpmm/math`](/pt/products/cpmm/math).
* **Sementes canônicas / IDs de programa**: [`reference/program-addresses`](/pt/reference/program-addresses).

Fontes:

* [`raydium-io/raydium-cp-swap` — PoolState, AmmConfig, ObservationState](https://github.com/raydium-io/raydium-cp-swap)
