Documentation Index
Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
Use this file to discover all available pages before exploring further.
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 Accounts. Die Seeds sind kanonisch und unter
reference/program-addresses aufgeführt. Ein CLMM-Pool benötigt mehr Accounts als ein CPMM-Pool, da Liquidität dünn verteilt über den Tick-Bereich gespeichert wird — das Verstehen dieser Verteilung ist der Kerninhalt dieser Seite.Account-Übersicht
Ein aktiver CLMM-Pool wird durch folgende Account-Familien beschrieben. Alle gehören dem CLMM-Programm, mit Ausnahme der beiden Mints und ihrer Vaults.| Account | Zweck | Anzahl pro Pool |
|---|---|---|
AmmConfig | Fee-Tier: Handelsgebühr, Protokollanteil, Fondsanteil, Standard-Tick-Spacing. Wird von allen Pools dieses Tiers geteilt. | 1 (geteilt) |
PoolState | Aktueller sqrt_price_x64, aktueller Tick, Gesamtliquidität, globales Fee-Wachstum, Reward-Info, Observations-Zeiger. | 1 |
TickArrayState | Ein Block aus TICK_ARRAY_SIZE benachbarten Ticks. Wird nur bei Bedarf initialisiert. | 0 ≤ N ≤ Bereich |
TickArrayBitmapExtension | Overflow-Bitmap, die nachverfolgt, welche Tick-Arrays außerhalb der inline-Bitmap in PoolState vorhanden sind. | 0 oder 1 |
PersonalPositionState | Einer pro LP-Position. Speichert den Bereich, die Liquidität und das zuletzt gesehene Fee-/Reward-Wachstum. Authority = NFT-Inhaber. | 1 pro Position |
| Position-NFT-Mint | Mint mit Supply 1, verknüpft mit PersonalPositionState. Die Übertragung des NFTs überträgt die Position. | 1 pro Position |
ObservationState | Ringpuffer mit Preisbeobachtungen für den TWAP. | 1 |
token_0_vault, token_1_vault | Token-Accounts mit den Pool-Guthaben. Eigentümer: Pool-Authority. | 2 |
DynamicFeeConfig | Wiederverwendbarer Parametersatz für den dynamischen Gebührenmechanismus. Pools, die via create_customizable_pool erstellt wurden, können ihn aktivieren. Admin-verwaltet. | geteilt (pro Index) |
LimitOrderState | Einer pro offenem Limit-Order. Enthält Inhaber, Tick, Richtung, Gesamtbetrag und Snapshot des abgerechneten Outputs. | 1 pro Order |
LimitOrderNonce | Pro-(wallet, nonce_index)-Zähler, der eindeutige Order-PDAs ableitet. | 1 pro (Wallet, Index) |
PoolState
Der Live-Zustand des Pools, der bei jedem Swap und jeder Positionsänderung gelesen wird.
sqrt_price_x64undtick_currentstellen den Preisstatus des Pools dar. Sie werden bei jedem Swap gemeinsam aktualisiert.tick_currentist der ganzzahlige Anteil vonlog_{1.0001}(price).liquidityist die aktive Liquidität — die Summe derL-Werte aller Positionen, deren Bereichtick_currententhält. Sie ändert sich, sobald ein Swap einen Tick kreuzt oder eine Position geöffnet, geschlossen oder angepasst wird.fee_growth_global_{0,1}_x64sind die kumulierten Gebühren pro Liquiditätseinheit über die gesamte Pool-Geschichte. Positionen lesen diesen Wert, um ihren ausstehenden Anteil zu berechnen.tick_spacingwird bei der Initialisierung an denAmmConfiggebunden und ändert sich nie. Es legt fest, welche Tick-Indizes als Positionsendpunkte zulässig sind.tick_array_bitmapist eine inline Bitmap, die den üblicherweise genutzten Tick-Bereich um den Spotpreis abdeckt. Für Pools, deren Positionen weiter außerhalb liegen, lebt die Overflow-Nachverfolgung im separatenTickArrayBitmapExtension-Account.fee_onwird bei der Pool-Erstellung festgelegt.0(FromInput) reproduziert das klassische Uniswap-V3-Verhalten.1und2leiten die Swap-Gebühr an eine einzelne Seite des Buches weiter — sieheproducts/clmm/feesfür die jeweiligen Abwägungen.dynamic_fee_infoenthält den Volatilitätsstatus für den dynamischen Gebührenzuschlag. Wenn aktiviert, berechnet jeder Swap einendynamic_fee_componentzusätzlich zuAmmConfig.trade_fee_rate. Das Layout ist unterDynamicFeeInfoweiter unten dokumentiert; Pools ohne dynamische Gebühr lassen die gesamte Struktur auf null.
AmmConfig
GET https://api-v3.raydium.io/main/clmm-config verifizieren):
| Index | trade_fee_rate | Tick-Spacing | Typische Verwendung |
|---|---|---|---|
| 0 | 100 (0,01 %) | 1 | Stabile Paare, USDC/USDT |
| 1 | 500 (0,05 %) | 10 | Korrelierte Blue-Chips |
| 2 | 2_500 (0,25 %) | 60 | Standardpaare |
| 3 | 10_000 (1,00 %) | 120 | Volatile oder Long-Tail-Assets |
protocol_fee_rate und fund_fee_rate sind Anteile der Handelsgebühr — gleiche Konvention wie bei CPMM. Siehe products/clmm/fees.
TickArrayState
CLMM speichert keinen einzelnen Eintrag pro Tick — das wären Milliarden von Accounts. Stattdessen fasst es TICK_ARRAY_SIZE benachbarte, initialisierte oder nicht initialisierte Ticks (typischerweise 60 oder 88, je nach Programmversion) in einem TickArrayState zusammen, der bei erster Verwendung lazily angelegt wird.
order_phaseist die Kohorten-ID. Sie wird jedes Mal erhöht, wenn eine Kohorte von „vollständig ungefüllt” auf „teilweise gefüllt” übergeht.orders_amountist der Input-Token-Gesamtbetrag der aktuellen (neuesten) Kohorte.part_filled_orders_remainingverfolgt die vorherige Kohorte, die gerade durch laufende Swaps gefüllt wird.unfilled_ratio_x64ist ein Q64.64-Multiplikator der Kohorte: 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 Eröffnungszeitpunkt, sodass die Abrechnungsrechnung auf einen Snapshot-Vergleich reduziert wird.
- Ein Positionsendpunkt-Tick t muss
t % tick_spacing == 0erfüllen. Das Programm lehnt Positionen mit ungültigem Spacing ab. - Das Array eines Ticks befindet sich bei
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Ein Tick-Array wird lazily initialisiert: Die erste Position oder der erste Swap, der ein nicht initialisiertes Array berührt, legt es an und übernimmt die Miete.
- Ein Tick-Array wird vom Programm nie geschlossen. Einmal angelegt, bleibt er für die Lebensdauer des Pools bestehen, auch wenn alle darin enthaltenen Ticks wieder
liquidity_gross == 0erreichen. Folgende Positionen und Swaps nutzen den bestehenden Account ohne zusätzliche Miete. Es gibt keinenClosePosition-gesteuerten Bereinigungspfad für Tick-Arrays.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (inline) deckt den „nahe am Spotpreis”-Bereich ab — ±1.024 Tick-Arrays. Außerhalb dieses Bereichs (für extreme Tick-Werte) verwaltet das Programm einen Extension-Account:
(MIN_TICK, MAX_TICK)) benötigen ihn; das SDK löst ihn für Sie auf.
Positionen
Eine CLMM-Position ist ein Bündel aus drei Accounts plus einem Mint:Position-NFT-Mint
Ein SPL-Token-Mint mit Supply 1. Die Adresse des Mints ist ein deterministischer PDA; das Position-NFT im Wallet des Inhabers ist lediglich ein ATA, das dieses einzelne Token hält. Die Übertragung des NFTs ist der Mechanismus, über den eine Position den Besitzer wechselt — das Programm knüpft die Autorisierung an den aktuellen Inhaber des ATA-Guthabens des NFTs, nicht an einen in State gespeicherten Pubkey.PersonalPositionState
Einer pro offener Position. Abgeleitet vom NFT-Mint.
ProtocolPositionState (veraltet)
Ältere CLMM-Versionen speicherten aggregierte Buchführung pro
(pool, tick_lower, tick_upper) in einem ProtocolPositionState-PDA. Neuere Versionen erstellen oder lesen diesen Account nicht mehr. Der Slot erscheint in den Account-Listen von OpenPosition / IncreaseLiquidity / DecreaseLiquidity noch als UncheckedAccount für ABI-Kompatibilität, aber das Programm schreibt nicht mehr darin. Bestehende Accounts on-chain sind Relikte; der Admin kann CloseProtocolPosition aufrufen, um die Miete zurückzugewinnen.Die aggregierte Bereichsbuchführung wird jetzt direkt aus den beiden Endpunkt-Ticks (liquidity_gross, liquidity_net sowie die Tick-spezifischen fee_growth_outside_* / reward_growths_outside_x64) im TickArrayState abgeleitet. Die Fee-Growth-Inside-Formel fee_growth_inside = global − outside_lower − outside_upper funktioniert weiterhin ohne aggregierten Positions-Account.Observation
(tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) und anschließend price = 1.0001 ** tick. Siehe algorithms/clmm-math.
DynamicFeeConfig und DynamicFeeInfo
Dynamische Gebührenparameter befinden sich an zwei Stellen. Die wiederverwendbare Vorlage — DynamicFeeConfig — wird vom Admin verwaltet und von Pools geteilt, die sich anmelden. Der Pool-spezifische Laufzeitzustand — DynamicFeeInfo — ist in PoolState eingebettet und wird bei jedem Swap aktualisiert.
DynamicFeeConfig
["dynamic_fee_config", index.to_be_bytes()]. Wird über create_dynamic_fee_config (Admin-gesperrt) erstellt und über update_dynamic_fee_config geändert. Ein Pool, der mit enable_dynamic_fee = true erstellt wird, übernimmt die fünf Kalibrierungsparameter (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) bei der Erstellung in seine eigene DynamicFeeInfo; spätere Änderungen am DynamicFeeConfig wirken sich nicht rückwirkend auf bestehende Pools aus.
DynamicFeeInfo (eingebettet in PoolState)
DynamicFeeConfig kopiert wurden. Die Gebührenberechnung und die Decay-Regeln sind unter products/clmm/math und products/clmm/fees dokumentiert.
Von der Formel verwendete Konstanten:
| Konstante | Wert | Bedeutung |
|---|---|---|
VOLATILITY_ACCUMULATOR_SCALE | 10_000 | Granularität des Volatilitätsakkumulators |
REDUCTION_FACTOR_DENOMINATOR | 10_000 | Nenner für reduction_factor |
DYNAMIC_FEE_CONTROL_DENOMINATOR | 100_000 | Nenner für dynamic_fee_control |
MAX_FEE_RATE_NUMERATOR | 100_000 | Harte Obergrenze von 10 % für die resultierende Gebührenrate |
LimitOrderState
Einer pro offener Limit-Order.
- Eröffnen — Der Nutzer ruft
open_limit_orderauf, hinterlegttotal_amountdes Input-Tokens; die Order wird an eineTickState-Kohorte gebunden. - (optional) Erhöhen / Verringern —
increase_limit_ordererhöhttotal_amount;decrease_limit_ordergibt ungefüllte Token zurück (und jeden bis dahin abgerechneten Output). - Abrechnen — Wenn die Kohorte vollständig oder teilweise gefüllt ist, ruft der Inhaber oder der operationale Keeper
settle_limit_orderauf, um Output-Token an das ATA des Inhabers zu übertragen. - Schließen — Sobald
unfilled_amount == 0, kann der Account geschlossen werden. Die Miete geht immer anownerzurück.
[owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. Der Order-PDA ist daher eindeutig pro (owner, nonce_index, order_nonce).
LimitOrderNonce
Pro-(wallet, nonce_index)-Zähler, der es einem einzelnen Nutzer ermöglicht, mehrere parallele Pipelines von Limit-Orders zu betreiben, ohne PDA-Kollisionen zu verursachen.
[user_wallet.as_ref(), &[nonce_index]]. Die meisten Clients verwenden nonce_index = 0 und lassen order_nonce die Kardinalität tragen.
Ableitung der wichtigsten Accounts
reference/program-addresses gegengeprüft werden.
Kurzreferenz Lebenszyklus
| Ereignis | Erstellte Accounts | Gelöschte Accounts |
|---|---|---|
CreatePool | poolState, observation, token_0_vault, token_1_vault | — |
OpenPosition[WithToken22Nft] | NFT-Mint + ATA, personalPosition, ggf. neue tickArrayState(s), tickArrayBitmapExtension falls noch nicht vorhanden | — |
IncreaseLiquidity | Ggf. neue tickArrayState(s) | — |
DecreaseLiquidity | — | Ggf. Tick-Einträge werden geleert (aber tickArrayState selbst wird nicht geschlossen) |
ClosePosition | — | NFT-Mint, personalPosition |
SwapV2 | Ggf. neuer tickArrayState | — |
OpenLimitOrder | limitOrderState, ggf. limitOrderNonce (init-if-needed), ggf. neuer tickArrayState | — |
IncreaseLimitOrder | — | — |
DecreaseLimitOrder | — | Schließt limitOrderState, wenn die Order vollständig verbraucht ist |
SettleLimitOrder | — | — |
CloseLimitOrder | — | limitOrderState (Miete → owner) |
CreateDynamicFeeConfig | dynamicFeeConfig | — |
CreateCustomizablePool | poolState, observation, Vaults — wie CreatePool. Übernimmt dynamicFeeConfig, wenn enable_dynamic_fee = true. | — |
CollectRewards | — | — |
UpdateRewardInfos | — | — |
CloseProtocolPosition (Admin) | — | Veralteter protocolPositionState (Miete → Admin) |
TickArrayState-Accounts werden vom Programm nie geschlossen — sie bleiben für die gesamte Lebensdauer des Pools bestehen. Einmal initialisiert, verbleibt ein Tick-Array on-chain, auch wenn jeder darin enthaltene Tick wieder liquidity_gross == 0 erreicht. Die Wiederverwendung eines bestehenden Tick-Arrays ist kostenlos; nur die erste Position, die ein noch nie initialisiertes Array berührt, übernimmt dessen Miete.
Was wo nachzulesen ist
- Tick-Mathematik und Bereichsmechanik:
products/clmm/ticks-and-positions. - Swap-Walk und Fee-Growth-Mathematik:
products/clmm/math. - Instruction-Account-Listen:
products/clmm/instructions. - Gebühren und Reward-Ansammlung:
products/clmm/fees. - Kanonische Programm-IDs und Seeds:
reference/program-addresses.


