Zum Hauptinhalt springen

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 →

Die Invariante

Der Pool erhält coin_reserve × pc_reserve = k, wobei:
coin_reserve = coin_vault_balance
             + orders_posted_on_openbook.base
             + pending_coin_fill_not_yet_settled
pc_reserve   = pc_vault_balance
             + orders_posted_on_openbook.quote
             + pending_pc_fill_not_yet_settled
             - accrued_pnl_pc
Zwei wichtige Punkte:
  1. Die Reserven enthalten auf OpenBook eingegangene Beträge. Die Limitorder des AMM bleiben Teil seiner Liquidität – sie gehen nicht an das Orderbuch „verloren”, sondern sind dort nur hinterlegt. Die Berechnung von k nur aus den On-Chain-Vault-Saldos unterschätzt die tatsächlichen Reserven.
  2. Der PnL-Rückgang (need_take_pnl_*) wird subtrahiert, damit die Kurve erhalten bleibt, wenn der Admin Gebühren einzieht. Das gleiche Prinzip wie die protocol_fees_*-Ausnahme bei CPMM.
Jeder Swap*-Vorgang sichert k' ≥ k ab, nachdem der Gebührenanteil des LP wieder zu den Reserven hinzugefügt wurde.

Gebührenkonvention

AMM v4 verwendet Verhältnisgebühren (Zähler/Nenner-Paare) statt der 1/1_000_000-Konvention von CPMM/CLMM. Die On-Chain-Fees-Struktur (siehe Fees::initialize im Programmquellcode) hat folgende Standardwerte:
Fees {
  min_separate_numerator:    5,
  min_separate_denominator:  10_000,   //  5/10_000 = 0.05%

  trade_fee_numerator:      25,
  trade_fee_denominator:    10_000,    // 25/10_000 = 0.25% — wird für Limitorder-Preisbildung bei OpenBook verwendet

  pnl_numerator:            12,
  pnl_denominator:          100,       // 12/100   = 12%   — Anteil des Protokolls VON der Swap-Gebühr

  swap_fee_numerator:       25,
  swap_fee_denominator:     10_000,    // 25/10_000 = 0.25% — Bruttogebühr für AMM-Pfad-Swaps
}
Interpretation (veröffentlichte Mainnet-Standardwerte):
  • Gesamte Swap-Gebühr: swap_fee = amount_in × 25 / 10_000 = 0,25% des Brutto-Eingabebetrags.
  • Protokollanteil: pnl_numerator / pnl_denominator = 12 / 100 = 12% der Swap-Gebühr, was 0,25% × 12% = 0,03% des Volumens entspricht. Dieser Anteil sammelt sich in den PnL-Zählern an und wird durch WithdrawPnl entnommen.
  • LP-Anteil: Die verbleibenden 88% der Swap-Gebühr, was 0,25% × 88% = 0,22% des Volumens entspricht. Bleiben im Pool und erhöhen k.
  • Kein Fondsanteil. AMM v4 hat keine Fondsgebühren-Aufteilung wie CPMM/CLMM.
Beachten Sie, dass pnl_numerator / pnl_denominator ein Bruchteil der Gebühr ist, nicht des Handelsvolumens – eine häufige Fehlinterpretation dieser Feldnamen. trade_fee_numerator / trade_fee_denominator (auch 25 / 10_000) ist ein separates Feld, das von der OpenBook-Integration beim Berechnen von gebühreninklusiven Preisen für das Gitter von Limitorder des AMM verwendet wird. Es entspricht standardmäßig swap_fee, wird aber über einen anderen Code-Pfad ausgelesen. Abweichungen von diesen Standardwerten sind selten, es gibt aber einige auf älteren Pools. Lesen Sie die Gebühren immer aus AmmInfo.fees aus, bevor Sie Preise angeben.

Direkter Swap (AMM-Pfad)

Der einfachste Fall: Der Benutzer tauscht gegen die Vault des Pools aus, ohne mit OpenBook zu interagieren. Die internen Reserven des Pools (einschließlich On-Book-Zuordnungen) sind der Nenner. SwapBaseIn (genaue Eingabe):
amount_after_fee = amount_in − ceil(amount_in × swap_fee_numerator / swap_fee_denominator)
amount_out = amount_after_fee × out_reserve
           / (in_reserve + amount_after_fee)
require(amount_out >= minimum_amount_out)
Die hier verwendeten Reserven sind die effektiven Reserven. Historisch war dies coin_vault_balance + coin_posted_on_openbook + ... (der Vault des AMM plus die Token, die in OpenBook-Orders gesperrt waren). Seit der OpenBook-Deaktivierung ist der On-Book-Saldo null, daher entsprechen die effektiven Reserven den reinen Vault-Bilanzen. Der MonitorStep/Implicit-Settle-Pfad, der früher die OpenBook-Seite aktualisierte, wird in der Praxis nicht mehr benötigt. SwapBaseOut (genaue Ausgabe):
amount_in_after_fee = ceil(in_reserve × amount_out / (out_reserve − amount_out))
amount_in_gross     = ceil(amount_in_after_fee × swap_fee_denominator
                            / (swap_fee_denominator − swap_fee_numerator))
require(amount_in_gross <= maximum_amount_in)

Orderbook-Interaktion (historisch)

Nicht mehr aktiv. Die in diesem Abschnitt beschriebene Gitterkonstruktion zeigt, wie AMM v4 ursprünglich die Kurve auf einem OpenBook-Markt abbildete. Die OpenBook-Integration wurde deaktiviert; Pools veröffentlichen oder verwalten keine Order mehr auf OpenBook. Die Mathematik unten wird zu Dokumentationszwecken beibehalten – sie erklärt, wofür die On-Chain-Konten target_orders/amm_open_orders dimensioniert wurden und warum das Programm weiterhin MonitorStep-bezogene Parameter validiert, obwohl der Keeper sie nicht mehr ausführt.
Getrennt von Benutzer-Swaps platzierte AMM v4 historisch ein Gitter von Limitorder auf dem OpenBook-Markt. Das Gitter wurde aus AmmInfo-Parametern berechnet:
  • depth – Anzahl der Preisstufen pro Seite.
  • amount_wave – Basiseinheit der Größe pro Stufe.
  • min_size, coin_lot_size, pc_lot_size – OpenBook-Marktbeschränkungen.
  • state_data.swap_acc_coin_fee, swap_acc_pc_fee – kumulative Gebührenzähler seit letztem TakePnl.
Das Programm leitet Preise pro Stufe ab, indem es vom aktuellen Kurspreis in konstanten Verhältnisschritten ausgeht:
price_level(k) = curve_price × (1.0001 ^ k)       # konzeptionell
size_level(k)  = amount_wave × f(depth, k)        # reduziert durch depth
Die genauen Preise und Größen werden durch target_orders bestimmt, die in build_orders berechnet und bei jedem MonitorStep mit amm_open_orders verglichen werden. Jede Abweichung führt zu Annullierungen und neuen Orders. Neu gefüllte Order auf OpenBook werden bei der nächsten Operation, die die OpenBook-Seite aktualisiert, in die Pool-Vault abgerechnet. Integratoren müssen das Gitter selten selbst berechnen – der Raydium-Keeper verwaltet es – aber es ist nützlich zu wissen, dass:
  • Ein Pool mit erheblicher On-Book-Liquidität diese Liquidität zu k beiträgt, nicht untätig ruht.
  • Ein veralteter OpenBook-Markt (Event-Queue voll, Cranks blockiert) verhindert Gitter-Updates; der AMM kann dann Preise angeboten, die vom sichtbaren Orderbook abweichen, bis zum nächsten Crank.

Abrechnung (PnL)

Der 0,03%-Protokollanteil sammelt sich in state_data.need_take_pnl_coin und state_data.need_take_pnl_pc an. TakePnl verschiebt diese Beträge aus den Vault zum Admin-angegebenen Ziel und setzt die Zähler zurück. Entscheidende Eigenschaft: Reserven in der Invariante werden immer minus aufgelaufenem PnL berechnet, daher beweget TakePnl die Kurve nicht. Dies entspricht der CPMM-Konvention.

Praktisches Beispiel

Pool-Zustand:
  • coin_reserve = 1_000_000_000_000 (1.000.000 Coin-Seite; 6 Dezimalstellen)
  • pc_reserve = 2_000_000_000_000 (2.000.000 PC-Seite; 6 Dezimalstellen)
  • Gebühren: Standard swap = 25/10_000, pnl = 3/10_000.
Benutzer: SwapBaseIn mit genaue Eingabe 1_000_000_000 Coin (1.000 Coin).
swap_fee        = ceil(1_000_000_000 * 25 / 10_000)    = 2_500_000
amount_after_fee =                                      997_500_000

amount_out = amount_after_fee * pc_reserve
           / (coin_reserve + amount_after_fee)
           = 997_500_000 * 2_000_000_000_000
           / (1_000_000_000_000 + 997_500_000)
           ≈ 1_995_015_009  (1.995,015 PC)

// Von der 2_500_000 Swap-Gebühr:
pnl_share = 2_500_000 * 3 / 25  = 300_000    (geht an Protokoll via need_take_pnl_coin)
lp_share  = 2_500_000 * 22 / 25 = 2_200_000  (bleibt in coin_reserve)

new coin_reserve = 1_000_000_000_000 + 1_000_000_000                 = 1_001_000_000_000
                   (von dem 300_000 aufgelaufener PnL ist)
  curve coin_reserve = 1_001_000_000_000 − 300_000 = 1_000_999_700_000
new pc_reserve   = 2_000_000_000_000 − 1_995_015_009                 ≈ 1_998_004_984_991

k' = curve_coin_reserve * new_pc_reserve
   ≈ 2.000_002_701E24
k  = 1_000_000_000_000 * 2_000_000_000_000
   = 2.0E24
k' > k   ✓
Der LP-Anteil (2_200_000) wird nirgendwo separat ausgebrochen – er ist einfach der Rest, der k' erhöht.

Präzisionsregeln

  • Reserve-Multiplikationen verwenden u128; endgültige Divisionen runden gegen null.
  • swap_fee rundet auf (damit der Pool nicht untergebührt).
  • amount_in für SwapBaseOut rundet auf (damit der Benutzer nicht unterbezahlt).
  • Pools mit extremen Reserveverhältnissen können ZeroTradingTokens bei sehr kleinen Eingaben treffen; gleiches Verfahren wie CPMM.

Einschränkungen im Vergleich zu CPMM

  • Die Reserven von AMM v4 enthalten den OpenBook-hinterlegten Anteil, daher kann ein Integrator nicht korrekt nur aus getTokenAccountBalance zitieren. Holen Sie sich immer den vollständigen Zustand (Vault + open_orders.free + open_orders.locked), oder verwenden Sie das SDK/API-Angebot.
  • AMM v4 stellt keine strukturierte On-Chain-TWAP zur Verfügung. Externe Verbraucher, die einen AMM-v4-gestützten Preis benötigen, müssen ihn selbst aus Handelsprotokollen berechnen.
  • Token-2022 wird nicht unterstützt.

Nächste Schritte

Quellen: