Skip to main content
Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Programm-ID und PDA-Seeds für CPMM sind kanonisch in 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.

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. Und die gemeinsame Konfiguration:

Ableitung eines Pools aus nichts als zwei Mints

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

Konto-Layouts

Die vollständigen Rust-Definitionen befinden sich in der raydium-cp-swap-Quelle. Die Felder unten sind diejenigen, die Sie aus einer Integration lesen werden.

PoolState

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

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

Konto-Lebenszyklus

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

Quellen: