Skip to main content
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.
Beide Anweisungen zur Gebührenerfassung des Erstellers haben ihre Kontolisten am 2026-09-19 geändert. CollectCreatorFee erhält creator_fee_share; CollectCreatorFeePermissionless erhält amm_config und creator_fee_share. Beide werden nach system_program angehängt, sodass jedes Konto, das ein bestehender Client bereits übergibt, seinen Index behält — aber die neuen Konten sind verpflichtend, sodass eine gegen das ältere Layout erstellte Transaktion zu wenige Konten übergibt und mit Anchors AccountNotEnoughKeys (3005) abgelehnt wird. Zwei Admin-Anweisungen — CreateCreatorFeeShare und CloseCreatorFeeShare — werden hinzugefügt, und UpdateAmmConfig nimmt einen neuen param = 8. Siehe den Changelog-Eintrag vom 2026-09-19.

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
Konten (W = schreibbar, S = Unterzeichner) * 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_mint nach Byte-Ordnung).
  • Kein Mint verwendet eine Erweiterung außerhalb der CPMM-Allowlist (TransferFeeConfig, MetadataPointer, TokenMetadata, InterestBearingConfig, ScaledUiAmount) — siehe products/cpmm/accounts. Ein Mint, dessen SupportMintAssociated-PDA (Seed [b"support_mint", mint]) existiert, überspringt die Erweiterungsprüfung — aber Sie müssen diese PDA zu remaining_accounts hinzufü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 mit NotSupportMint (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.
  • creator hat mindestens init_amount_0 und init_amount_1 in den jeweiligen ATAs.
  • amm_config.disable_create_pool == false.
Nachbedingungen
  • pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1) — die vollständige Quadratwurzel. Der Ersteller wird mit lp_supply − 100 geprägt; die 100 gesperrten Basiseinheiten werden in lp_supply gezählt, aber nie geprägt.
  • Also lp_mint.supply == pool_state.lp_supply − 100 für die Lebensdauer des Pools. Alle LP-Anteil-Mathematik (Deposit, Withdraw) teilt durch lp_supply, daher verwenden Sie dieses Feld und ersetzen Sie nicht die On-Chain-Versorgung des Mints. Setzt zurück mit InitLpAmountTooLess, wenn sqrt(...) < 100.
  • observation_state wird initialisiert; observation_index = 0 und pool_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 = false und creator_fee_on = BothToken. Initialize unterstützt nicht das Aktivieren der Ersteller-Gebühr — dieser Pfad ist InitializeWithPermission.
  • open_time wird auf block_timestamp + 1 erhöht, wenn der Aufrufer einen Wert <= block_timestamp übergeben hat. Swaps werden vor open_time abgelehnt; Deposits und Withdrawals funktionieren sofort.
Häufige Fehler (vollständige Liste in reference/error-codes)
  • InvalidInput — Mints unsortiert oder identisch.
  • NotSupportMint — blockierte Token-2022-Erweiterung.
  • ExceededSlippage — selten; wenn init_amount_0/1 aufgrund von Dezimalstellen-Nichtübereinstimmung zu null LP führen.

Deposit

Fügt Liquidität in beiden Token proportional zum Pool hinzu. Argumente
Konten Mathematik
Zwei Details, die es zu beachten gilt: Die anteilsmäßige Basis ist die gebührenausgeschlossene Vault-Gesamtsumme (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).
Häufige Fehler — ExceededSlippage, ZeroTradingTokens, InvalidStatus, wenn Deposit pausiert ist.

Withdraw

Verbrennt LP-Token und erhält beide zugrunde liegenden Token anteilsmäßig. Argumente
Konten 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
Nachbedingungen
  • 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
Konten 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_status erlaubt Swap.
  • Kein Mint pausiert oder eingefroren für diese Autorität.
  • amount_in > 0.
Häufige Fehler
  • ExceededSlippage — amount_out < minimum_amount_out.
  • ZeroTradingTokens — der Handel rundet auf null.
  • NotApproved — Pool ist für Swaps über UpdatePoolStatus pausiert.
  • InvalidInput — Mints stimmen nicht mit einem der Vault-Mints des Pools überein.

SwapBaseOutput

Exakte-Ausgabe-Swap. Argumente
Konten — gleich wie 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
Keine Änderung an den effektiven Bilanzen der Kurve (aufgelaufene Gebühren waren bereits ausgeschlossen). Häufiger Fehler — 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
Der Anteil des Protokolls verlässt den Vault hier nie — er wird als Protokollgebühr neu gekennzeichnet und wartet auf 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
Die zwei neuen Konten werden nach system_program angehängt, nicht eingefügt. Jedes Konto von payer bis system_program behält die Position, die es vor dem Upgrade hatte, daher ist der Bruch ein sauberer: Eine Transaktion, die gegen das Vierzehn-Konto-Layout vor dem Upgrade erstellt wurde, liest keinen Vault fälschlich als Config — sie übergibt schlicht zu wenige Konten, und Anchor lehnt sie mit AccountNotEnoughKeys (3005) ab, bevor irgendeine Einschränkung läuft. Die Konten bleiben dennoch verpflichtend, hängen Sie also beide an und aktualisieren Sie die IDL; es gibt keinen Kompatibilitätspfad für das alte Layout.
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
Konten 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
Konten Vorbedingungen
  • Keine existierende AmmConfig mit demselben index.
  • 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 (behauptet trade_fee_rate + creator_fee_rate < 1_000_000)
  • param = 1 → protocol_fee_rate (behauptet ≤ 1_000_000 und + fund_fee_rate ≤ 1_000_000)
  • param = 2 → fund_fee_rate (behauptet ≤ 1_000_000 und + protocol_fee_rate ≤ 1_000_000)
  • param = 3 → protocol_owner. Der neue Schlüssel ist nicht in value: fügen Sie ihn als remaining_accounts[0] an (schreibgeschützt ist in Ordnung). Er darf nicht der Standard-Pubkey sein, und das Weglassen des Kontos panikt bei einem unwrap().
  • param = 4 → fund_owner. Gleicher Mechanismus wie 3.
  • param = 5 → create_pool_fee
  • param = 6 → disable_create_pool (jeder Nicht-Null-value deaktiviert)
  • param = 7 → creator_fee_rate (behauptet creator_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; siehe products/cpmm/fees. Es ist nicht verwandt mit protocol_fee_rate, das die Handelsgebühr aufteilt.
Jeder andere 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
Konten Vorbedingungen
  • share_rate <= 1_000_000, sonst InvalidInput (6003).
  • Die PDA darf nicht bereits existieren — Anchors init schlägt beim zweiten Aufruf für dasselbe Paar fehl. Um einen Satz zu ändern, schließen Sie das Konto und erstellen Sie es erneut.
Nachbedingungen
  • creator_fee_share speichert bump, creator, amm_config und share_rate.
  • Jeder nachfolgende CollectCreatorFee / CollectCreatorFeePermissionless auf einem Pool, der von creator unter amm_config erstellt 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_rate wieder auf — was 0 ist, es sei denn, ein Admin hat UpdateAmmConfig-Parameter 8 gesetzt.

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.
Wie jedes Quellkonto behandelt wird Das Programm dispatcht auf den 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

Quellen: