Zum Hauptinhalt springen
Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Diese Seite ergänzt products/clmm/accounts (Beschreibung der Accounts) und products/clmm/math (Beschreibung der Mathematik). Sie ist maßgeblich für Argumente und Account-Reihenfolge; konkrete Byte-Layouts entnehmen Sie dem IDL.

Instruktionsübersicht

Die meisten nur-Admin-Instruktionen (CreateAmmConfig, UpdateAmmConfig, UpdatePoolStatus, CreateSupportMintAssociated, CreateOperationAccount, UpdateOperationAccount, CloseProtocolPosition) sind durch den fest programmierten admin-Pubkey des Programms geschützt. Reward-Stream-Admin-Instruktionen (TransferRewardOwner, CollectRemainingRewards) werden durch den Reward-Funder, nicht durch den Programm-Admin, kontrolliert. Das Suffix V2 bedeutet: „Token-2022 auf Vaults/NFT unterstützt, Bitmap-Extension-Slot erforderlich”. Das SDK wählt für neue Pools standardmäßig V2.

CreatePool

Argumente
Accounts (vereinfacht) Vorbedingungen
  • token_mint_0 < token_mint_1 nach Byte-Reihenfolge.
  • amm_config.disable_create_pool == false.
  • Mints werden nicht durch die Token-2022-Extension-Allowlist abgelehnt.
Nachbedingungen
  • 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_info ist auf null gesetzt (Dynamic Fee deaktiviert).

CreateCustomizablePool

Empfohlen für neue Pools. Gleiche Wirkung wie CreatePool, zusätzlich mit pool-spezifischem Fee-Erhebungsmodus und optionalem Dynamic-Fee-Opt-in. Argumente
Accounts (vereinfacht) — wie CreatePool, zusätzlich bei enable_dynamic_fee = true: Vorbedingungen — wie CreatePool. Bei enable_dynamic_fee = false wird dynamic_fee_config ignoriert. Nachbedingungen
  • pool_state.fee_on wird auf die gewählte CollectFeeOn-Variante gesetzt.
  • Wenn Dynamic Fee aktiviert wurde: pool_state.dynamic_fee_info wird aus der übergebenen DynamicFeeConfig initialisiert (fünf Kalibrierungsparameter werden kopiert; Zustandsfelder auf null gesetzt).
  • Andernfalls: pool_state.dynamic_fee_info bleibt null (= Dynamic Fee für diesen Pool dauerhaft inaktiv).
fee_on und das Dynamic-Fee-Aktivierungsbit werden ausschließlich bei der Pool-Erstellung gesetzt. Es gibt keinen nachträglichen Upgrade-Pfad — Pools, die über das Legacy-CreatePool erstellt wurden, können weder Dynamic Fee noch einseitige Gebühren nachträglich erhalten. Neue Deployments sollten standardmäßig diese Instruktion verwenden.

OpenPositionV2 / OpenPositionWithToken22Nft

Neue Position innerhalb eines bestehenden Pools erstellen. Argumente
Accounts (vereinfacht) Mathematik — siehe products/clmm/math. Abhängig von base_flag berechnet das Programm aus liquidity oder (amount_0_max, amount_1_max) das tatsächliche L sowie die tatsächlich verbrauchten Token-Beträge. Vorbedingungen
  • tick_lower < tick_upper, beide Vielfache von pool.tick_spacing, innerhalb von [MIN_TICK, MAX_TICK].
  • Erforderliche Tick-Arrays übergeben und initialisiert (oder in der Transaktion über InitTickArray-CPI erstellt).
  • Nutzer verfügt über mindestens amount_0_max und amount_1_max in den Quell-ATAs.
Nachbedingungen
  • personal_position existiert, liquidity ist gesetzt, fee_growth_inside_last wurde gespeichert.
  • Tick-Array-Einträge bei tick_lower und tick_upper aktualisiert (liquidity_gross += L, liquidity_net ± L, Fee-Growth-Snapshots gepflegt).
  • pool_state.liquidity += L, sofern die Position im Bereich liegt (tick_lower ≤ tick_current < tick_upper).
Häufige FehlerInvalidTickIndex, NotApproved, ZeroAmountSpecified, TransactionTooLarge (bei zu vielen Tick-Arrays).

IncreaseLiquidityV2

Liquidität zu einer bereits geöffneten Position hinzufügen. Argumente
Accounts — wie OpenPosition, jedoch ohne den NFT-Mint (die Position existiert bereits; das NFT wird als ATA des Inhabers mit 1 Token übergeben). Wirkung
  • Überträgt amount_0_actual / amount_1_actual vom Nutzer an die Vaults.
  • Erhöht personal_position.liquidity und pool_state.liquidity (wenn im Bereich) sowie liquidity_gross / liquidity_net der Endpunkt-Ticks entsprechend.
  • Sammelt ausstehende Gebühren und Rewards seit dem letzten Zugriff und schreibt sie in tokens_fees_owed_{0,1} / reward_amount_owed. Diese werden erst bei DecreaseLiquidity oder CollectReward ausgezahlt, nicht beim Erhöhen.

DecreaseLiquidityV2

Liquidität aus einer Position entfernen. Argumente
Accounts — gleiche Struktur wie IncreaseLiquidity. Wirkung
  • Berechnet (amount_0, amount_1) für das entfernte L auf Basis des aktuellen sqrt_price_x64.
  • Rechnet seit dem letzten Zugriff aufgelaufene Gebühren/Rewards ab, genau wie bei IncreaseLiquidity.
  • Überträgt amount_0 + fees_owed_0 und amount_1 + fees_owed_1 aus den Vaults an den Nutzer.
  • Vermindert die Liquiditätszähler; wenn personal_position.liquidity == 0 nach der Reduktion, ist die Position für ClosePosition freigegeben.
Slippageamount_0_min und amount_1_min sind die Mindestbeträge, die der Nutzer nach Abzug etwaiger Token-2022-Transfergebühren auf der Ausgabeseite akzeptiert.

ClosePosition

Das Position-NFT verbrennen und PersonalPositionState schließen. Vorbedingungen
  • personal_position.liquidity == 0.
  • tokens_fees_owed_{0,1} == 0.
  • Alle Reward-Zähler reward_amount_owed == 0.
(D. h., zunächst alles einsammeln und Liquidität auf null reduzieren.) Wirkung
  • Verbrennt das NFT.
  • Schließt den NFT-Mint-Account und den personal_position-Account; die Rent wird an den payer zurückerstattet.

SwapV2

Durchläuft die Liquiditätskurve; entweder exakter Input oder exakter Output, abhängig von is_base_input. Argumente
Accounts (vereinfacht) Aufrufer übergeben eine geordnete Liste von Tick-Arrays, die den erwarteten Swap-Pfad 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.status erlaubt Swaps.
  • now >= open_time.
  • sqrt_price_limit_x64 liegt für die gewählte Richtung auf der richtigen Seite von sqrt_price_x64.
Häufige FehlerExceededSlippage, SqrtPriceLimitOverflow, TickArrayNotFound, LiquidityInsufficient. Was SwapV2 intern tut, das Aufrufer wissen sollten (Release nach 2025):
  1. Dynamic-Fee-Zuschlag — wenn pool.dynamic_fee_info ungleich null ist, aktualisiert das Programm den Volatilitätsakkumulator anhand der seit dem letzten Swap zurückgelegten Tick-Distanz (mit den Filter-/Decay-Regeln aus products/clmm/fees) und addiert eine dynamic_fee_component zur AmmConfig.trade_fee_rate. Die Gesamtgebühr ist auf 10 % begrenzt (MAX_FEE_RATE_NUMERATOR / 1_000_000).
  2. Limit-Order-Matching — wenn der Preispfad einen Tick mit offenen Limit Orders kreuzt, füllt das Programm zuerst die verfügbare Limit-Order-Liquidität an diesem Tick (FIFO nach order_phase) und fährt dann entlang der LP-Liquiditätskurve fort. Gefüllte Beträge aktualisieren tick.unfilled_ratio_x64 und tick.part_filled_orders_remaining für die spätere Abrechnung; die Orders selbst bleiben unverändert, bis der Inhaber SettleLimitOrder aufruft.
  3. Einseitiges Fee-Routing — wenn pool.fee_on = Token0Only oder Token1Only, berechnet der Swap-Schritt denselben Input-Output-Handel; die Gebühr wird dann an die konfigurierte Seite weitergeleitet. Bei Richtungen, bei denen die konfigurierte Fee-Seite die Ausgabe ist, wird die Gebühr vom Swap-Output abgezogen (der Nutzer erhält out − fee); bei Richtungen, bei denen sie der Input ist, entspricht das Verhalten FromInput. Siehe is_fee_on_input(zero_for_one) und is_fee_on_token0(zero_for_one) auf PoolState.
Swap (V1) implementiert dieselbe Dynamic Fee, dasselbe einseitige Fee-Routing und dasselbe Limit-Order-Matching wie SwapV2; der einzige fehlende Aspekt ist die Token-2022-Unterstützung — beide Vaults müssen klassische SPL-Token sein. Pools mit einem Token-2022-Mint müssen über SwapV2 geswappt werden. Der Aggregator und das SDK bevorzugen für jedes CLMM-Leg bereits V2, sodass Aufrufer nicht nach Mint-Typ unterscheiden müssen.

OpenLimitOrder

Verkaufsorder an einem bestimmten Tick platzieren. Die Order sitzt in einer per-Tick-FIFO-Kohorte und wird gefüllt, wenn der Preis diesen Tick passiert. Argumente
Accounts (vereinfacht) Vorbedingungen
  • tick_index % pool.tick_spacing == 0 und innerhalb von [MIN_TICK, MAX_TICK].
  • tick_index liegt auf der richtigen Seite von pool.tick_current für die gewählte Richtung (token0 verkaufen → Tick muss oberhalb des aktuellen liegen, und umgekehrt). Eine Order an einem bereits überquerten Tick würde sofort gematcht und wird abgelehnt.
  • pool_state.status erlaubt Limit-Order-Operationen (Bit 5).
Nachbedingungen
  • limit_order existiert und hat tick.order_phase sowie tick.unfilled_ratio_x64 zum Öffnungszeitpunkt gespeichert.
  • tick.orders_amount += amount (in der aktuellen Kohorte).
  • limit_order_nonce.order_nonce += 1.
  • OpenLimitOrderEvent wird ausgelöst.
Häufige FehlerInvalidLimitOrderAmount (null oder unterhalb des Pool-Minimums), 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

Bestehende offene Order aufstocken. Nur durch den owner der Order aufrufbar. Argumente
Accounts — wie OpenLimitOrder, jedoch ohne den Nonce-Account; die limit_order-PDA wird direkt übergeben. Vorbedingungen
  • limit_order.owner == signer.
  • Die Order befindet sich noch in derselben Kohorte (tick.order_phase == limit_order.order_phase). Hat die Kohorte bereits begonnen sich zu füllen, ist die Order teilweise abgerechnet — der Aufrufer sollte zunächst DecreaseLimitOrder oder SettleLimitOrder aufrufen, um den Status voranzubringen.
Wirkung
  • Überträgt amount vom Inhaber-ATA an input_vault.
  • limit_order.total_amount += amount; tick.orders_amount += amount.

DecreaseLimitOrder

Offene Order reduzieren oder vollständig stornieren. Zahlt den ungefüllten Rest an den Inhaber zurück, zuzüglich bereits durch frühere Teilfüllungen abgerechneter Ausgaben. Argumente
Accounts — beide Token-Seiten (Input und Output): Wirkung
  • Berechnet den gefüllten Betrag der Order aus dem unfilled_ratio_x64 der Kohorte seit der Öffnung neu.
  • Sendet gefüllten Output an output_token_account.
  • Sendet amount des ungefüllten Inputs zurück an input_token_account.
  • Aktualisiert limit_order entsprechend. Ist der verbleibende ungefüllte Rest null, schließt das Programm den Account und erstattet die Rent an owner zurück.

SettleLimitOrder

Gefüllte Output-Token an den Inhaber übermitteln, ohne den ungefüllten Rest der Order zu ändern. Nützlich, wenn auto_withdraw-Keeper lang laufende Teilfüllungen schrittweise auszahlen möchten. Aufrufer — entweder der owner der Order oder der limit_order_admin des Programms (ein Off-Chain-operativer Hot Wallet, der eine automatisierte Keeper-Schleife betreibt). Der Keeper hat keine weitere Autorität — er kann Nutzergelder ausschließlich als gefüllten Output an die owner-ATA der Order weiterleiten. Accounts Wirkung
  • Berechnet den kumulativen geschuldeten Output anhand von (limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64).
  • Überträgt die Differenz an output_token_account.
  • Aktualisiert limit_order.settled_output.
  • Schließt die Order nicht; sie bleibt für verbleibenden Input offen.

CloseLimitOrder

Vollständig ausgeführten Order-Account schließen. Die Rent wird stets an limit_order.owner zurückgegeben, unabhängig davon, wer unterschreibt. Aufrufer — entweder owner oder limit_order_admin. Vorbedingungen
  • Die Order hat einen ungefüllten Rest von null (entweder wurde amount == total_amount gefüllt und abgerechnet, oder der Inhaber hat die Order zuvor auf null reduziert und vergessen zu schließen).
Wirkung
  • Schließt limit_order; Rent wird an limit_order.owner gesendet.

CreateDynamicFeeConfig (Admin)

Wiederverwendbaren Parametersatz unter einem u16-Index anlegen. Argumente
Accounts Häufige FehlerInvalidDynamicFeeConfigParams, wenn decay_period <= filter_period oder ein Feld mit Wert 0 außerhalb des gültigen Bereichs liegt.

UpdateDynamicFeeConfig (Admin)

Bestehende DynamicFeeConfig bearbeiten. Pools, die die Konfiguration bereits zum Erstellungszeitpunkt gespeichert haben, werden nicht rückwirkend aktualisiert; nur neu erstellte Pools, die auf diese Konfiguration verweisen, übernehmen die neuen Werte. Argumente — dieselben fünf Kalibrierungsfelder wie bei CreateDynamicFeeConfig (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator); index wird bei der Erstellung festgelegt und hier nicht erneut übergeben.

CollectProtocolFee / CollectFundFee

Identische Struktur wie CPMMs CollectProtocolFee / CollectFundFee. Der Unterzeichner muss AmmConfig.owner / AmmConfig.fund_owner entsprechen. Aufgelaufene Protokoll-/Fondsgebühren werden aus den Pool-Vaults an einen Empfänger übertragen; die entsprechenden Felder PoolState.protocol_fees_* / fund_fees_* werden auf null gesetzt.

InitializeReward

Neuen Reward-Stream an einen Pool anhängen. Maximal 3 Streams können gleichzeitig aktiv sein. Argumente
Accounts Vorbedingungen
  • Weniger als 3 Streams derzeit am Pool aktiv.
  • Der Funder hinterlegt im Rahmen dieser Instruktion total_emission = emissions_per_second × (end_time − open_time) Reward-Token im Vault.
  • Reward-Mint gemäß operation_state auf der Whitelist.

SetRewardParams

Bestehenden Reward-Stream verlängern, auffüllen oder die Emissionsrate ändern. Wird typischerweise vom Pool-Ersteller oder dem Raydium-Multisig aufgerufen. Die Einschränkungen sind on-chain: end_time kann in der Regel verlängert oder die Emissionen erhöht werden, eine rückwirkende Verringerung ist nicht möglich. Prüfen Sie die Inhaberliste von operation_state.

UpdateRewardInfos

Reine Buchhaltung — rechnet reward_growth_global_x64 durch Multiplikation von emissions_per_second × Δt / liquidity auf den aktuellen Zeitpunkt ab. Wird intern von jeder liquiditätsberührenden Instruktion aufgerufen. Als eigenständige Instruktion verfügbar, da externe Akteure (UIs, Cranks) diese Abrechnung manchmal manuell auslösen möchten.

CollectReward

Position-Inhaber beansprucht ausstehende Reward-Token. Accounts Wirkung
  • Rechnet Reward-Wachstum ab (gleiche Logik wie bei Gebühren).
  • Überträgt den geschuldeten Betrag an die Empfänger-ATA; reward_amount_owed[i] wird auf null gesetzt.

Zustandsänderungsmatrix

Weiterführende Ressourcen

Quellen: