Ana içeriğe atla

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.

Bu sayfa yapay zekâ tarafından otomatik olarak çevrilmiştir. İngilizce sürüm esas alınır.İngilizce sürümü görüntüle →
Bu sayfa CLMM’nin arkasındaki türetmeleri bir araya getirir. Zincir üzerindeki uygulama için, bkz. products/clmm/math (bu sayfaya atıfta bulunur) ve products/clmm/ticks-and-positions (tick ızgarasını motive eder).

Neden sqrt-fiyat, sadece fiyat değil

Uniswap-v3-benzeri CLMM’ler fiyatı karekök olarak gösterir ve sabit nokta Q64.64 içinde depolar:
sqrt_price_x64 = floor(sqrt(price) · 2^64)
Üç sebep:
  1. Doğrusal likidite matematiği. Bir fiyat aralığındaki token0 veya token1 miktarı, price değil sqrt_price doğrusal bir fonksiyonudur. sqrt_price depolamak, swap adımının karekök hesaplamadan bu doğrusal formülleri değerlendirmesine izin verir.
  2. Taşma kontrolü. sqrt_price · L tüm makul parametreler için u256 içine sığar; price · L çok daha erken taşabilir.
  3. Tick matematiği tekdüze. Tick’ler 1.0001^i olarak tanımlandığından, sqrt(price) = 1.00005^i de tam bir 1.00005 kuvvetleridir. Her tick-geçişi sqrt_price_x64 uzayında küçük bir çarpmaya çevirisi.
Fiyat ve sqrt-fiyat bire-birdir; dönüşüm price = (sqrt_price_x64 / 2^64)^2.

Tick ızgarası

Fiyatlar bir ızgaraya ayrıştırılır:
price(tick_i) = 1.0001^i
tick_i bir i32. Canlı aralık [MIN_TICK, MAX_TICK] = [−443636, 443636] olup kabaca [2^−128, 2^128] fiyat aralığı verir. Her havuzun tick_spacing’i, ücret katmanı tarafından ayarlanır: sıkı çiftler için daha küçük aralıklar (örn. stablecoin %0.01 katmanı aralık 1 kullanır), değişken çiftler için daha büyük aralıklar (%0.25 katmanı 60 kullanır, %1 katmanı 120). Pozisyonlar tick_lower ve tick_upper değerlerinin tick_spacing ile hizalı olması gerekir. Havuzun aktif tick’leri (likiditenin başladığı veya bittiği yerler) swap adımının önem verdiği tek tick’lerdir.

Likidite-miktar

Likidite L ve fiyat aralığı [sqrt_lo, sqrt_hi] (tüm sqrt_price değerleri) içeren bir pozisyon için:
Havuz durumuToken0 miktarıToken1 miktarı
Fiyat aralığın üzerinde (sqrt_p ≥ sqrt_hi)0L · (sqrt_hi − sqrt_lo)
Fiyat aralık içindeL · (sqrt_hi − sqrt_p) / (sqrt_p · sqrt_hi)L · (sqrt_p − sqrt_lo)
Fiyat aralığın altında (sqrt_p ≤ sqrt_lo)L · (sqrt_hi − sqrt_lo) / (sqrt_lo · sqrt_hi)0
Türetim: CPMM değişmezini yerel olarak diferansiyel alınız. Herhangi bir tek tick aralığı içinde, pozisyon sanal rezervleri (x_v, y_v) ile CPMM olarak davranır ve havuzun geçerli (sqrt_p, L) ile L = sqrt(x_v · y_v) tutarlı olacak şekilde seçilir. sqrt_p’den aralık sınırına integre etmek yukarıdaki miktarları verir. Ters formüller (verilen amount0 veya amount1 için pozisyon mint ederken kullanılır):
L_from_amount0(amount0, sqrt_lo, sqrt_hi, sqrt_p) =
    amount0 · sqrt_p · sqrt_hi / (sqrt_hi − sqrt_p)

L_from_amount1(amount1, sqrt_lo, sqrt_hi, sqrt_p) =
    amount1 / (sqrt_p − sqrt_lo)

// Aralıkta olan pozisyona simetrik depozito için minimumu alınız.
L = min(L_from_amount0, L_from_amount1)

Tek-tick swap adımı

Tek bir tick aralığı içinde havuz CPMM gibi davranır. Mevcut sqrt_p ve hedef sqrt_target verildiğinde:
Δamount0_step = L · (sqrt_target − sqrt_p) / (sqrt_p · sqrt_target)     // token0 için swap yapılıyorsa
Δamount1_step = L · (sqrt_target − sqrt_p)                              // token1 için swap yapılıyorsa

Tam-giriş adımı

Δin_remaining verildiğinde:
// Tick sınırına doldurmak için aday yeni sqrt_p:
sqrt_after_full = sqrt_target
amount_to_full  = Δamount_in_to_reach(sqrt_p → sqrt_target)

if Δin_remaining ≥ amount_to_full:
    // Kovasının geri kalanını tüket
    sqrt_p'         = sqrt_target
    Δin_consumed    = amount_to_full
    Δout            = amount_out_at_boundary
else:
    // Geçmeyiz; terminal sqrt_p için çöz
    sqrt_p'         = L · sqrt_p / (L + Δin_remaining · sqrt_p)      // 0→1 swapları için
    Δin_consumed    = Δin_remaining
    Δout            = L · (sqrt_p − sqrt_p')                          // Δsqrt'ye orantılı
0→1 swap sqrt_p’yi düşürür (fiyat token0 satarken düşer). 1→0 swap bunu yükseltir. Formüller sqrt_p ve sqrt_target yer değişmişken simetriktir.

Tam-çıkış adımı

Aynı yapı, bunun yerine Δin için çözer.

Çok-tick swap döngüsü

Bir swap giriş tükenene veya fiyat sınırına çarpılana kadar tick’ler üzerinde yinelenir:
while Δin_remaining > 0 and sqrt_p != sqrt_price_limit:
    next_tick = find_next_initialized_tick(pool.tick_current, direction)
    sqrt_target = min(next_tick.sqrt_price, sqrt_price_limit)       // yönsel olarak

    (Δin, Δout, sqrt_p') = single_step(sqrt_p, sqrt_target, L, Δin_remaining)

    Δin_remaining -= Δin
    accumulated_out += Δout

    if sqrt_p' == next_tick.sqrt_price:
        // tick'i geçme
        L += next_tick.liquidity_net * direction_sign
        flip_fee_growth_outside(next_tick)
        match_limit_orders_at_tick(next_tick, ...)        // bkz products/clmm/math
        pool.tick_current = next_tick.tick_index
    sqrt_p = sqrt_p'
Her single_step havuzun mevcut L’sini kullanır. L sadece başlatılmış bir tick geçildiğinde değişir. Tick’ler arasındaki likidite sabittir, bu da adım matematik kapalı-formunu mümkün kılar. Bir tick’teki liquidity_net o tick’te başlayan pozisyon likiditeleri eksi orada biten likiditelerin imzalı toplamıdır. Yukarı doğru geçiş liquidity_net ekler; aşağı doğru geçiş çıkarır. Havuzda bir tick’te limit emirleri açık olduğunda, geçiş-tick adımı aynı zamanda swap girişinin bir kısmını faydalı olarak bu emirleri doldurmak için tüketir (kohortlar arasında FIFO). Eşleştirme algoritması ve tabanfiyat adımının üstüne uygulanabilen dinamik-ücret artışı products/clmm/math içinde belgelenmiştir; yukarıdaki kapalı-formül tek-adım formüllerini değiştirmezler.

Ücret-büyüme biriktiriciler

CLMM, aktif likidite başına ücretleri, her tarafı, global ve tick başına izler:
fee_growth_global_0_x64     // Q64.64, monoton
fee_growth_global_1_x64
tick.fee_growth_outside_0_x64   // "bu tick aktif aralığın dışında iken biriken ücretler"
tick.fee_growth_outside_1_x64
Her single_step üzerinde:
step_lp_fee = (Δin · fee_rate) · (1 − protocol_fraction − fund_fraction)
fee_growth_global += step_lp_fee · 2^64 / L     // sadece giriş tarafı için
(Diğer tarafın fee_growth_global bu adımda hareket etmez, çünkü o tarafta hiçbir token giriş olarak ödenmedi.) Bir tick geçildiğinde, program fee_growth_outside’ı çevirir:
tick.fee_growth_outside_0_x64 = fee_growth_global_0_x64 − tick.fee_growth_outside_0_x64
tick.fee_growth_outside_1_x64 = fee_growth_global_1_x64 − tick.fee_growth_outside_1_x64
“Dışarı” tick_current’e göreldir. tick_current tick’in üzerinde olduğunda, dışarı “aşağı” anlamına gelir. tick_current aşağında olduğunda, dışarı “yukarı” anlamına gelir. Çevirme yorumu değiştirir.

Bir pozisyon için fee_growth_inside

Pozisyon [tick_lower, tick_upper] ve mevcut tick_current verildiğinde:
if tick_current >= tick_upper:
    inside = tick_lower.fee_growth_outside − tick_upper.fee_growth_outside
else if tick_current < tick_lower:
    inside = tick_upper.fee_growth_outside − tick_lower.fee_growth_outside
else:     // pozisyon aralık içinde
    inside = fee_growth_global
           − tick_lower.fee_growth_outside
           − tick_upper.fee_growth_outside
Bir pozisyonun token tarafı s için toplanmayan ücretleri:
tokens_owed_s += L · (fee_growth_inside_s − fee_growth_inside_last_s) / 2^64
fee_growth_inside_last_s = fee_growth_inside_s
Bu güncelleme pozisyon ile her etkileşimde çalışır (IncreaseLiquidity, DecreaseLiquidity, CollectFees).

İşlenmiş örnek — bir tick’i geçme

Havuz (basitleştirilmiş):
  • sqrt_p_x64 = 2^64 · 1.0 = 2^64 (fiyat = 1.0)
  • L = 1_000_000
  • tick_current = 0
  • Altta sonraki başlatılmış tick: tick = −60, sqrt_price = 1.0001^(−30) ≈ 0.99700, liquidity_net = −400_000 (bu tick bir pozisyonu sonlandırır, bu nedenle aşağı doğru geçiş 400k çıkarır)
  • Ücret oranı: %0.25
Swap: Δin = 10_000 token0, yön = 0→1. Adım 1 — sqrt_target = 0.99700 · 2^64 kadar:
amount_in_to_target = L · (1/sqrt_target − 1/sqrt_p)
                    = 1_000_000 · (1/0.99700 − 1/1.0)
                    ≈ 1_000_000 · 0.003009
                    ≈ 3_009
3.009 < 10.000, bu nedenle bu adımı tamamen doldururuz:
Δin_step  = 3_009 / (1 − 0.0025)  = 3_017    // ücret brüt
Δout_step = L · (sqrt_p − sqrt_target) ≈ 1_000_000 · 0.00299 ≈ 2_990
sqrt_p    = 0.99700 · 2^64
tick_current = −60
L         = 1_000_000 + (−400_000)  = 600_000         // tick geçildi
tick −60'da fee_growth_outside çevrilir
Δin_remaining = 10_000 − 3_017 = 6_983
Adım 2 — yeni L = 600_000 ile: Sonraki başlatılmış tick (diyelim tick = −120) sqrt = 0.99402’de. amount_in_to_target’ı yeniden hesaplayınız:
amount_in_to_target = 600_000 · (1/0.99402 − 1/0.99700)
                    ≈ 600_000 · 0.003010
                    ≈ 1_806
Hâlâ Δin_remaining’ten az. Tekrar geçiniz. Δin_remaining sıfıra ulaşıncaya kadar devam ediniz. Δout’un tam dizisi nihai swap çıkışına birikir.

Başlatma ve taşma korumaları

  • MIN_SQRT_PRICE_X64 ve MAX_SQRT_PRICE_X64 tick = ±443636 ile karşılık gelir. sqrt_p’yi bu aralığın dışına itecek herhangi bir swap geri döner.
  • Kullanıcının sqrt_price_limit parametresi aynı aralıkta bulunmalıdır; program kontrol eder.
  • L · Δsqrt ürünleri u256 içinde hesaplanır, ardından taşmayı önlemek için u128 ye geri kaydırılır.

Uniswap v3’e karşı farklılıklar

  • Oracle. Raydium’un ObservationState bir (block_timestamp, tick_cumulative, seconds_per_liquidity_cumulative) halka tamponu depolar; Uniswap’ınkinden biraz farklı tel biçimi ama aynı TWAP matematik.
  • Token-2022. Raydium CLMM Token-2022 mintlerini destekler; transfer-ücret varyantı ek ön/son-swap miktar ayarlamaları gerektirir. Bkz algorithms/token-2022-transfer-fees.
  • Tick bitmap. Raydium başlatılmış-tick bitmap’i hızlı find_next_initialized_tick için havuz başına [u64; 16] içine paketler; Uniswap kelime başına zincir üzerinde bir eşlem kullanır. Tradeoff kira vs arama maliyetidir.
  • Ödül yuvaları. Raydium havuz başına 3 ayrı ödül akışını ayrı reward_growth_global_x64 sayaçları ile destekler; ücret-büyüme biriktiricisi ile aynı yapı.

İşaretçiler

Kaynaklar:
  • Uniswap v3 teknik raporu (sqrt-fiyat matematik kanonik türetimi).
  • Raydium CLMM program kaynağı.