Skip to main content
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 her hesabın düzeni ve rolünü açıklar. Seed’ler kanonik olup reference/program-addresses içinde listelenmiştir. CLMM havuzu, CPMM havuzundan daha fazla hesap gerektiren bir yapıdır çünkü likidite tick aralığı boyunca seyrek şekilde depolanır; bu sayfanın büyük bölümü bu seyrekliği anlamakla ilgilidir.

Hesap envanteri

Canlı bir CLMM havuzu aşağıdaki hesap aileleri tarafından tanımlanır. Tümü CLMM programına aittir; iki mint ve bunların vault’ları hariç.

PoolState

Havuzun canlı durumu, her swap ve her pozisyon değişikliğinde okunur.
Gerçekten dokunacağınız alanlar:
  • sqrt_price_x64 ve tick_current havuzun fiyat durumudur. Her swap’ta birlikte güncellenir. tick_current, log_{1.0001}(price) tabanıdır.
  • liquidity aktif likidite — aralığı tick_current içeren tüm pozisyonların L değerlerinin toplamıdır. Bir swap bir tick’i geçtiğinde ve bir pozisyon açıldığında/kapatıldığında/yeniden boyutlandırıldığında değişir.
  • fee_growth_global_{0,1}_x64 tüm havuz geçmişi boyunca likidite birimi başına kazanılan kümülatif ücretlerdir. Pozisyonlar kendilerine ne borçlu olduğunu hesaplamak için bunu okur.
  • tick_spacing başlatmada AmmConfig’e kilitlenir ve asla değişmez. Hangi tick indekslerine pozisyon uç noktası olarak izin verildiğini belirler.
  • tick_array_bitmap spot fiyatın etrafındaki yaygın olarak kullanılan aralığı kaplayan satır içi bir bitmap’tir (±1.024 tick dizisi). Pozisyonlar çok uzağa ulaşan havuzlar için taşma izlemesi ayrı TickArrayBitmapExtension içinde yaşar.
  • fee_on havuz oluşturmada sabitlenir. 0 (FromInput) klasik Uniswap-V3 davranışını yeniden üretir. 1 ve 2 swap ücretini kitabın tek bir tarafına yönlendirir — ödünleşmeler için products/clmm/fees bölümüne bakın.
  • seed_index CreatePool / CreateCustomizablePool aracılığıyla oluşturulan her havuz için [0, 0] değerindedir. Sıfır olmayan bir değer, havuzun CreatePermissionedPool aracılığıyla oluşturulduğu ve dizinin havuzun PDA seed’lerinin bir parçası olduğu anlamına gelir; aynı (config, mint0, mint1) için birkaç havuzun bir arada bulunmasını sağlar. Böyle bir havuzun adresini yeniden türetmek için seed_index değerini bilmeniz gerekir.
  • dynamic_fee_info dinamik ücret surşarjı için volatilite durumunu taşır. Etkinleştirildiğinde, her swap AmmConfig.trade_fee_rate üzerine bir dynamic_fee_component yeniden hesaplar. Düzen DynamicFeeInfo altında belgelenmiştir; dinamik ücret olmayan havuzlar tüm yapıyı sıfır bırakır.

AmmConfig

Tipik yayınlanmış CLMM ücret katmanları seti (GET https://api-v3.raydium.io/main/clmm-config ile doğrulayın): protocol_fee_rate ve fund_fee_rate işlem ücretinin kesintileridir; CPMM ile aynı kural. products/clmm/fees bölümüne bakın.

TickArrayState

CLMM tek bir tick başına bir kayıt depolamaz. Bu milyarlarca hesap olurdu. Bunun yerine TICK_ARRAY_SIZE bitişik başlatılmış-veya-değil tick’leri (program sürümüne bağlı olarak tipik olarak 60 veya 88) ilk kullanımda tembel olarak oluşturulan bir TickArrayState içine gruplandırır.
Dört limit emir alanı, hiçbir zaman limit emir için kullanılmamış herhangi bir tick’te sıfırdır. Emirler bir tick’te açıldığında, program bunları bir dizi kohort olarak izler:
  • order_phase kohort kimliğidir. Bir kohort “tümü doldurulmamış” durumundan “kısmen doldurulmuş” durumuna geçtiğinde artar.
  • orders_amount mevcut (en yeni) kohortu giriş-token toplamıdır.
  • part_filled_orders_remaining şu anda devam eden swap’lar tarafından doldurulmakta olan önceki kohortu izler.
  • unfilled_ratio_x64 kohort üzerinde taşınan bir Q64.64 çarpanıdır: bir swap kohortu X% doldurduğunda, oran (1 − X) ile çarpılır. Her açık emir açılış zamanında kendi (order_phase, unfilled_ratio_x64) anlık görüntüsünü depolar, bu nedenle kapatma matematiği anlık görüntüleri karşılaştırmaya indirgenir.
Kurallar:
  • Bir pozisyon uç noktası tick’i t t % tick_spacing == 0 koşulunu sağlamalıdır. Program aralık dışı pozisyonları reddeder.
  • Tick’in dizisi floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing) konumunda bulunur.
  • Bir tick dizisi tembel olarak başlatılır: başlatılmamış bir diziyi ilk kez dokunacak pozisyon veya swap onu oluşturur ve kirayı öder.
  • Bir tick dizisi program tarafından asla kapatılmaz. Bir kez tahsis edildikten sonra, içindeki her tick liquidity_gross == 0 durumuna döndükten sonra bile havuzun ömrü boyunca devam eder. Mevcut bir tick dizisini yeniden kullanmak hiçbir ek kira maliyeti olmadan yapılır. Tick dizileri için ClosePosition tarafından yönlendirilen temizleme yolu yoktur.

TickArrayBitmapExtension

PoolState.tick_array_bitmap (satır içi) “spot’a yakın” aralığını kapsar — ±1.024 tick dizisi. Bu aralığın dışında (aşırı tick değerleri için), program bir uzantı hesabı tutar:
Pozisyonunuzun aralığı “normal” ise, uzantı hesabı hakkında hiç düşünmezsiniz. Tam aralık pozisyonları (örn. (MIN_TICK, MAX_TICK)) bunu gerektirir; SDK bunu sizin için çözer.

Pozisyonlar

Bir CLMM pozisyonu üç hesap artı bir mint’in bir paketidir:

Position NFT mint

Arz 1 olan bir SPL Token mint’i. Mint’in adresi deterministik bir PDA’dır; sahibinin cüzdanındaki position NFT’si sadece o tek token’ı tutan bir ATA’dır. NFT’yi aktarmak, bir pozisyonun el değiştirmesidir — program yetkilendirmeyi bir Pubkey’e depolanan değere değil, NFT’nin ATA bakiyesinin mevcut sahibine anahtarlar.

PersonalPositionState

Açık pozisyon başına bir tane. NFT mint’ine göre anahtarlanır.

ProtocolPositionState (kullanımdan kaldırıldı)

Eski CLMM sürümleri (pool, tick_lower, tick_upper) başına toplam muhasebe bilgisini bir ProtocolPositionState PDA’sında depoladı. Yeni sürümler artık bu hesabı oluşturmaz veya okumaz. Slot, ABI uyumluluğu için OpenPosition / IncreaseLiquidity / DecreaseLiquidity hesap listelerinde bir UncheckedAccount olarak görünmeye devam eder, ancak program buna yazmaz. Zincir üzerinde mevcut hesaplar kalıntıdır; yönetici kirayı geri almak için CloseProtocolPosition çağırabilir.Toplam aralık muhasebesi artık doğrudan iki uç noktası tick’ten (liquidity_gross, liquidity_net ve tick başına fee_growth_outside_* / reward_growths_outside_x64) TickArrayState içinde türetilir. Ücret-büyüme-içi formülü fee_growth_inside = global − outside_lower − outside_upper toplam pozisyon hesabı olmadan çalışmaya devam eder.

Gözlem

CLMM’nin gözlem tamponu kümülatif fiyat değil kümülatif tick depolar. Harici tüketiciler (tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) aralığından geometrik-ortalama fiyatı hesaplar ve ardından price = 1.0001 ** tick hesaplar. algorithms/clmm-math bölümüne bakın.

DynamicFeeConfig ve DynamicFeeInfo

Dinamik ücret parametreleri iki yerde yaşar. Yeniden kullanılabilir şablon — DynamicFeeConfig — yönetici tarafından yönetilir ve katılan havuzlar arasında paylaşılır. Havuz başına çalışma zamanı durumu — DynamicFeeInfoPoolState içine gömülü ve her swap tarafından güncellenir.

DynamicFeeConfig

PDA seed’i: ["dynamic_fee_config", index.to_be_bytes()]. create_dynamic_fee_config (yönetici kapılı) aracılığıyla oluşturulur ve update_dynamic_fee_config aracılığıyla değiştirilir. enable_dynamic_fee = true ile oluşturulan bir havuz, yapılandırmanın beş kalibrasyon parametresini (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) oluşturma zamanında kendi DynamicFeeInfo içine anlık görüntü alır; DynamicFeeConfig için daha sonraki düzenlemeler mevcut havuzları geriye dönük olarak etkilemez.

DynamicFeeInfo (PoolState içine gömülü)

Alt dört alan durumdur; üst beş alan DynamicFeeConfig adresinden kopyalanan kalibrasyon değerleridir. Ücret matematiği ve bozunma kuralları products/clmm/math ve products/clmm/fees altında belgelenmiştir. Formül tarafından kullanılan sabitler:

LimitOrderState

Açık limit emir başına bir hesap.
Yaşam döngüsü:
  1. — kullanıcı open_limit_order çağırır, giriş token’ının total_amount değerini depozit eder, emir bir TickState kohortuna bağlanır.
  2. (isteğe bağlı) Artır / Azaltincrease_limit_order total_amount değerine ekler; decrease_limit_order doldurulmamış token’ları (ve o noktaya kadar kapatılan herhangi bir çıktıyı) döndürür.
  3. Kapat — kohort tamamen veya kısmen doldurulduğunda, sahibi veya operasyonel bekçi çıktı token’larını sahibinin ATA’sına göndermek için settle_limit_order çağırır.
  4. Kapatunfilled_amount == 0 olduğunda, hesap kapatılabilir. Kira her zaman owner adresine döner.
PDA seed’i: [owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. Emir PDA’sı bu nedenle (owner, nonce_index, order_nonce) başına benzersizdir.

LimitOrderNonce

Her (wallet, nonce_index) başına sayaç, tek bir kullanıcının PDA’larda çarpışmadan birden fazla paralel limit emir hattı çalıştırmasını sağlar.
PDA seed’i: [user_wallet.as_ref(), &[nonce_index]]. Çoğu istemci nonce_index = 0 kullanır ve order_nonce değerinin kardinaliteyi taşımasına izin verir.

Permission

Varlığı izin olan bir yetenek hesabı: belirli bir yetki için bir Permission PDA türetilirse, bu yetki CreatePermissionedPool çağırabilir. Oluşturulduğu yetkilendirmenin ötesinde hiçbir şey depolamaz.
PDA seed’i: ["permission", authority.as_ref()]. Yönetici tarafından CreatePermissionPda aracılığıyla oluşturulur ve ClosePermissionPda aracılığıyla yıkılır (kira arayana döner). Her iki yönetici talimatı da program admin veya özel permission_pda_admin anahtarını kabul eder. PDA’yı kapatmak izni iptal eder — yetki artık ek havuzlar oluşturamaz, ancak zaten oluşturduğu havuzlar etkilenmez.

Anahtar hesapları türetme

Tam seed dizgeleri her zaman zincir üzerindeki IDL ve reference/program-addresses ile karşılaştırılmalıdır.

Yaşam döngüsü hızlı referansı

TickArrayState hesapları program tarafından asla kapatılmaz — havuzun ömrü boyunca devam eder. Bir tick dizisi başlatıldıktan sonra, içindeki her tick liquidity_gross == 0 durumuna döndükten sonra bile zincir üzerinde kalır. Mevcut bir tick dizisini yeniden kullanmak ücretsizdir; yalnızca hiçbir zaman başlatılmamış bir diziyi ilk kez dokunacak pozisyon kirayı öder.

Nerede ne okuyacağınız

Kaynaklar: