> ## 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.

# CPMM-Konten

> Alle PDAs und gemeinsamen Konten, die ein CPMM-Pool berührt: PoolState, AmmConfig, Authority, LP-Mint, Token-Vaults und der Observation-Ringpuffer.

<Info>
  **Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.**

  [Englische Version ansehen →](/products/cpmm/accounts)
</Info>

<Info>
  Programm-ID und PDA-Seeds für CPMM sind kanonisch in [`reference/program-addresses`](/de/reference/program-addresses) aufgelistet. Diese Seite konzentriert sich auf **wofür jedes Konto ist und welche Invarianten es aufrechterhält**, nicht auf die hartcodierten Adressen.
</Info>

## Die sechs Konten eines CPMM-Pools

Jeder CPMM-Pool wird vollständig durch sechs programmabgeleitete Adressen (PDAs) unter dem CPMM-Programm beschrieben, plus ein gemeinsames `AmmConfig`-Konto, auf das er verweist. Sobald Sie die beiden Mints haben, können Sie deterministisch alles ableiten, ohne das Netzwerk zu berühren.

| Konto         | Seed(s)                                                                                                                  | Besitzer               | Zweck                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authority`   | `"vault_and_lp_mint_auth_seed"`                                                                                          | CPMM                   | Der Unterzeichner für jede Vault-Bewegung und jede LP-Mint/Burn. Gemeinsam über **alle** CPMM-Pools.                                                                                                                                                                                                                                                                                                                                                                                               |
| `poolState`   | `"pool"`, `ammConfig`, `token0Mint`, `token1Mint` **oder** beliebiger von Unterzeichner bereitgestellter Zufalls-Keypair | CPMM                   | Die Pool-Status-Struktur — Mintpaar, Vault-Salden, LP-Angebot, Gebührenakkretion, Observation-Pointer. Die CPMM-`Initialize`-Anweisung akzeptiert entweder die kanonische PDA, die aus den vier Seeds abgeleitet wird, **oder** einen beliebigen Keypair, der vom Creator unterzeichnet wird. Der Zufalls-Keypair-Pfad existiert, um einen Front-Running-Angriff zu vereiteln, bei dem ein Gegner den Mempool beobachtet und sich beeilt, die kanonische PDA vor dem legitimen Creator zu belegen. |
| `lpMint`      | `"pool_lp_mint"`, `poolState`                                                                                            | SPL Token              | Der LP-Token des Pools. Angebot = ausstehende LP-Gesamtmenge. Mint-Autorität = die CPMM-Authority-PDA.                                                                                                                                                                                                                                                                                                                                                                                             |
| `vault0`      | `"pool_vault"`, `poolState`, `token0Mint`                                                                                | SPL Token / Token-2022 | Hält den Pool-Saldo von Token0. Im Besitz der Authority-PDA.                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `vault1`      | `"pool_vault"`, `poolState`, `token1Mint`                                                                                | SPL Token / Token-2022 | Hält den Pool-Saldo von Token1. Im Besitz der Authority-PDA.                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `observation` | `"observation"`, `poolState`                                                                                             | CPMM                   | Ringpuffer von Preisproben, die für die TWAP verwendet werden. Wird bei jedem Swap geschrieben.                                                                                                                                                                                                                                                                                                                                                                                                    |

Und die gemeinsame Konfiguration:

| Konto       | Seed(s)                      | Besitzer | Zweck                                                                                                                                                                                        |
| ----------- | ---------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ammConfig` | `"amm_config"`, `index: u16` | CPMM     | Hält die Handels-/Protokoll-/Fonds-/Creator-Gebührensätze und Admin-Schlüssel. Ein pro „Gebührentiers". Poolstate bindet sich bei der Erstellung an einen und kann sich später nicht ändern. |

## Ableitung eines Pools aus nichts als zwei 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>
  **Sortieren Sie Mints immer, bevor Sie die Pool-PDA ableiten.** Der Seed hasht die zwei Mints in Byte-Reihenfolge, nicht in Benutzerreihenfolge. Zwei Pools mit `(A, B)` und `(B, A)` würden sich on-chain kollidieren — Sortieren ist, wie das Programm die Zuordnung kanonisch macht.
</Tip>

<Note>
  **Pool-ID ist nicht immer die kanonische PDA.** `Initialize` akzeptiert einen beliebigen Signer-Keypair als `pool_state` zusätzlich zur obigen PDA. Wenn das übergebene Konto nicht mit der kanonischen PDA übereinstimmt, erfordert das Programm, dass es ein Signer ist — d.h., der Creator übergibt einen frischen Keypair, mit dem sie signieren. Dies ist die Front-Run-Verteidigung: Jede dritte Partei, die sich beeilt, die kanonische PDA zu greifen, kann vom legitimen Creator durch die Verwendung eines Zufalls-Keypairs stattdessen umgangen werden. Die nachgelagerten PDAs (`lpMint`, `vault0`, `vault1`, `observation`) werden immer noch von `poolState.key()` abgeleitet, sodass sie eindeutig für jede verwendete Adresse bleiben. Wenn Sie Pools indexieren, entdecken Sie die Pool-ID immer aus dem on-chain-Status (z.B. `PoolState`-Konten unter dem CPMM-Programm), nicht durch Ableitung der kanonischen PDA — letztere wird Zufalls-Keypair-Pools vermissen.
</Note>

## Konto-Layouts

Die vollständigen Rust-Definitionen befinden sich in der [`raydium-cp-swap`](https://github.com/raydium-io/raydium-cp-swap)-Quelle. Die Felder unten sind diejenigen, die Sie aus einer Integration lesen werden.

### `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],
}
```

Was Sie tatsächlich lesen sollten:

* **`lp_supply`** — der interne Spiegel des Pools des LP-Mints. Verwenden Sie ihn für LP-Anteil-Mathematik; der Wert sollte mit dem Mint's on-chain-Angebot übereinstimmen, aber ihn aus `PoolState` zu lesen, vermeidet einen zusätzlichen Account-Abruf.
* **`protocol_fees_token{0,1}`**, **`fund_fees_token{0,1}`** — *aufgelaufene* Gebühren, die noch nicht eingezogen wurden. Diese beeinflussen nicht die Swap-Preisgestaltung; sie sitzen in den Vaults, bis `CollectProtocolFee` / `CollectFundFee` aufgerufen wird.
* **`status`** — eine Bitmaske, die kontrolliert, ob `Swap`, `Deposit`, `Withdraw` erlaubt sind. Aktualisiert vom Admin über `UpdatePoolStatus`. Das SDK prüft dies, bevor es eine Transaktion erstellt; wenn Sie direkt CPI verwenden, prüfen Sie es selbst.
* **`token0_program` / `token1_program`** — das Token-Programm, in das für jede Vault CPI durchgeführt wird. Das eine kann klassisches SPL Token und das andere Token-2022 sein; sie sind unabhängig.
* **`open_time`** — ein Unix-Zeitstempel. Swaps vor dieser Zeit schlagen fehl. Ablagerungen sind vor `open_time` zulässig, damit der Pool aufgefüllt werden kann.
* **`creator_fee_on` / `enable_creator_fee`** — kontrollieren zusammen, ob die optionale Creator-Gebühr für diesen Pool aktiv ist und auf welcher Seite des Swaps sie eingezogen wird. `enable_creator_fee == false` nullifiziert den Creator-Gebühren-Pfad vollständig. Wenn aktiviert, wählt `creator_fee_on`: `0` = Gebühr vom Token, das der Swap-Input ist (`BothToken`); `1` = Gebühr von `token_0` nur (überspringen bei `token_1 → token_0`-Swaps); `2` = Gebühr von `token_1` nur. Wird bei Pool-Erstellung über `InitializeWithPermission` festgelegt; kann sich später nicht ändern.
* **`creator_fees_token_{0,1}`** — aufgelaufene Creator-Gebühren, eingezogen durch `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],
}
```

Drei Dinge, auf die Sie achten sollten:

1. **`trade_fee_rate` und `creator_fee_rate` sind Bruchteile des Volumens**, beide in Einheiten von `1/1_000_000` ausgedrückt. `2500` bedeutet 0,25% des Swap-Volumens. **`protocol_fee_rate` und `fund_fee_rate` sind Bruchteile der *Handelsgebühr*** (nicht des Volumens), mit dem gleichen Nenner von `1/1_000_000`. Die Creator-Gebühr ist **nicht** ein Bruchteil der Handelsgebühr — sie ist ihre eigene unabhängige Rate. Vollständige Arithmetik in [`products/cpmm/fees`](/de/products/cpmm/fees).
2. **`index` ist ein `u16`**, also verwendet der Seed-Hash 2 Bytes Big-Endian. Ein Byte-Reihenfolge-Fehler um 1 ist ein häufiger Integrationsfehler.
3. **`AmmConfig` ist unveränderlich auf Pool-Ebene.** Ein Pool verweist bei der Erstellung auf ein `AmmConfig` und wechselt nie. Gebührenänderungen werden verteilt, da der Pool die Konfiguration bei jedem Swap liest — aber der Pool kann nicht zwischen Gebührentiers verschoben werden.

Eine Anmerkung zu Creator-Gebühren: die **Rate** selbst (`creator_fee_rate`) lebt auf `AmmConfig` und wird über das Gebührentier geteilt. Ob ein bestimmter Pool sie tatsächlich berechnet (`enable_creator_fee`) und auf welcher Seite des Swaps sie landet (`creator_fee_on`) leben auf `PoolState`. Die Creator-Gebühr ist **unabhängig** von der Handelsgebühr — sie ist ihre eigene Rate, aufgelaufen auf ihren eigenen Zählern (`creator_fees_token_{0,1}`), und reduziert niemals die LP-/Protokoll-/Fonds-Anteile der Handelsgebühr. Eintreibung ist über `CollectCreatorFee`. Siehe [`products/cpmm/fees`](/de/products/cpmm/fees) für die vollständige Mechanik.

### `Permission`

Ein kleines Zugriffskontrollkonto, das von `InitializeWithPermission` verwendet wird. Das CPMM-Programm unterstützt einen Pool-Erstellungs-Pfad mit Genehmigung, damit andere Programme (z.B. LaunchLab beim Hochfahren eines Tokens zu CPMM) beweisen können, dass sie berechtigt sind, einen Pool gegen ein gegebenes `AmmConfig` zu erstellen.

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

Die Permission-PDA wird vom CPMM-Admin über `CreatePermissionPda` erstellt und über `ClosePermissionPda` widerrufen. Endbenutzer interagieren nicht direkt mit diesem Konto — es ist Installationen für Cross-Program-Flows.

### Vaults und Token-2022

`vault0` und `vault1` werden von der CPMM-Authority-PDA besessen, und ihr Token-Programm-Besitzer (`token_program`) ist entweder SPL Token oder Token-2022, bestimmt bei Pool-Erstellung durch das Mint's-Programm. Der Pool handhabt beide Fälle transparent — Sie übergeben die richtige Token-Programm-ID für jede Seite in den `Swap` / `Deposit` / `Withdraw`-Anweisungs-Konten.

CPMM erzwingt eine strikte **Erweiterungs-Whitelist** bei Pool-Erstellung (`is_supported_mint` in `utils/token.rs`). Ein Token-2022-Mint kann in einem CPMM-Pool nur verwendet werden, wenn **jede** Erweiterung, die er trägt, auf dieser Liste steht:

* **`TransferFeeConfig`.** Angewendet vom Mint bei jeder Übertragung. Der Pool ist auf der Empfängerseite für `SwapBaseInput`-Ablagerungen und auf der Sender-Seite für Abhebungen. Das Programm berechnet den **Netto-Betrag**, der in der Vault landet, und stellt die Kurve entsprechend ein. Siehe [`algorithms/token-2022-transfer-fees`](/de/algorithms/token-2022-transfer-fees).
* **`MetadataPointer`** und **`TokenMetadata`.** Standard-on-Mint-Metadaten. Keine Auswirkung auf Swap-Mathematik.
* **`InterestBearingConfig`.** Der UI-Betrag des Mints sammelt Zinsen. Die Vault speichert Rohbeträge; die Kurve operiert nur auf Rohbeträgen. Benutzeroberflächen, die APR anzeigen, sollten die Token-2022-Helfer aufrufen, um den UI-Betrag zu rendern.
* **`ScaledUiAmount`.** Erweiterung zur UI-Display-Skalierung. Gleiche Behandlung wie `InterestBearingConfig` — die Kurve verwendet Rohbeträge.

Jede andere Erweiterung — `PermanentDelegate`, `TransferHook`, `DefaultAccountState`, `NonTransferable`, `ConfidentialTransfer`, `Group`/`GroupMember`, `MintCloseAuthority`, usw. — verursacht, dass `Initialize` mit `NotSupportMint` ablehnt. Die Ausnahme ist eine kleine hartcodierte **Mint-Whitelist** im Programm (eine Handvoll spezifischer Pubkeys), die die Erweiterungs-Prüfung umgeht; sie wird verwendet, um spezifische Mints Fall für Fall zu integrieren.

Die geprüfte Erweiterungs-Liste und die Mint-Whitelist befinden sich in der CP-Swap-Quelle unter `programs/cp-swap/src/utils/token.rs` und können sich bei zukünftigen Programm-Upgrades ändern.

### Observation

Das Observation-Konto ist ein Ringpuffer von `ObservationState`-Einträgen, die jeweils einen `block_timestamp` und einen **kumulativen Preis** speichern. Bei jedem Swap fügt das Programm eine neue Observation an, wenn genügend Zeit seit der letzten vergangen ist. TWAPs werden berechnet, indem zwei Observations gelesen und `Δcumulative / Δtime` dividiert werden.

```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],
}
```

Der Ringpuffer ist für **100 Observations** dimensioniert. Jede Observation ist 40 Bytes, das Array allein also 4.000 Bytes; die vollständige `ObservationState`-PDA ist nach den umgebenden Feldern und dem Diskriminator etwa 4.100 Bytes.

Zwei Konsumentenregeln:

* **Verwenden Sie nicht eine einzelne Observation als Preis.** Es ist eine *kumulative*, keine Spotpreis. Verwenden Sie zwei davon, um eine TWAP zu berechnen.
* **Wählen Sie Observations mindestens einen Block auseinander.** Swaps innerhalb des gleichen Blocks können keine neue Observation produzieren; das Zurücklesen nacheinander kann denselben Datensatz zurückgeben.

Weitere Mathematik in [`products/clmm/accounts`](/de/products/clmm/accounts).

## Konto-Lebenszyklus

| Ereignis             | Konten erstellt                                          | Konten zerstört |
| -------------------- | -------------------------------------------------------- | --------------- |
| `Initialize`         | `poolState`, `lpMint`, `vault0`, `vault1`, `observation` | —               |
| `Deposit`            | — (kann Benutzer-LP-ATA erstellen)                       | —               |
| `Withdraw`           | —                                                        | —               |
| `Swap`               | — (kann Benutzer-Ziel-ATA erstellen)                     | —               |
| `CollectProtocolFee` | —                                                        | —               |
| `CollectFundFee`     | —                                                        | —               |
| `UpdatePoolStatus`   | —                                                        | —               |

CPMM-Pools und ihre PDAs werden **niemals geschlossen**. Auch bei Null-Liquidität bleibt der `poolState` erhalten. Dies ist absichtlich: Das erneute Aufseeden desselben Pools später bewahrt seinen historischen Observation-Puffer und seine PDA-Ableitung bleibt stabil.

## Was wo lesen

* **Instruktions-Kontolisten** (welche der obigen sind schreibbar/Signer für jede Instruktion): [`products/cpmm/instructions`](/de/products/cpmm/instructions).
* **Gebühren-Akkretion-Semantik**: [`products/cpmm/fees`](/de/products/cpmm/fees).
* **Swap-Mathematik / Observation-Aktualisierungsregel**: [`products/cpmm/math`](/de/products/cpmm/math).
* **Kanonische Seeds / Programm-IDs**: [`reference/program-addresses`](/de/reference/program-addresses).

Quellen:

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