Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Diese Seite ergänzt
products/clmm/accounts (was die Konten sind) und products/clmm/math (was die Mathematik ist). Sie ist maßgeblich für Argumente und Kontenreihenfolge; spezifische Byte-Layouts stammen aus dem IDL.Anweisungsübersicht
Die meisten Admin-only-Anweisungen (
CreateAmmConfig, UpdateAmmConfig, UpdatePoolStatus, CreateSupportMintAssociated, CreateOperationAccount, UpdateOperationAccount, CloseProtocolPosition) werden durch den hardcodierten admin Public Key des Programms gated. CreatePermissionPda / ClosePermissionPda akzeptieren entweder den admin Public Key oder einen dedizierten permission_pda_admin-Schlüssel. Reward-Stream-Admin-Anweisungen (TransferRewardOwner, CollectRemainingRewards) werden durch den Reward-Funder gated, nicht durch den Programm-Admin.
V2-Suffix bedeutet „unterstützt Token-2022 auf Vaults/NFT, erfordert Bitmap-Erweiterungs-Slot”. Das SDK wählt V2 standardmäßig für neue Pools.
CreatePool
Argumente
Vorbedingungen
token_mint_0 < token_mint_1nach Byte-Reihenfolge.amm_config.disable_create_pool == false.- Mints werden nicht durch die Token-2022-Erweiterungs-Erlaubt-Liste abgelehnt.
pool_state.sqrt_price_x64 = sqrt_price_x64,tick_current = floor(log_{1.0001}(price)).pool_state.liquidity = 0(noch keine Positionen).pool_state.fee_on = FromInput(Legacy-Standard).pool_state.dynamic_fee_infoist auf Null gesetzt (dynamische Gebühr deaktiviert).
CreateCustomizablePool
Empfohlen für neue Pools. Gleiche Wirkung wie CreatePool plus Pool-Gebührensammlungsmodus und ein optionales dynamisches Gebühren-Opt-in.
Argumente
CreatePool plus, wenn enable_dynamic_fee = true:
Vorbedingungen — gleich wie
CreatePool. Wenn enable_dynamic_fee = false, wird dynamic_fee_config ignoriert.
Nachbedingungen
pool_state.fee_onauf die gewählteCollectFeeOn-Variante gesetzt.- Wenn dynamische Gebühr aktiviert wurde:
pool_state.dynamic_fee_infowird aus der bereitgestelltenDynamicFeeConfiginitialisiert (fünf Kalibrierungsparameter kopiert; Zustandsfelder auf Null gesetzt). - Andernfalls:
pool_state.dynamic_fee_infoist auf Null gesetzt (= dynamische Gebühr für immer inaktiv für diesen Pool).
fee_on und das dynamische Gebühren-Aktivierungsbit werden nur bei der Pool-Erstellung gesetzt. Es gibt kein In-Place-Upgrade — Pools, die über Legacy-CreatePool erstellt wurden, können nicht rückwirkend dynamische Gebühren oder einseitige Gebühren erhalten. Neue Bereitstellungen sollten standardmäßig diese Anweisung verwenden.
CreatePermissionedPool
Sowohl CreatePool als auch CreateCustomizablePool leiten die Pool-PDA von ["pool", amm_config, token_mint_0, token_mint_1] ab, daher gibt es genau eine kanonische Pool-Adresse pro (config, mint0, mint1)-Triple — ein zweites init bei denselben Seeds schlägt fehl. CreatePermissionedPool hebt diese Einschränkung auf, indem ein vom Client bereitgestellter seed_index: u16 in die Pool-PDA-Seeds gefaltet wird, was mehrere Pools für dasselbe Paar und dieselbe Gebührenebene ermöglicht — jeweils unter seiner eigenen Adresse. Da eine beliebige Pool-Adresse eine privilegierte Fähigkeit ist, muss der Zahler eine Permission PDA halten, die ihn autorisiert.
Alles andere am Pool ist identisch mit CreateCustomizablePool: Es nimmt die gleichen CreateCustomizableParams und unterstützt einseitige Gebühren und das dynamische Gebühren-Opt-in.
Argumente
CreateCustomizablePool plus, am Anfang:
Die
pool_state PDA wird von ["pool", amm_config, token_mint_0, token_mint_1, seed_index.to_le_bytes()] abgeleitet.
Vorbedingungen
seed_index != 0. Einseed_indexvon0ist für Legacy-Pools reserviert und wird hier abgelehnt; die[0, 0]-Seed-Komponente ist das, was eine Legacy-Pool-Adresse zum Zusammenbruch in die klassische Vier-Seed-Form führt.- Die
permissionPDA fürpayerexistiert (erstellt von einem Admin überCreatePermissionPda). - Gleiche Mint-/Erlaubt-Listen-Regeln wie
CreatePool.
- Eine neue
pool_stateexistiert unter derseed_index-abgeleiteten Adresse, mitpool_state.seed_index = seed_index. - Alle anderen Post-State-Übereinstimmungen mit
CreateCustomizablePool(Gebührenmodus, optionale dynamische Gebühr).
Diese Anweisung verbreitert nicht den allgemeinen Pool-Erstellungszugriff — erlaubnislose Erstellung läuft weiterhin über
CreatePool / CreateCustomizablePool, die ein Pool pro Paar bleiben. CreatePermissionedPool existiert für den spezifischen Fall, in dem ein auf der Whitelist stehender Operator mehrere Pools für dasselbe Paar benötigt (z. B. unterschiedliche Anfangspreise oder Launch-Kohorten) und eine Permission PDA hält, die vom Admin gewährt wurde.OpenPositionV2 / OpenPositionWithToken22Nft
Erstellt eine neue Position in einem bestehenden Pool.
Argumente
Mathematik — siehe
products/clmm/math. Gegeben base_flag, löst das Programm entweder liquidity oder (amount_0_max, amount_1_max) in das tatsächliche L und die tatsächlich verbrauchten Token-Beträge auf.
Vorbedingungen
tick_lower < tick_upper, beide Vielfache vonpool.tick_spacing, innerhalb von[MIN_TICK, MAX_TICK].- Erforderliche Tick-Arrays übergeben und initialisiert (oder hier über
InitTickArrayCPI in der Transaktion erstellt). - Benutzer hat mindestens
amount_0_maxundamount_1_maxin den Quell-ATAs.
personal_positionexistiert,liquiditygesetzt,fee_growth_inside_lastabgebildet.- Tick-Array-Einträge bei
tick_lowerundtick_upperaktualisiert (liquidity_gross += L,liquidity_net ± L, Gebührenwachstums-Snapshots gepflegt). pool_state.liquidity += L, wenn Position im Bereich ist (tick_lower ≤ tick_current < tick_upper).- Die Positions-NFT-Mint zeichnet
pool_stateals Freeze-Autorität auf. Mint-Autorität wird entfernt, nachdem die einzelne NFT geprägt wurde. Das Aufzeichnen der Freeze-Autorität ändert den Zustand des NFT-Token-Kontos nicht. - Das NFT-Token-Konto bleibt aufgetaut, es sei denn, die Anweisung ist
OpenPositionV2oderOpenPositionWithToken22Nftund die Freeze-Autorität einer Vault-Mint entspricht der CLMM-Liste der eingeschränkten Aussteller. Nur dieser übereinstimmende V2-Pfad friert das Konto ein.OpenPositionV1 friert nicht ein.
InvalidTickIndex, NotApproved, ZeroAmountSpecified, TransactionTooLarge (wenn zu viele Tick-Arrays).
Position-Einfrieren fügt keine deklarierten Anweisungskonten oder Argumente hinzu. Clients können diese Positionen mit den bestehenden V2-Layouts öffnen. Das Verhalten wird On-Chain aus
vault_0_mint und vault_1_mint ausgewählt.IncreaseLiquidityV2
Fügt Liquidität zu einer bereits offenen Position hinzu.
Argumente
OpenPosition minus die NFT-Mint (Position existiert bereits; die NFT wird als Eigentümer-ATA übergeben, die 1 Token hält).
Effekt
- Überträgt
amount_0_actual/amount_1_actualvon Benutzer → Vaults. - Erhöht
personal_position.liquidityundpool_state.liquidity(wenn im Bereich), und die Endpunkt-Tickliquidity_gross/liquidity_netentsprechend. - Sammelt fällige Gebühren und Rewards seit letztem Zugriff und schreibt sie
tokens_fees_owed_{0,1}/reward_amount_owedgut. Diese werden nur beiDecreaseLiquidityoderCollectRewardausgezahlt, nicht bei Erhöhung.
DecreaseLiquidityV2
Entfernt Liquidität aus einer Position.
Argumente
IncreaseLiquidity.
Effekt
- Berechnet
(amount_0, amount_1)für das entfernteLgegeben aktuellessqrt_price_x64. - Setzt Gebühren/Rewards ab, die seit letztem Zugriff aufgelaufen sind, gleich wie
IncreaseLiquidity. - Überträgt
amount_0 + fees_owed_0undamount_1 + fees_owed_1aus Vaults zum Benutzer. - Verringert Liquiditätszähler; wenn das neue
personal_position.liquidity == 0, ist die Position berechtigt fürClosePosition.
amount_0_min und amount_1_min sind die Mindestwerte, die der Benutzer netto von Token-2022-Transfergebühren auf der Ausgabeseite akzeptiert.
ClosePosition
Brennt die Positions-NFT und schließt PersonalPositionState.
Deklarierte Konten
Verbleibende Konten
- Aufgetaute NFT: keine erforderlich; ein zusätzliches Pool-Konto ist harmlos, da der Handler es nicht liest.
- Eingefrorene NFT: fügen Sie
personal_position.pool_idals erstes verbleibendes Konto an. Das Programm lädt es alsPoolStateund verwendet seine PDA-Seeds zum Signieren des Auftauens.
personal_position.liquidity == 0.tokens_fees_owed_{0,1} == 0.- Alle Reward-Zähler
reward_amount_owed == 0.
- Wenn das NFT-Token-Konto eingefroren ist, überprüft, ob das erste verbleibende Konto gleich
personal_position.pool_idist, und taut es dann mit der Pool-PDA auf. - Brennt die NFT.
- Schließt das NFT-Token-Konto und
personal_position, erstattet Miete annft_owner. Wenn die Positions-NFT Token-2022 verwendet, schließt es auch die NFT-Mint; klassische SPL Token-Mints können nicht geschlossen werden und bleiben mit Angebot Null.
AccountLack fehl, wenn eine eingefrorene Position geschlossen wird. Das Pool-Konto für jeden Close zu übergeben ist die einfachste kompatible Strategie.
SwapV2
Geht die Liquiditätskurve entlang; exakte Eingabe oder exakte Ausgabe je nach is_base_input.
Argumente
Aufrufer übergeben eine geordnete Liste von Tick-Arrays, die die erwartete Swap-Spanne abdecken; das Programm verwendet so viele wie nötig. Das SDK berechnet diese Liste über
PoolUtils.computeAmountOutFormat oder den Quote-Endpunkt der API.
Vorbedingungen
pool_state.statuserlaubt Swap.now >= open_time.sqrt_price_limit_x64ist auf der korrekten Seite vonsqrt_price_x64für die Richtung.
ExceededSlippage, SqrtPriceLimitOverflow, TickArrayNotFound, LiquidityInsufficient.
Was SwapV2 intern tut, das Aufrufer wissen sollten (Post-2025-Release):
- Dynamische Gebührenzuschlag — wenn
pool.dynamic_fee_infoungleich Null ist, aktualisiert das Programm den Volatilitäts-Akkumulator unter Verwendung der seit dem letzten Swap durchquerten Tick-Distanz (mit den Filter-/Decay-Regeln ausproducts/clmm/fees) und fügt einedynamic_fee_componentaufAmmConfig.trade_fee_ratehinzu. Die Gesamtgebühr ist auf 10% begrenzt (MAX_FEE_RATE_NUMERATOR / 1_000_000). - Limit-Order-Matching — wenn der Preis-Walk einen Tick kreuzt, der offene Limit-Orders hält, erfüllt das Programm zuerst verfügbare Limit-Order-Liquidität bei diesem Tick (FIFO nach
order_phase), dann geht es entlang der LP-Liquiditätskurve weiter. Erfüllte Beträge aktualisierentick.unfilled_ratio_x64undtick.part_filled_orders_remainingfür spätere Abwicklung; Orders selbst bleiben unausgegeben, bis ihr EigentümerSettleLimitOrderaufruft. - Einseitige Gebührenrouting — wenn
pool.fee_on = Token0OnlyoderToken1Only, berechnet der Swap-Schritt immer noch die gleiche Input-Output-Trade; die Gebühr wird dann zur konfigurierten Seite geleitet. Für Richtungen, bei denen die konfigurierte Gebührenseite die Ausgabe ist, wird die Gebühr von der Swap-Ausgabe abgezogen (der Benutzer erhältout − fee); für Richtungen, bei denen sie die Eingabe ist, entspricht das VerhaltenFromInput. Sieheis_fee_on_input(zero_for_one)undis_fee_on_token0(zero_for_one)aufPoolState.
Swap (V1) implementiert die gleiche dynamische Gebühr, einseitige Gebührenrouting und Limit-Order-Matching wie SwapV2; das einzige Feature, das es fehlt, ist Token-2022-Unterstützung — beide Vaults müssen klassisches SPL Token sein. Pools mit einer Token-2022-Mint müssen über SwapV2 getauscht werden. Der Aggregator und das SDK bevorzugen bereits V2 für jeden CLMM-Leg, daher müssen Aufrufer nicht nach Mint-Typ verzweigen.
OpenLimitOrder
Platziert eine Verkaufsorder bei einem bestimmten Tick. Die Order sitzt in einer Pro-Tick-FIFO-Kohorte und wird erfüllt, wenn der Preis vorbeigeht.
Argumente
Konten-Listen-Änderung (2026-07-Release).
OpenLimitOrder nimmt jetzt auch die Output-Seiten-Konten — output_token_account, output_vault und output_vault_mint — zusätzlich zur Input-Seite. Sie werden nur zur Validierung verwendet: Das Programm lehnt die Order ab, wenn das Input- oder Output-Token-Konto des Eigentümers eingefroren ist. Dies garantiert, dass eine Erfüllung tatsächlich zum Output-ATA des Eigentümers abgewickelt werden kann, was für Erlaubt-Listen-/Standard-eingefrorene Token-2022-Mints (z. B. berechtigte Token) wichtig ist, bei denen ein Konto möglicherweise noch nicht aufgetaut ist. Clients, die gegen die ältere einseitige Kontenliste erstellt wurden, müssen die drei Output-Konten hinzufügen.- Weder
input_token_accountnochoutput_token_accountist eingefroren (andernfallsNotApproved). pool_state.statuserlaubt sowohl den Swap (Bit 4) als auch Limit-Order-Operationen (Bit 5) (andernfallsNotApproved).tick_index % pool.tick_spacing == 0und innerhalb von[MIN_TICK, MAX_TICK].tick_indexist auf der rechten Seite vonpool.tick_currentfür die gewählte Richtung (Verkauf von token0 → Tick muss über aktuell sein, und umgekehrt). Verkauf bei einem bereits gekreuzten Tick würde sofort erfüllt und wird abgelehnt.
limit_orderexistiert, Snapshot vontick.order_phaseundtick.unfilled_ratio_x64bei Öffnungszeit.tick.orders_amount += amount(in der aktuellen Kohorte).limit_order_nonce.order_nonce += 1.OpenLimitOrderEventemittiert.
NotApproved (Input- oder Output-Token-Konto eingefroren, oder der Pool hat Swap/Limit-Order deaktiviert), InvalidLimitOrderAmount (Null oder unter dem Pool-Minimum), InvalidTickIndex (außerhalb von [MIN_TICK, MAX_TICK], oder auf der falschen Seite von tick_current für die gewählte Richtung), TickAndSpacingNotMatch (tick_index % pool.tick_spacing != 0), OrderPhaseSaturated.
IncreaseLimitOrder
Fügt zu einer bestehenden offenen Order hinzu. Nur vom owner der Order aufrufbar.
Argumente
OpenLimitOrder minus das Nonce-Konto; die limit_order PDA wird direkt übergeben.
Vorbedingungen
limit_order.owner == signer.- Die Order ist immer noch in der gleichen Kohorte (
tick.order_phase == limit_order.order_phase). Wenn die Kohorte bereits mit dem Erfüllen begonnen hat, ist die Order teilweise abgewickelt — der Aufrufer sollte zuerstDecreaseLimitOrderoderSettleLimitOrderaufrufen, um voranzukommen.
- Überträgt
amountvon Eigentümer-ATA zuinput_vault. limit_order.total_amount += amount;tick.orders_amount += amount.
DecreaseLimitOrder
Reduziert oder storniert vollständig eine offene Order. Zahlt den unerfüllten Rest zurück zum Eigentümer, plus jede Ausgabe, die bereits durch frühere Teilerfüllungen abgewickelt wurde.
Argumente
Effekt
- Berechnet den erfüllten Betrag der Order aus der Kohorte
unfilled_ratio_x64seit Öffnung neu. - Sendet erfüllte Ausgabe zu
output_token_account. - Sendet
amountunerfüllter Eingabe zurück zuinput_token_account. - Aktualisiert
limit_orderentsprechend. Wenn der neue unerfüllte Rest Null ist, schließt das Programm das Konto und erstattet Miete anowner.
SettleLimitOrder
Schiebt erfüllte Ausgabe-Token zum Eigentümer, ohne den unerfüllten Rest der Order zu ändern. Nützlich, wenn auto_withdraw-Keeper lange laufende Teilerfüllungen tropfenweise zahlen möchten.
Aufrufer — entweder der owner der Order, oder der limit_order_admin des Programms (ein Off-Chain-Operationshot-Wallet, das eine automatisierte Keeper-Schleife ausführt). Der Keeper hat keine andere Autorität — er kann Benutzerfonds nicht außerhalb des Schiebens erfüllter Ausgabe zum Order-owner-ATA verschieben.
Konten
Effekt
- Berechnet die kumulativ fällige Ausgabe unter Verwendung von
(limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64). - Überträgt das Delta zu
output_token_account. - Aktualisiert
limit_order.settled_output. - Schließt die Order nicht; sie ist immer noch gegen verbleibende Eingabe offen.
CloseLimitOrder
Schließt ein vollständig verbrauchtes Order-Konto. Miete wird immer an limit_order.owner zurückgegeben, unabhängig davon, wer signiert.
Aufrufer — entweder owner oder limit_order_admin.
Vorbedingungen
- Die Order hat einen unerfüllten Rest von Null (entweder
amount == total_amountwurde erfüllt und abgewickelt, oder der Eigentümer hat die Order zuvor auf Null verringert und vergessen zu schließen).
- Schließt
limit_order; Miete wird anlimit_order.ownergesendet.
CreateDynamicFeeConfig (Admin)
Erstellt einen wiederverwendbaren Parametersatz unter einem u16-Index.
Argumente
Häufige Fehler —
InvalidDynamicFeeConfigParams, wenn decay_period <= filter_period oder ein Feld mit Wert Null außerhalb der Grenzen liegt.
UpdateDynamicFeeConfig (Admin)
Ändert eine bestehende DynamicFeeConfig. Pools, die die Konfiguration bereits bei der Erstellung abgebildet haben, werden nicht rückwirkend aktualisiert; nur neu erstellte Pools, die diese Konfiguration referenzieren, werden die neuen Werte aufgreifen.
Argumente — gleich fünf Kalibrierungsfelder wie CreateDynamicFeeConfig (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator); index ist bei der Erstellung festgelegt und wird hier nicht erneut übergeben.
CollectProtocolFee / CollectFundFee
Identische Form zu CPMM’s CollectProtocolFee / CollectFundFee. Unterzeichner muss mit AmmConfig.owner / AmmConfig.fund_owner übereinstimmen. Sammelt aufgelaufene Protokoll-/Fondsgebühren aus den Pool-Vaults zu einem Empfänger, setzt die entsprechenden PoolState.protocol_fees_* / fund_fees_*-Felder auf Null.
InitializeReward
Fügt einen neuen Reward-Stream zu einem Pool hinzu. Bis zu 3 Streams können gleichzeitig aktiv sein.
Argumente
Vorbedingungen
- Weniger als 3 Streams sind derzeit auf dem Pool aktiv.
- Funder zahlt
total_emission = emissions_per_second × (end_time − open_time)Wert des Reward-Tokens als Teil dieser Anweisung in den Vault ein. - Whitelisted Reward-Mint pro
operation_state.
SetRewardParams
Erweitert, füllt auf oder ändert die Emissionsrate auf einem bestehenden Reward-Stream. Typischerweise vom Pool-Ersteller oder dem Raydium-Multisig aufgerufen. Einschränkungen leben On-Chain: Sie können normalerweise end_time erweitern oder Emissionen erhöhen, nicht rückwirkend verringern. Überprüfen Sie die Eigentümerliste von operation_state.
UpdateRewardInfos
Reine Buchhaltung — setzt reward_growth_global_x64 auf die aktuelle Zeit, indem emissions_per_second × Δt / liquidity multipliziert wird. Wird intern von jeder Liquiditäts-berührenden Anweisung aufgerufen. Wird als eigenständige Anweisung bereitgestellt, da externe Akteure (UIs, Cranks) sie manchmal auslösen möchten.
CollectReward
Positionseigentümer beansprucht fällige Reward-Token.
Konten
Effekt
- Setzt Reward-Wachstum ab (gleiche Muster wie Gebühren).
- Überträgt den fälligen Betrag zur Empfänger-ATA, setzt
reward_amount_owed[i]auf Null.
Zustandsänderungsmatrix
Nächste Schritte
products/clmm/code-demos— ausführbare TypeScript-Beispiele.products/clmm/fees— Details zu Gebühren- und Reward-Abgrenzung.reference/error-codes— vollständige CLMM-Anchor-Fehlertabelle.
raydium-io/raydium-clmm—programs/amm/src/instructions- Raydium SDK v2 —
@raydium-io/raydium-sdk-v2

