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 operasyonel: CLMM programı tarafından kullanılan formülleri, sabit-nokta kurallarını ve adım-adım prosedürü sunmaktadır. Konsantre likidite eğrisinin kendisinin arkasındaki mantık — neden
L = sqrt(x · y) önemli — için bkz. algorithms/clmm-math. Bu sayfayı okumadan önce o sayfayı okumuş olduğunuzu varsayıyoruz.Kare kök fiyat gösterimi
CLMM fiyatısqrt_price_x64 olarak saklar — token1-başına-token0 fiyatının kare kökü, Q64.64 sabit-nokta sayısı olarak:
burada p = token1_amount / token0_amount. Kare kök cinsinden çalışmak swap matematiğini doğrusallaştırır (token-tutarı deltalar Δsqrt_price’te doğrusal hale gelir) ve x64 sabit-nokta çok-tick swaplarda kesinliği korur.
Tick ↔ kare kök fiyat dönüşümü bit-by-bit logaritma yaklaşımıyla önceden hesaplanır:
tick_math::get_sqrt_price_at_tick’te arama tablosu tabanlı üs alma olarak uygulanır.
Likidite kanonik birim olarak
[sqrt_a, sqrt_b] aralığında (sqrt_a < sqrt_b), likidite L konumlandırması token tutarlarına aşağıdaki gibi eşlenir. sqrt_c = sqrt_price_x64 havuzun mevcut fiyatı olsun.
| Durum | amount0 | amount1 |
|---|---|---|
sqrt_c <= sqrt_a (havuz fiyatı aralığın altında) | L · (sqrt_b - sqrt_a) / (sqrt_a · sqrt_b) | 0 |
sqrt_a < sqrt_c < sqrt_b (aralık içinde) | L · (sqrt_b - sqrt_c) / (sqrt_c · sqrt_b) | L · (sqrt_c - sqrt_a) |
sqrt_c >= sqrt_b (havuz fiyatı aralığın üstünde) | 0 | L · (sqrt_b - sqrt_a) |
x = L / sqrt_p, y = L · sqrt_p değişmezinden gelir.
Entegratörler tipik olarak tersi isteyebilir: amount0 / amount1 mevduatı verilen, aralığa sığan maksimum L hesaplansın. SDK’nın LiquidityMath.getLiquidityFromTokenAmounts bunu yapar. Aralık içi durum için formül:
Hangisi sınırlayıcı ise gerçekte tüketilen oranı belirler; diğer taraf kalan kalabilir.
Tek-tick swap adımı
Swap adımlar halinde ilerler. Her adım ya (a) mevcut tick aralığındaki tüm mevcut girdisi tick geçmeden tüketir ya da (b) fiyatı tam olarak sonraki başlatılmış tick’e hareket ettirir. Mevcut durum(sqrt_c, L) ve yukarı swap (token0 giriş, token1 çıkış, sqrt_price artar) verilen, sonraki başlatılmış tick’e kadar mesafe sqrt_t’dir. Bu mikro-aralık içinde giriş ve fiyat arasındaki ilişki:
ve
Program iki şeyden birini yapar:
-
Tüm giriş uyuyor mu? Kalan giriş (ücret sonrası)
sqrt_t’ye ulaşmak içinΔamount0’dan azsa, yenisqrt_c'’yi tam olarak çözün: (tam-giriştoken0 → token1swap için). Swap bu adımda tick geçmeden tamamlanır. -
Giriş
Δamount0’ı aşıyor mu?sqrt_c' = sqrt_tayarlayın, tick geçin (liquidity_netuygulayın), kalan girdiyeΔamount0çıkartın, çıktıyaΔamount1ekleyin ve tekrarlayın.
token1 → token0, fiyat düşer), formüllerde sqrt_c ve sqrt_t değiştirilir ve ters başka slotta yapılır.
Tam Rust uygulaması raydium-clmm/programs/amm/src/libraries/swap_math.rs’de bulunur. Oradaki mantık Uniswap v3’ün SwapMath.computeSwapStep ile bire bir eşleşir.
Her adımda ücretler
İşlem ücretleri her adımda giriş tutarından alınır, CPMM ile aynı kural:L_i likiditelik bir pozisyon daha sonra L_i · Δfee_growth_global / 2^{64} ödenmesi gereken token’ları geri okur.
Protocol ve fund kısımları sırasıyla PoolState.protocol_fees_token_{0,1} ve PoolState.fund_fees_token_{0,1}’e birikir, CPMM ile aynı. Bunlar CollectProtocolFee / CollectFundFee tarafından taranır.
Dışarıda ve içeride ücret-artış
CLMM ücret muhasebesi zor kısım: bir pozisyon ücret kazanır sadece havuz fiyatı aralığı içinde iken. Havuz küresel birikmiş ücretleri izler; pozisyon kendi spesifik aralığı içinde birikmiş ücretleri bilmesi gerekir. Çözüm bir tick tabanlı akümülatördür. Her tick şunları saklar:- Havuz fiyatı bu tick’in üstündeyse (
tick_current >= this_tick),fee_growth_outside = fee_growth_global. (Şimdiye kadarki tüm kazanç bu tick’e göre “dışarıda” — yani aşağıda.) - Aksi takdirde
fee_growth_outside = 0.
fee_growth_outside’ını çevirir:
Bu korunan değişmez: herhangi bir tick t için, fee_growth_outside(t) tick_current t’nin karşı tarafında iken birikmiş ücretlere eşittir.
Aralık [tick_lower, tick_upper]’da ücret-artış içerde türetilir:
Bir pozisyon neyi saklar ve neyi okur
BirPersonalPositionState fee_growth_inside_0_last_x64 ve fee_growth_inside_1_last_x64 saklar: pozisyon son dokunuşta fee_growth_inside değerleri.
Herhangi bir sonraki dokunuş (arttırma, azaltma, toplama), program:
- Yukarıdaki formülü kullanarak şu anki
fee_growth_inside_{0,1}_x64’yi hesaplar. Δ = fee_growth_inside_now − fee_growth_inside_lasthesaplar (u128’de modüler çıkartma).Δ × position.liquidity / 2^{64}’ütokens_fees_owed_{0,1}’ye ekler.fee_growth_inside_last’ı yeni değere günceller.
CollectFees / DecreaseLiquidity’de, tokens_fees_owed’a karşı.
Ödüller
Havuzun üç ödül akışından her biri aynı artış-içinde mekanizmasını kullanır, kendireward_growth_global_x64 akümülatöründe. Emisyon sırasında:
— emisyonlar aktif likiditeyle ters yönde ölçeklenir, böylece daha yoğun bir havuz her pozisyona saniye başına orantısal olarak daha az öder, ama toplamda daha çok pozisyon üstünde. Pozisyon başına ödenen ödül
ve CollectReward yoluyla talep edilir. Bkz. products/clmm/fees.
Çalışılmış örnek: tam-giriş swap
Diyelim ki:tick_spacing = 60sqrt_price_x64 = 1 × 2^{64}— fiyat = 1.0, yanitick_current = 0.- Aktif likidite
L = 1_000_000 × 2^{64}. - Üstte sonraki başlatılmış tick:
t = 60(sqrt_price_b ≈1.003004 × 2^{64}). - İşlem ücreti oranı: 500 (0.05%).
SwapBaseInput tam-giriş 1,000 token0.
Adım 1 — ücretler:
999 < 2995.5, yani tüm giriş tick geçmeden uyuyor.
Adım 3 — yeni fiyat:
sqrt_c' sqrt_c’nin biraz altında. Yukarıdaki formülün token1 → token0 swap için olduğunu dikkate alın. Buradaki örnek token0 → token1, fiyatı yukarı çeker, aşağı değil — bu yüzden token0 giriş için karşılık gelen formu kullanırız:
token0 → token1 için beklenen swap yönüyle eşleşir: sqrt_c fiyat ile birlikte yükselir.)
Adım 4 — çıktı tutarı:
trade_fee_rate × protocol_fee_rate / 1e6 tarafından LP, protocol ve fund arasında bölünür (ve fund için benzer); LP kısmı fee_growth_global_0_x64 içine akar.
Swap sırasında limit emri eşleştirme
Swap adımı açık limit emirleri tutan bir tick’i geçtiğinde, bu emirler swap girdisini önce LP eğrisi olmadan, tick’in tam fiyatında tüketir. Eşleştirme tick içindeorder_phase kohortuna göre FIFO’dur.
TickState’de kohort başına durum
orders_amount’a katılır ve sonraki order_phase’i miras alır; önceki kohort tamamen tüketilinceye kadar dolduramazlar.
Eşleştirme adımı
Swap sırasında her tick geçişinde gerçekleşen eşleştirme için sözde kod:SettleLimitOrder (veya DecreaseLimitOrder) çağırana kadar. Havuz basitçe kohortan ne kadarının dolu olduğunu unfilled_ratio_x64 yoluyla izler. Her LimitOrderState açılış sırasında kendi (order_phase, unfilled_ratio_x64) anlık görüntüsünü saklar, yani settlement’e indirgenir:
LP eğrisiyle etkileşim
Bir swap adımında, limit emri eşleştirme tick’te oluşur (sıfırΔsqrt_price); LP eğrisi tüketimi tick’ler arasında oluşur. Sıra bu nedenle:
- Tick
t_crossgeçin (LPliquidity_netdeğişimini ilk uygulayın, çünkü Uniswap-V3 böyle yapar). t_cross’da oturan herhangi bir limit emri doldurun.- LP eğrisi boyunca sonraki başlatılmış tick’e veya
swap_inputtükenişine devam edin.
Dinamik ücret türetimi
PoolState.dynamic_fee_info volatilite durumunu taşır. Her swap adımı per-adım ücret oranını hesaplar:
nerede:
- —
DYNAMIC_FEE_CONTROL_DENOMINATOR - —
VOLATILITY_ACCUMULATOR_SCALE vol_accaşağıdaki güncelleme kuralından sonra per-swap akümülatördürtick_spacingPoolState.tick_spacing’den
Akümülatör güncelleme
İki kural her swap’ta sırada uygulanır: Azalma. Referans taban son güncelleme itibaren zamana göre azalır: Birikme. Yeni akümülatör referans artı önceki referans indeksinden beri kat edilen tick-mesafesidir:tick_spacing_index_reference () ham tick’te değil, tick-boşluk birimindedir: .
Neden parabol tick mesafede
Akümülatörü karelemek ücretin fiyat karesinin olarak yürüdüğü kadar yükseldiği anlamına gelir. Ampirik olarak bu rastgele-yürüyüş basıncı altında fiyatın varyans ölçeklemesi eşleşir: 2× tick sapması 4× örtülü volatilite anlamına gelir, yani 4× ek ücret alır.dynamic_fee_control parametresi mutlak seviyeyi ayarlar.
filter_period penceresi küçük alt-saniye salınımları (örn. MEV botlar sandviç) akümülatörü şişirmesinden önler. decay_period penceresi tek bir geçmiş spike’ın pazar sakinleştikten sonra ücret almaya devam etmesini önler.
Sayısal sağlamlık
- Tüm ara çarpımlar
u128veyau256şeklinde aritmetiğe gider. CLMMU128Sqrtyardımcılarını veFullMath::mulDivmodellerini Uniswap v3’ten doğrudan taşıyanları kullanır. - Bölme yuvarlama değişmez
k' ≥ kyerel olarak uygulamak için per-adım seçilir.SwapBaseInputçıktıyı aşağı yuvarlar;SwapBaseOutputgirdiye yukarı yuvarlar. - Tick geçişleri
PoolState.liquiditysıfıra düşürenler izin verilir (fiyat “likidite deliği” içinde gidebilir) ama swap basitçe sonraki başlatılmış tick’e giriş tüketin olmadan, ücret almadan ilerler. - Taşma koruması:
sqrt_price_x64[MIN_TICK, MAX_TICK]’e karşılık gelen[MIN_SQRT_PRICE_X64, MAX_SQRT_PRICE_X64]aralığında tutulur. Herhangi bir bağı geçecek bir swapSqrtPriceLimitOverflowile geri döner.
Sonra nereye gidilir
products/clmm/ticks-and-positionstick haritasının yürüyüşe nasıl katıldığı için.products/clmm/feesücret/ödül matematiği detaylı için.algorithms/clmm-mathL = sqrt(x · y)ve aralık-vs-likidite formüllerinin arkasındaki türetimler için.
raydium-io/raydium-clmm—libraries/swap_math.rs,libraries/tick_math.rs- “Uniswap v3 Core” whitepaper, §6–7


