Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Diese Seite ist die maßgebliche Anweisungsreferenz. Für Code, der diese Anweisungen tatsächlich zusammensetzt, siehe
products/cpmm/code-demos. Für Fehlerkodierungen siehe reference/error-codes.Das Programm-Upgrade 2026-09 hat CPMM auf Anchor 1.0.2 / Solana 3.1.10 neu aufgebaut, die Admin-Anweisung CollectExcessLamports hinzugefügt, die hardcodierte Token-2022-Mint-Whitelist entfernt und geändert, was CreateAmmConfig in protocol_owner / fund_owner schreibt. Keine benutzergerichtete Anweisung hat ihre Konten, Argumente oder Mathematik geändert. Siehe den Changelog-Eintrag vom 2026-09-09.Anweisungsübersicht
Status-Bitmaske: Der
status jedes Pools ist ein u8, wobei Bit 0 = Deposit deaktiviert, Bit 1 = Withdraw deaktiviert, Bit 2 = Swap deaktiviert (PoolStatusBitIndex { Deposit, Withdraw, Swap } im Programm). Ein gelöschtes Bit bedeutet, dass die Operation erlaubt ist; ein gesetztes Bit bedeutet, dass sie pausiert ist. UpdatePoolStatus nimmt ein rohes u8 und überschreibt den vorhandenen Wert.
Die nächsten Abschnitte gehen detailliert auf jede ein. Die Kontoordnung folgt der CPMM-IDL; das SDK und der Rust-Client in raydium-cp-swap/programs/cp-swap/src/instructions entsprechen dieser Ordnung.
Initialize
Erstellt einen neuen CPMM-Pool.
Argumente
* pool_state signiert nur auf dem zufälligen-Keypair-Pfad; der kanonische-PDA-Pfad läuft ohne pool_state-Signatur.
Vorbedingungen
- Mints sind sortiert (
token_0_mint < token_1_mintnach Byte-Ordnung). - Kein Mint verwendet eine Erweiterung außerhalb der CPMM-Allowlist (
TransferFeeConfig,MetadataPointer,TokenMetadata,InterestBearingConfig,ScaledUiAmount) — sieheproducts/cpmm/accounts. Ein Mint, dessenSupportMintAssociated-PDA (Seed[b"support_mint", mint]) existiert, überspringt die Erweiterungsprüfung — aber Sie müssen diese PDA zuremaining_accountshinzufügen. Das Programm scannt nur die Konten, die Sie übergeben, und lädt die PDA nie selbst, daher schlägt die Verwendung der Registrierung ohne Bereitstellung des Kontos immer noch mitNotSupportMint(6007) fehl. Die Ordnung spielt keine Rolle (Matching erfolgt nach Schlüssel); übergeben Sie einen Eintrag pro Mint, der die Umgehung benötigt. Diese Registrierung ist die einzige Umgehung, da das 2026-09-Upgrade die hardcodierte Vier-Mint-Whitelist entfernt hat. creatorhat mindestensinit_amount_0undinit_amount_1in den jeweiligen ATAs.amm_config.disable_create_pool == false.
pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1)— die vollständige Quadratwurzel. Der Ersteller wird mitlp_supply − 100geprägt; die 100 gesperrten Basiseinheiten werden inlp_supplygezählt, aber nie geprägt.- Also
lp_mint.supply == pool_state.lp_supply − 100für die Lebensdauer des Pools. Alle LP-Anteil-Mathematik (Deposit, Withdraw) teilt durchlp_supply, daher verwenden Sie dieses Feld und ersetzen Sie nicht die On-Chain-Versorgung des Mints. Setzt zurück mitInitLpAmountTooLess, wennsqrt(...) < 100. observation_statewird initialisiert;observation_index = 0undpool_id = pool_state.key().create_pool_fee-Lamports werden vom Ersteller zum Empfänger übertragen und als natives SOL synchronisiert (es ist eine wSOL-ATA).- Die Status-Bitmaske des Pools ist
0(Deposit / Withdraw / Swap alle aktiviert). enable_creator_fee = falseundcreator_fee_on = BothToken.Initializeunterstützt nicht das Aktivieren der Ersteller-Gebühr — dieser Pfad istInitializeWithPermission.open_timewird aufblock_timestamp + 1erhöht, wenn der Aufrufer einen Wert<= block_timestampübergeben hat. Swaps werden voropen_timeabgelehnt; Deposits und Withdrawals funktionieren sofort.
reference/error-codes)
InvalidInput— Mints unsortiert oder identisch.NotSupportMint— blockierte Token-2022-Erweiterung.ExceededSlippage— selten; wenninit_amount_0/1aufgrund von Dezimalstellen-Nichtübereinstimmung zu null LP führen.
Deposit
Fügt Liquidität in beiden Token proportional zum Pool hinzu.
Argumente
Mathematik
vault_amount_without_fee, d. h. der Rohsaldo minus der aufgelaufenen Protokoll-, Fonds- und Ersteller-Zähler), nicht der Rohsaldo des Vaults; und die Slippage-Obergrenze wird gegen das überprüft, was der Zahler tatsächlich überweist, nach der Token-2022-Transfergebühr hinzugefügt, nicht gegen die Brutto-Vault-Bewegung.
Keine Änderung an der Proportionalität von k — beide Gesamtsummen und lp_supply skalieren um denselben Faktor.
Nachbedingungen
lp_supply += lp_token_amount.vault_0 += needed_token_0(netto einer Token-2022-Transfergebühr auf Eingabe).vault_1 += needed_token_1(netto einer Token-2022-Transfergebühr auf Eingabe).
ExceededSlippage, ZeroTradingTokens, InvalidStatus, wenn Deposit pausiert ist.
Withdraw
Verbrennt LP-Token und erhält beide zugrunde liegenden Token anteilsmäßig.
Argumente
Die ersten 13 Konten sind identisch mit
Deposit, und lp_mint ist schreibbar, weil die LP-Token verbrannt werden. Withdraw nimmt zusätzlich ein 14. Konto, memo_program (eingeschränkt address = memo::ID) — Deposit nicht. Ein 13-Konto-Withdraw schlägt die Anchor-Deserialisierung fehl, daher kann der LP nicht aussteigen.
Mathematik
lp_supply -= lp_token_amount.- Vaults senden
out_token_0/out_token_1(Brutto; der Benutzer erhält netto einer Token-2022-Transfergebühr).
SwapBaseInput
Exakte-Eingabe-Swap.
Argumente
Die Ordnung Eingabe → Ausgabe ist nach der Richtung des Benutzers, nicht nach dem kanonischen
token_0 / token_1 des Pools. Das Programm ermittelt, welcher Vault welcher ist, durch Matching von Mints.
Mathematik — siehe products/cpmm/math.
Vorbedingungen
open_time <= now.pool_statuserlaubt Swap.- Kein Mint pausiert oder eingefroren für diese Autorität.
amount_in > 0.
ExceededSlippage—amount_out < minimum_amount_out.ZeroTradingTokens— der Handel rundet auf null.NotApproved— Pool ist für Swaps überUpdatePoolStatuspausiert.InvalidInput— Mints stimmen nicht mit einem der Vault-Mints des Pools überein.
SwapBaseOutput
Exakte-Ausgabe-Swap.
Argumente
SwapBaseInput.
Mathematik — inverse Kurve mit Obergrenze, siehe products/cpmm/math.
Häufige Fehler — ExceededSlippage (gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.
CollectProtocolFee
Sammelt aufgelaufene Protokollgebühren aus den Vaults zum Protokoll-Ziel.
Argumente — keine.
Konten
Effekt
InvalidOwner (6001), wenn der Unterzeichner weder amm_config.protocol_owner noch der Programm-Admin ist. (Es gibt keinen NotApproved auf diesem Pfad.)
CollectFundFee
Gleiche Form wie CollectProtocolFee, aber signiert von amm_config.fund_owner — oder wiederum vom Programm-Admin — und setzt die fund_fees_*-Zähler auf null. Gleicher InvalidOwner bei falschem Unterzeichner.
CollectCreatorFee
Signiert von pool_state.pool_creator. Es regelt die aufgelaufene Ersteller-Gebühr und überweist den Anteil des Erstellers auf die Token-Konten des Erstellers.
Argumente — keine.
Konten
Effekt
CollectProtocolFee. Beide Zähler sind bereits aus der Sicht der Kurve auf den Vault ausgeschlossen, daher bewegt sich der Pool-Preis nicht. Vollständige Herleitung in products/cpmm/fees.
Häufige Fehler — NoFeeCollect, wenn beide Ersteller-Zähler null sind (überprüft vor der Aufteilung), InvalidInput (6003), wenn die aufgelöste share_rate 1_000_000 überschreitet, MathOverflow (6011), wenn die Buchung des Anteils protocol_fees_token_* überläuft, und Anchors ConstraintSeeds-Fehler, wenn creator_fee_share nicht die kanonische PDA ist.
CollectCreatorFeePermissionless
Jeder kann die Erfassung der Ersteller-Gebühr auslösen. Die Anweisung sendet den Anteil des Erstellers immer an die kanonischen zugeordneten Token-Konten, die pool_state.pool_creator gehören; der Aufrufer kann keinen anderen Ersteller oder Ziel wählen. Wenn eine ATA fehlt, finanziert der Zahler ihre Erstellung.
Das ursprüngliche CollectCreatorFee bleibt aufrufbar, daher kann ein Ersteller, der für seine eigene Erfassung signieren möchte, dies immer noch tun.
Argumente — keine.
Konten
Effekt — identisch mit
CollectCreatorFee oben: Der Anteil wird aus creator_fee_share oder amm_config aufgelöst, der Anteil des Protokolls wird in protocol_fees_token_{0,1} gebucht, der Anteil des Erstellers wird auf die Ersteller-ATAs übertragen, beide Ersteller-Zähler werden auf null gesetzt, und recent_epoch wird aktualisiert. Gibt NoFeeCollect zurück, wenn beide Zähler null sind.
UpdatePoolStatus
Pausiert oder setzt einzelne Operationen auf einem Pool fort. Das status-Feld ist eine Bitmaske:
Argumente
Der Admin-Schlüssel ist ein öffentlicher Schlüssel, der in das Programm kompiliert ist (
crate::admin::ID), nicht die BPF-Upgrade-Autorität — das Ändern erfordert ein Programm-Upgrade. Siehe reference/program-addresses für den Wert und security/admin-and-multisig für wer ihn hält.
CreateAmmConfig
Erstellt eine neue Gebührenebene.
Argumente
Vorbedingungen
- Keine existierende
AmmConfigmit demselbenindex. protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
Geändert in 2026-09: Die Gebührenbesitzer der neuen Config stammen nicht mehr vom Unterzeichner.
create_amm_config schreibt jetzt die hardcodierten protocol_fee_owner::ID des Programms in protocol_owner und fund_fee_owner::ID in fund_owner, anstatt den Admin-Unterzeichner-Schlüssel in beide zu kopieren. Adressen sind in reference/program-addresses.Konsequenzen: Gebühren auf einer neu erstellten AmmConfig landen in den dedizierten Gebühren-Wallets statt beim Admin. Der Admin bleibt ein akzeptierter Unterzeichner für die Erfassung — CollectProtocolFee / CollectFundFee akzeptieren amm_config.protocol_owner / fund_owner oder crate::admin::ID — daher muss nichts rotiert werden, um zu sammeln; was sich geändert hat, ist nur, wohin die Einnahmen standardmäßig gehen. Existierende AmmConfig-Konten werden nicht neu geschrieben — was auf ihnen gespeichert ist, regiert immer noch, daher lesen Sie protocol_owner / fund_owner immer vom Konto, anstatt einen Wert anzunehmen. UpdateAmmConfig-Parameter 3 und 4 rotieren sie immer noch.UpdateAmmConfig
Ändert Gebührensätze oder Eigentümerschaft auf einer existierenden AmmConfig. Nimmt einen param: u8 (welches Feld zu aktualisieren) und einen value: u64. Die vollständige Dispatch-Tabelle:
param = 0→trade_fee_rate(behauptettrade_fee_rate + creator_fee_rate < 1_000_000)param = 1→protocol_fee_rate(behauptet≤ 1_000_000und+ fund_fee_rate ≤ 1_000_000)param = 2→fund_fee_rate(behauptet≤ 1_000_000und+ protocol_fee_rate ≤ 1_000_000)param = 3→protocol_owner. Der neue Schlüssel ist nicht invalue: fügen Sie ihn alsremaining_accounts[0]an (schreibgeschützt ist in Ordnung). Er darf nicht der Standard-Pubkey sein, und das Weglassen des Kontos panikt bei einemunwrap().param = 4→fund_owner. Gleicher Mechanismus wie3.param = 5→create_pool_feeparam = 6→disable_create_pool(jeder Nicht-Null-valuedeaktiviert)param = 7→creator_fee_rate(behauptetcreator_fee_rate + trade_fee_rate < 1_000_000)param = 8→creator_fee_share_rate(behauptet≤ 1_000_000). Hinzugefügt 2026-09-19. Der Standard-Anteil des Protokolls der Ersteller-Gebühr auf dieser Ebene; sieheproducts/cpmm/fees. Es ist nicht verwandt mitprotocol_fee_rate, das die Handelsgebühr aufteilt.
param gibt InvalidInput zurück.
Änderungen werden vom Admin signiert und beeinflussen jeden Pool, der an diese AmmConfig gebunden ist beim nächsten Swap. Keine Migration; Pools lesen einfach die neuen Werte.
CreateCreatorFeeShare
Legt einen benutzerdefinierten Protokoll-Anteil der Ersteller-Gebühr für ein (creator, amm_config)-Paar fest und überschreibt AmmConfig.creator_fee_share_rate für jeden Pool, den dieser Ersteller auf dieser Gebührenebene besitzt. Hinzugefügt im 2026-09-19-Creator-Fee-Share-Upgrade.
Argumente
Vorbedingungen
share_rate <= 1_000_000, sonstInvalidInput(6003).- Die PDA darf nicht bereits existieren — Anchors
initschlägt beim zweiten Aufruf für dasselbe Paar fehl. Um einen Satz zu ändern, schließen Sie das Konto und erstellen Sie es erneut.
creator_fee_sharespeichertbump,creator,amm_configundshare_rate.- Jeder nachfolgende
CollectCreatorFee/CollectCreatorFeePermissionlessauf einem Pool, der voncreatorunteramm_configerstellt wurde, löst den Anteil aus diesem Konto statt aus der Config auf.
Der Pool-Ersteller ist keine Partei dieser Anweisung und signiert sie nicht. Der Satz wird zum Erfassungszeitpunkt gelesen, daher gilt eine nach bereits aufgelaufenen Gebühren erstellte Überschreibung auch für diesen aufgelaufenen Saldo.
CloseCreatorFeeShare
Entfernt die Überschreibung. Das Paar fällt auf AmmConfig.creator_fee_share_rate zurück.
Argumente — keine.
Konten
Nachbedingungen
- Das Konto wird geschlossen und seine Lamports gehen an
owner. - Erfassungen für dieses Paar lösen den Anteil aus
amm_config.creator_fee_share_ratewieder auf — was0ist, es sei denn, ein Admin hatUpdateAmmConfig-Parameter8gesetzt.
CollectExcessLamports
Admin-Sweep von Lamports, die über dem Mietbefreiungsminimum auf Konten sitzen, die CPMM kontrolliert. Hinzugefügt im 2026-09-Upgrade, damit das Protokoll die Überfinanzierung zurückfordern kann, die die SIMD-0437-Mietreduktion auf Konten hinterlässt, die vor jedem Schritt erstellt wurden.
Nur der Überschuss bewegt sich. Token-Bilanzen, Kontodaten, Besitzer, Pool-Status und die Kurve bleiben unverändert, und die Anweisung ist ein No-Op gegen ein Konto, das bereits bei seinem Minimum ist — daher ist es sicher, nach jedem Rollout-Schritt erneut auszuführen.
Argumente — keine.
Konten
Ordnungsfix, 2026-09-19. Das Programm macht jetzt zwei Durchläufe über
remaining_accounts — jede Token-Programm-CPI zuerst, dann die direkten Belastungen von CPMM-eigenen PDAs. Das Verschachteln von ihnen brach mit dem UnbalancedInstruction-Fehler der Laufzeit ab („Summe der Kontobilanzen vor und nach der Anweisung stimmen nicht überein”), wann immer eine PDA vor einer CPI belastet wurde, weil die ausstehenden Lamport-Änderungen des Aufrufers nur in Konten geleert werden, die eine CPI tatsächlich trägt. Aufrufer müssen die Liste nicht selbst gruppieren oder sortieren.owner des Quellkontos:
Da es eine unbegrenzte
remaining_accounts-Liste nimmt, ist die Transaktionsgröße die echte Grenze — die gleiche Einschränkung wie der Wallet-seitige Sweep, der in solana-fundamentals/rent-and-reclaimable-rent beschrieben ist.
Häufige Fehler — InvalidOwner (6001, falscher Unterzeichner), LamportsCalculateError (6015, die wSOL-Rundreise nettete nicht zu null), und InsufficientFunds aus dem Programm-eigenen Pfad, wenn ein Konto weniger als sein eigenes Mietminimum hält.
Kein SDK-Builder. @raydium-io/raydium-sdk-v2 liefert keinen Builder für diese Anweisung, und auch das raydium-sdk-V2-demo-Repo nicht — es ist ein Admin-Pfad. Codieren Sie es von Hand, wie der Wallet-seitige Sweep in solana-fundamentals/rent-and-reclaimable-rent für die Token-Programm-Anweisung.
Zustandsänderungsmatrix
Nächste Schritte
products/cpmm/code-demos— ausführbare TypeScript-Beispiele für die obigen.reference/error-codes— die vollständige Anchor-Fehlertabelle.products/cpmm/fees— das Gebühren-Aufzinsungsmodell, das dieCollect*Fee-Anweisungen leeren.

