Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Diese Seite beschreibt das Layout und die Rolle jedes Kontos. Seeds sind kanonisch und in
reference/program-addresses aufgelistet. Ein CLMM-Pool ist kontointensiver als ein CPMM-Pool, da Liquidität spärlich über den Tick-Bereich verteilt ist; das Verständnis dieser Spärlichkeit ist der Kern dieser Seite.Kontobestand
Ein aktiver CLMM-Pool wird durch die folgenden Kontofamilien beschrieben. Alle werden vom CLMM-Programm verwaltet, außer den beiden Mints und ihren Vaults.PoolState
Der Live-Status des Pools, gelesen bei jedem Swap und jeder Positionsänderung.
sqrt_price_x64undtick_currentsind der Preisstatus des Pools. Sie werden bei jedem Swap zusammen aktualisiert.tick_currentist die Untergrenze vonlog_{1.0001}(price).liquidityist die aktive Liquidität — die Summe derL-Werte für alle Positionen, deren Bereichtick_currententhält. Sie ändert sich jedes Mal, wenn ein Swap einen Tick kreuzt, und jedes Mal, wenn eine Position geöffnet/geschlossen/angepasst wird.fee_growth_global_{0,1}_x64sind die kumulativen Gebühren pro Liquiditätseinheit über die gesamte Pool-Historie. Positionen lesen dies, um zu berechnen, was ihnen geschuldet wird.tick_spacingist bei der Initialisierung an dieAmmConfiggebunden und ändert sich nie. Es bestimmt, welche Tick-Indizes als Positionsendpunkte zulässig sind.tick_array_bitmapist eine Inline-Bitmap, die den häufig verwendeten Tick-Bereich um den Spotpreis abdeckt. Für Pools, deren Positionen weit reichen, lebt die Overflow-Verfolgung in der separatenTickArrayBitmapExtension.fee_onist bei der Pool-Erstellung festgelegt.0(FromInput) reproduziert das klassische Uniswap-V3-Verhalten.1und2leiten die Swap-Gebühr auf eine einzelne Seite des Buches — sieheproducts/clmm/feesfür Abwägungen.seed_indexist[0, 0]für jeden Pool, der überCreatePool/CreateCustomizablePoolerstellt wird (ein kanonischer Pool pro Paar). Ein nicht-null Wert bedeutet, dass der Pool überCreateCustomizablePoolV2(vor 2026-10-22CreatePermissionedPoolgenannt) erstellt wurde und der Index Teil der Pool-PDA-Seeds ist, was mehrere Pools für dasselbe(config, mint0, mint1)ermöglicht. Um die Adresse eines solchen Pools erneut abzuleiten, müssen Sie seinenseed_indexkennen.dynamic_fee_infoträgt Volatilitätsstatus für den dynamischen Gebührenzuschlag. Wenn aktiviert, berechnet jeder Swap einedynamic_fee_componentzusätzlich zuAmmConfig.trade_fee_rateneu. Das Layout ist unterDynamicFeeInfounten dokumentiert; Pools ohne dynamische Gebühr lassen die gesamte Struktur null.
AmmConfig
CreateAmmConfig die hardcodierte protocol_fee_owner::ID des Programms in owner und fund_fee_owner::ID in fund_owner. Davor kopierte es den Schlüssel des Admin-Signers in beide. Bestehende Konfigurationen behalten, was sie erstellt oder rotiert wurden, also lesen Sie beide Felder vom Konto. UpdateAmmConfig-Parameter 3 / 4 rotieren sie immer noch. Adressen sind in reference/program-addresses aufgelistet.
Ein typischer veröffentlichter Satz von CLMM-Gebührentiers (bestätigen Sie gegen GET https://api-v3.raydium.io/main/clmm-config):
protocol_fee_rate und fund_fee_rate sind Anteile der Handelsgebühr; gleiche Konvention wie CPMM. Siehe products/clmm/fees.
TickArrayState
CLMM speichert nicht einen einzelnen Datensatz pro Tick. Das würde Milliarden von Konten bedeuten. Stattdessen gruppiert es TICK_ARRAY_SIZE benachbarte initialisierte oder nicht initialisierte Ticks (typischerweise 60 oder 88, je nach Programmversion) in einen TickArrayState, der bei der ersten Verwendung lazy erstellt wird.
order_phaseist die Kohorten-ID. Sie erhöht sich jedes Mal, wenn eine Kohorte von „vollständig ungefüllt” zu „teilweise gefüllt” übergeht.orders_amountist die Input-Token-Summe der aktuellen (neuesten) Kohorte.part_filled_orders_remainingverfolgt die vorherige Kohorte, die derzeit durch laufende Swaps gefüllt wird.unfilled_ratio_x64ist ein Q64.64-Multiplikator, der auf der Kohorte gespeichert wird: Wenn ein Swap X% der Kohorte füllt, wird das Verhältnis mit(1 − X)multipliziert. Jede offene Order speichert ihren eigenen(order_phase, unfilled_ratio_x64)-Snapshot zum Zeitpunkt der Eröffnung, sodass die Settle-Mathematik auf den Vergleich von Snapshots reduziert wird.
- Ein Positions-Endpunkt-Tick t muss
t % tick_spacing == 0erfüllen. Das Programm lehnt Positionen mit falscher Abstände ab. - Das Array des Ticks befindet sich unter
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Ein Tick-Array wird lazy initialisiert: Die erste Position oder der erste Swap, der ein nicht initialisiertes Array berührt, erstellt es und zahlt die Miete.
- Ein Tick-Array wird vom Programm nie geschlossen. Nach der Zuweisung bleibt es für die Lebensdauer des Pools bestehen, auch nachdem jeder Tick darin zu
liquidity_gross == 0zurückgekehrt ist. Nachfolgende Positionen und Swaps verwenden das vorhandene Konto ohne zusätzliche Miete wieder. Es gibt keinenClosePosition-gesteuerten Bereinigungspfad für Tick-Arrays.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (inline) deckt den „nahe am Spot”-Bereich ab — ±512 Tick-Arrays (TICK_ARRAY_BITMAP_SIZE = 512; das [u64; 16]-Feld ist 1.024 Bits, gleichmäßig zwischen negativen und positiven Start-Indizes aufgeteilt, also Array-Indizes −512 … +511). Außerhalb dieses Bereichs (für extreme Tick-Werte) verwaltet das Programm ein Erweiterungskonto:
(MIN_TICK, MAX_TICK)) erfordern es; das SDK löst es für Sie auf.
Positionen
Eine CLMM-Position ist ein Bündel aus drei Konten plus einem Mint:Position-NFT-Mint
Ein SPL-Token oder Token-2022-Mint mit Supply 1. Das Position-NFT in der Wallet des Besitzers ist ein ATA, das diesen einzelnen Token hält. Das Programm bindet die Autorisierung an den aktuellen Inhaber des NFT-ATA-Guthabens, nicht an einen in der State gespeicherten Pubkey. Neue Position-NFT-Mints setzenpool_state als ihre Freeze-Authority, bevor sie den einzelnen Token prägen und die Mint-Authority entfernen. Das Setzen einer Freeze-Authority friert das NFT-Konto nicht selbst ein. Das Konto bleibt ungefroren und übertragbar, es sei denn, beide Bedingungen sind erfüllt: Der Aufrufer verwendet OpenPositionV2 oder OpenPositionWithToken22Nft, und mindestens eine zugrunde liegende Vault-Mint-Freeze-Authority erscheint auf CLMMs Restricted-Issuer-Liste. Nur dann friert CLMM das NFT-Konto nach dem Prägen ein. Dies ändert keine PersonalPositionState- oder PoolState-Bytes.
PersonalPositionState
Eines pro offene Position. Basierend auf dem NFT-Mint.
ProtocolPositionState (veraltet)
Ältere CLMM-Versionen speicherten aggregierte Pro-
(pool, tick_lower, tick_upper)-Buchführung in einem ProtocolPositionState-PDA. Neuere Versionen erstellen oder lesen dieses Konto nicht mehr. Der Slot erscheint immer noch in den OpenPosition- / IncreaseLiquidity- / DecreaseLiquidity-Kontolisten als UncheckedAccount für ABI-Kompatibilität, aber das Programm schreibt nicht darauf. Vorhandene Konten in der Chain sind vestigial; der Admin kann CloseProtocolPosition aufrufen, um die Miete dafür zurückzufordern.Die aggregierte Bereichsbuchführung wird jetzt direkt aus den zwei Endpunkt-Ticks (liquidity_gross, liquidity_net und den Pro-Tick-fee_growth_outside_* / reward_growths_outside_x64) in TickArrayState abgeleitet. Die Fee-Growth-Inside-Formel fee_growth_inside = global − outside_lower − outside_upper funktioniert weiterhin ohne ein aggregiertes Positions-Konto.Observation
(tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) und dann price = 1.0001 ** tick. Siehe algorithms/clmm-math.
DynamicFeeConfig und DynamicFeeInfo
Parameter für dynamische Gebühren befinden sich an zwei Stellen. Die wiederverwendbare Vorlage — DynamicFeeConfig — wird vom Admin verwaltet und von Pools gemeinsam genutzt, die sich dafür entscheiden. Der Pro-Pool-Laufzeitzustand — DynamicFeeInfo — ist in PoolState eingebettet und wird bei jedem Swap aktualisiert.
DynamicFeeConfig
["dynamic_fee_config", index.to_be_bytes()]. Erstellt über create_dynamic_fee_config (Admin-gated) und modifiziert über update_dynamic_fee_config. Ein Pool, der mit enable_dynamic_fee = true erstellt wird, speichert die fünf Kalibrierungsparameter der Config (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) zum Erstellungszeitpunkt in seinen eigenen DynamicFeeInfo; spätere Änderungen an DynamicFeeConfig beeinflussen bestehende Pools nicht rückwirkend.
DynamicFeeInfo (eingebettet in PoolState)
DynamicFeeConfig kopiert wurde. Die Gebühren-Mathematik und die Decay-Regeln sind unter products/clmm/math und products/clmm/fees dokumentiert.
Von der Formel verwendete Konstanten:
LimitOrderState
Ein Konto pro offene Limit-Order.
- Open — Der Benutzer ruft
open_limit_orderauf, hinterlegttotal_amountdes Input-Tokens, die Order wird an eineTickState-Kohorte gebunden. - (optional) Increase / Decrease —
increase_limit_orderaddiert zutotal_amount;decrease_limit_ordergibt ungefüllte Tokens zurück (und jede bis dahin abgerechnete Ausgabe). - Settle — Wenn die Kohorte vollständig oder teilweise gefüllt ist, ruft der Besitzer oder der operationale Keeper
settle_limit_orderauf, um Output-Tokens an das ATA des Besitzers zu übertragen. - Close — Sobald
unfilled_amount == 0, ist das Konto schließbar. Die Miete wird immer anownerzurückgegeben.
[owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. Das Order-PDA ist daher eindeutig pro (owner, nonce_index, order_nonce).
LimitOrderNonce
Ein Pro-(wallet, nonce_index)-Zähler, der es einem einzelnen Benutzer ermöglicht, mehrere parallele Pipelines von Limit-Orders auszuführen, ohne auf PDAs zu kollidieren.
[user_wallet.as_ref(), &[nonce_index]]. Die meisten Clients verwenden nonce_index = 0 und lassen order_nonce die Kardinalität tragen.
Permission (veraltet)
Das Permission-Konto wurde im Upgrade vom 2026-10-22 entfernt. Es sperrte früher CreatePermissionedPool, das jetzt die erlaubnisfreie CreateCustomizablePoolV2 ist. Das Programm liest oder schließt diese Konten nicht mehr, und die Anweisungen CreatePermissionPda / ClosePermissionPda sind weg. PDAs, die vor dem Upgrade erstellt wurden (["permission", authority], 280 Bytes), bleiben als inerte Daten in der Chain; ignorieren Sie sie beim Scannen von CLMM-eigenen Konten.
Ableitung der Schlüsselkonten
reference/program-addresses überprüft werden.
Lebenszyklus-Kurzreferenz
TickArrayState-Konten werden vom Programm niemals geschlossen — sie bleiben für die Lebensdauer des Pools bestehen. Sobald ein Tick-Array initialisiert wurde, bleibt es in der Chain, auch wenn jeder Tick darin zu liquidity_gross == 0 zurückkehrt. Die Wiederverwendung eines bestehenden Tick-Arrays ist kostenlos; nur die erste Position, die ein noch nie initialisiertes Array berührt, zahlt dessen Miete.
Was wo zu lesen ist
- Tick-Mathematik und Range-Mechaniken:
products/clmm/ticks-and-positions. - Swap-Ablauf und Fee-Growth-Mathematik:
products/clmm/math. - Anweisungs-Kontolisten:
products/clmm/instructions. - Gebühren und Reward-Abgrenzung:
products/clmm/fees. - Kanonische Programm-IDs und Seeds:
reference/program-addresses.

