Halaman ini diterjemahkan secara otomatis oleh AI. Versi bahasa Inggris adalah acuan resmi.Lihat versi bahasa Inggris →
Mengapa ticks ada
Likuiditas CLMM terkonsentrasi dalam rentang harga. Untuk membuat rentang dapat ditangani on-chain, harga dikuantisasi menjadi integer ticks, di mana setiap tick adalah kelipatan konstan dari yang sebelumnya: Satu tick sesuai dengan pergerakan harga 0,01%, atau ~1 basis poin. Pemetaannya adalah:MIN_TICK dan MAX_TICK dipilih sehingga sqrt_price_x64 sesuai dalam u128 di kedua ujung. Setiap pool memberlakukan bahwa tick_lower >= MIN_TICK dan tick_upper <= MAX_TICK. Dalam praktiknya, UI web membatasi rentang ke sesuatu yang jauh lebih sempit untuk mencegah pengguna mengunci likuiditas ke ticks yang tidak dapat dijangkau.
Tick spacing
AmmConfig pool menetapkan tick spacing — satu-satunya ticks yang diizinkan posisi gunakan sebagai endpoint. Jika tick_spacing = 60, hanya ticks …, −120, −60, 0, 60, 120, … yang valid. Upaya membuka posisi dengan endpoint 31 akan kembali dengan InvalidTickIndex.
Spacing yang dipublikasikan secara umum:
Semakin kasar spacing-nya, semakin sedikit tick arrays yang perlu diinisialisasi, semakin murah untuk membuka posisi yang lebar, dan semakin kabur batas harganya. Pasangan yang volatil biasanya berada di tier spacing 120; stablecoin berada di tier spacing 1.
Tick arrays
Pool tidak menyimpan status per-tick dalam akun terpisah. Sebaliknya,TICK_ARRAY_SIZE ticks yang berdekatan (60 dalam CLMM Raydium saat ini) dikemas ke dalam satu TickArrayState. Array pertama tick adalah start_tick_index-nya, dan mencakup tepat TICK_ARRAY_SIZE * tick_spacing unit integer-tick.
Untuk tick_spacing = 60 dan TICK_ARRAY_SIZE = 60:
- Setiap tick array mencakup
60 × 60 = 3600integer ticks. start_tick_indexadalah kelipatan 3600:…, -7200, -3600, 0, 3600, 7200, ….
t = 2040 pada tick_spacing = 60 berada di tick array dengan start_tick_index = 0. Endpoint posisi t = 4200 berada di array dengan start_tick_index = 3600.
Ketika array diinisialisasi
Tick array adalah lazy: posisi pertama yang mereferensikan tick apa pun di dalamnya menginisialisasi array, membayar sewa. Swap tidak menginisialisasi tick arrays — mereka melewati array yang tidak diinisialisasi menggunakan bitmap. Alur open-position SDK memeriksa rentang yang dipilih, menghitung daftar tick arrays yang disentuhnya, dan menambahkan instruksiinit_tick_array dalam transaksi yang sama dengan OpenPosition jika ada yang hilang.
Tick arrays tidak ditutup
Setelah tick array diinisialisasi, array tersebut bertahan selama masa hidup pool. Program tidak mengekspos jalur untuk menutup tick array, bahkan setelahinitialized_tick_count kembali ke nol. Tidak ada pemulihan sewa untuk tick arrays; sewa yang dibayar oleh posisi pertama yang menyentuh array dikunci ke akun itu secara permanen. Ini adalah trade-off yang disengaja: menggunakan kembali tick array yang ada gratis untuk setiap posisi berikutnya, jadi pool yang banyak diperdagangkan hanya membayar biaya sewa sekali per slot (pool, start_tick_index) terlepas dari churn.
Bitmap
Menemukan “tick yang diinisialisasi berikutnya ke kiri/kanan dari tick saat ini” harus cepat — swap dapat melintasi banyak ticks. Pool menyimpan bitmap 1-bit-per-tick-array inline diPoolState untuk rentang ±1.024 arrays di sekitar tick 0. Di luar rentang itu (posisi full-range, setup eksotis), TickArrayBitmapExtension menyediakan overflow.
Swap berjalan melalui bitmap: lowest_set_bit_above(tick_current_array_index) memberikan array berikutnya dengan tick yang diinisialisasi di sisi yang dilintasi swap. Dalam array itu, bit-scan serupa menemukan tick yang diinisialisasi berikutnya.
liquidity_gross dan liquidity_net
Setiap tick yang diinisialisasi menyimpan dua nilai likuiditas:
liquidity_gross— jumlahLdi atas semua posisi yang mereferensikan tick ini sebagai endpoint. Ketikaliquidity_grossmencapai nol, tick menjadi tidak diinisialisasi dan dapat dihapus dari bitmap.liquidity_net— perubahan bertanda keliquiditylevel-pool ketika harga melintasi tick ini bergerak ke atas (kiri-ke-kanan dalam ruang tick). Jika tick ini adalah batas bawah posisi dengan ukuranL, ia berkontribusi+L; jika ini adalah batas atas posisi itu, ia berkontribusi−L.
- Posisi A:
tick_lower = -120,tick_upper = 0, likuiditasL_A = 100. - Posisi B:
tick_lower = -60,tick_upper = 60, likuiditasL_B = 50.
liquidity level-pool untuk nilai tick_current yang berbeda:
tick_current = -180:liquidity = 0(sebelum posisi apa pun)tick_current = -90:liquidity = 100(hanya di dalam A)tick_current = -30:liquidity = 150(di dalam A dan B)tick_current = 30:liquidity = 50(hanya di dalam B)tick_current = 90:liquidity = 0(melewati keduanya)
liquidity_net (mungkin negatif) ke PoolState.liquidity. Ini adalah mekanisme Uniswap-v3 yang tepat.
Posisi sebagai NFT
Posisi CLMM Raydium adalah NFT. Membuka posisi mencetak mint baru dengan supply 1 ke dompet pemanggil, dan otoritas mint adalah program CLMM. Program mengikat kepemilikan posisi ke siapa pun yang memegang saldo di ATA mint itu pada waktu CPI. Konsekuensi:- Posisi biasanya dapat ditransfer. Dompet dapat menjual atau airdrop posisi dengan mentransfer NFT. Pemegang baru kemudian dapat memanggil
CollectRewards,IncreaseLiquidity, dll. Pengecualian adalah posisi yang dibekukan di bawah jalur restricted-issuer di bawah. - Posisi dapat dialamatkan di luar CLMM. Marketplace dan dompet menampilkan posisi seperti NFT lainnya. SDK menetapkan
name/symbolyang masuk akal pada metadata mint. - PDA posisi diturunkan dari NFT mint. Anda dapat menemukan
PersonalPositionStatetanpa mengetahui siapa yang saat ini menahannya.
Posisi restricted-issuer
Setiap mint NFT posisi yang dibuat setelah upgrade 2026-08 mencatatpool_state CLMM-nya sebagai freeze authority. Ini tidak berarti setiap posisi baru dibekukan. Untuk pool biasa dan setiap posisi non-matching, akun token NFT tetap tidak dibekukan dan dapat ditransfer. Pool PDA tidak dapat menandatangani di luar program CLMM, dan CLMM tidak mengekspos instruksi freeze tujuan umum.
Pembekuan memerlukan kedua kondisi ini:
- Posisi dibuka melalui
OpenPositionV2atauOpenPositionWithToken22Nft. - Setidaknya satu vault mint pool membawa freeze authority dari daftar restricted-issuer yang dikodekan keras program.
OpenPosition V1 tidak menerapkan filter ini. Lihat reference/program-addresses untuk daftar saat ini.
Posisi yang dibekukan:
- Tidak dapat mentransfer NFT-nya ke akun token lain.
- Tidak dapat mengubah pemilik akun token NFT.
- Masih dapat meningkatkan atau mengurangi likuiditas dan mengumpulkan biaya atau reward ketika pemilik yang tercatat menandatangani.
- Masih dapat ditutup.
ClosePositionmenggunakan pool PDA untuk mencairkan akun NFT, kemudian membakar NFT dan menutup akun posisi dalam instruksi yang sama.
Posisi Token-2022
CLMM dapat mencetak NFT posisi di bawah Token SPL klasik melaluiOpenPositionV2, atau di bawah Token-2022 melalui OpenPositionWithToken22Nft. Kedua jalur V2 memeriksa vault mints pool dan menerapkan aturan freeze restricted-issuer yang sama. OpenPosition V1 adalah jalur token klasik legacy dan tidak dapat melayani pool dengan vault mints Token-2022. Kompatibilitas dompet dan marketplace berbeda; UI Raydium melacak kedua program NFT.
Aturan rentang yang diizinkan
Pada waktuOpenPosition program memberlakukan:
tick_lower < tick_upper.tick_lower % tick_spacing == 0dantick_upper % tick_spacing == 0.MIN_TICK <= tick_lowerdantick_upper <= MAX_TICK.- Pemanggil telah menyediakan tick arrays yang berisi
tick_lowerdantick_upper— baik sudah diinisialisasi atau melaluiinit_tick_arraydalam transaksi yang sama. - Akun bitmap extension, jika posisi ini meluas ke dalam rentang extension.
InvalidTickIndex, NotApproved, atau InsufficientLiquidity tergantung pada batasan mana. Lihat reference/error-codes.
”In-range” vs “out-of-range”
Posisi adalah in range ketikatick_lower <= tick_current < tick_upper. Hanya posisi in-range yang berkontribusi pada PoolState.liquidity dan oleh karena itu hanya mereka yang mendapatkan biaya swap.
Posisi out-of-range:
- Memegang 100% dari satu token (yang rentangnya telah melewati). Secara spesifik, jika
tick_current < tick_lower, posisi hanya memegang token1 (sudah “dijual” oleh harga yang bergerak menjauh); jikatick_current >= tick_upper, hanya memegang token0. - Tidak mendapatkan biaya swap.
- Terus mengumpulkan reward jika aliran reward pool memancarkan ke likuiditas out-of-range — tetapi perilaku default Raydium adalah “emit hanya ke in-range”, sesuai dengan konvensi Uniswap v3. Lihat
products/clmm/fees.
Jebakan integrasi umum
- Endpoint off-spacing. Kode yang menghitung tick dari harga target harus snap ke kelipatan
tick_spacingsebelum meneruskannya keOpenPosition. Helper SDK (TickUtils.getTickWithPriceAndTickspacing) melakukan ini; math buatan sendiri sering tidak. - Tick arrays yang hilang. Membuka posisi yang lebar mungkin memerlukan inisialisasi beberapa tick arrays; lupa meneruskannya sebagai akun writable akan kembali. SDK
openPositionFromBasemengembalikan daftar untuk Anda. - Tick stale setelah swap.
tick_currentdapat melintasi banyak ticks dalam satu swap. Jika UX Anda menampilkan “current tick” dari satu panggilan RPC dan kemudian membuka posisi di panggilan yang lebih baru, posisi relatif vs harga live dapat mati puluhan ticks. Ambil ulang tepat sebelum menandatangani. - NFT posisi dengan metadata tambahan. Jika Anda membangun dompet yang mengenali posisi Raydium, gunakan posisi PDA / data program dan bukan field metadata yang dikodekan keras. Mint posisi baru menggunakan pool PDA sebagai mint dan freeze authority saat pembuatan; mint authority dihapus setelah NFT tunggal dicetak.
- Mengasumsikan setiap posisi dapat ditransfer. Baca status
isFrozenakun token NFT sebelum menampilkan transfer, marketplace, escrow, atau Burn & Earn actions.
Ke mana selanjutnya
- Math — langkah swap dan derivasi fee-growth yang batas tick ikuti serta.
- Accounts — layout
TickArrayStatedanPositionState. - Biaya dan reward — bagaimana in-range-ness gating fee accrual.
algorithms/clmm-math— derivasi bersama formula concentrated-liquidity.
raydium-io/raydium-clmm— modultick_array,tick,position- Whitepaper “Uniswap v3 Core”, §6 (ticks), §7 (fee growth)

