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.
Trang này được dịch tự động bằng AI. Phiên bản tiếng Anh là bản chính thức.Xem bản tiếng Anh →
Tại sao tick tồn tại
Tính thanhtí của CLMM được tập trung vào các dải giá. Để làm cho các dải này dễ quản lý trên chuỗi, giá được lượng tử hóa thành các số nguyên tick, trong đó mỗi tick là một bội số hằng của cái trước: Một tick tương ứng với một bước giá 0,01%, hay khoảng 1 điểm cơ bản. Ánh xạ như sau:Chỉ số tick i | Hệ số giá |
|---|---|
0 | 1.0000 |
100 | 1.0100 (≈ +1.00%) |
-100 | 0.9900 (≈ −0.99%) |
10000 | 2.7181 (≈ e) |
MAX_TICK = 443636 | ≈ 1.84e19 |
MIN_TICK = -443636 | ≈ 5.42e-20 |
MIN_TICK và MAX_TICK được chọn sao cho sqrt_price_x64 vừa trong một u128 ở cả hai đầu. Mọi pool đều tuân thủ tick_lower >= MIN_TICK và tick_upper <= MAX_TICK. Trong thực tế, giao diện web sẽ giới hạn dải này một cách chặt chẽ hơn để ngăn người dùng khóa tính thanh khoản vào các tick không thể truy cập được.
Khoảng cách tick
AmmConfig của một pool xác định tick spacing — các tick duy nhất mà một vị trí được phép sử dụng làm điểm cuối. Nếu tick_spacing = 60, chỉ các tick …, −120, −60, 0, 60, 120, … là hợp lệ. Một nỗ lực mở vị trí với điểm cuối 31 sẽ bị hoàn nguyên với InvalidTickIndex.
Các khoảng cách được công bố phổ biến:
| Tầng phí | trade_fee_rate | Tick spacing | Bước giá thô nhất trên mỗi vị trí tick |
|---|---|---|---|
| 0.01% | 100 | 1 | 0.01% |
| 0.05% | 500 | 10 | 0.10% |
| 0.25% | 2500 | 60 | 0.60% |
| 1.00% | 10000 | 120 | 1.21% |
Mảng tick
Pool không lưu trữ trạng thái mỗi tick trong các tài khoản riêng biệt. Thay vào đó,TICK_ARRAY_SIZE tick liền kề (60 trong Raydium CLMM hiện tại) được đóng gói thành một TickArrayState duy nhất. Tick đầu tiên của mảng là start_tick_index của nó, và nó bao phủ chính xác TICK_ARRAY_SIZE * tick_spacing đơn vị tick nguyên.
Đối với tick_spacing = 60 và TICK_ARRAY_SIZE = 60:
- Mỗi mảng tick bao gồm
60 × 60 = 3600tick nguyên. start_tick_indexlà bội số của 3600:…, -7200, -3600, 0, 3600, 7200, ….
t = 2040 ở tick_spacing = 60 nằm trong mảng tick có start_tick_index = 0. Một điểm cuối vị trí t = 4200 nằm trong mảng có start_tick_index = 3600.
Khi một mảng được tạo
Một mảng tick là lười biếng: vị trí đầu tiên tham chiếu bất kỳ tick nào trong nó sẽ khởi tạo mảng, trả tiền cho rent. Các swap không khởi tạo mảng tick — chúng bỏ qua các mảng chưa khởi tạo bằng cách sử dụng bitmap. Quy trình mở vị trí của SDK kiểm tra phạm vi được chọn, tính toán danh sách các mảng tick mà nó chạm vào, và thêm các hướng dẫninit_tick_array trong cùng một giao dịch với OpenPosition nếu có bất kỳ cái nào bị thiếu.
Mảng tick không được đóng
Sau khi một mảng tick đã được khởi tạo, nó tồn tại suốt vòng đời của pool. Chương trình không cung cấp một cách để đóng mảng tick, thậm chí sau khiinitialized_tick_count quay trở về không. Không có phục hồi rent cho mảng tick; tiền rent được trả bởi vị trí đầu tiên chạm vào một mảng bị khóa vào tài khoản đó vĩnh viễn. Đây là một sự cân bằng cố ý: tái sử dụng một mảng tick hiện có là miễn phí cho mọi vị trí tiếp theo, vì vậy một pool được giao dịch nhiều chỉ trả chi phí rent một lần cho mỗi slot (pool, start_tick_index) bất kể có bao nhiêu sự thay đổi.
Bitmap
Việc tìm “tick được khởi tạo tiếp theo ở bên trái/phải của tick hiện tại” phải nhanh — một swap có thể vượt qua nhiều tick. Pool lưu trữ một bitmap 1-bit-trên-mỗi-mảng-tick trongPoolState cho phạm vi ±1,024 mảng xung quanh tick 0. Ngoài phạm vi đó (vị trí phạm vi đầy đủ, thiết lập exotic), TickArrayBitmapExtension cung cấp tràn.
Một swap bước đi qua bitmap: lowest_set_bit_above(tick_current_array_index) cho mảng tiếp theo có một tick được khởi tạo ở phía swap đang vượt qua. Trong mảng đó, một quét bit tương tự định vị tick được khởi tạo tiếp theo.
liquidity_gross và liquidity_net
Mỗi tick được khởi tạo lưu trữ hai giá trị tính thanh khoản:
liquidity_gross— tổng củaLtrên tất cả các vị trí tham chiếu tick này làm điểm cuối. Khiliquidity_grossđạt không, tick trở nên chưa khởi tạo và có thể bị loại bỏ khỏi bitmap.liquidity_net— có dấu thay đổi tính thanh khoản ở cấp độ pool khi giá vượt qua tick này di chuyển lên (từ trái sang phải trong không gian tick). Nếu tick này là giới hạn dưới của vị trí với kích thướcL, nó đóng góp+L; nếu nó là giới hạn trên của vị trí đó, nó đóng góp−L.
- Vị trí A:
tick_lower = -120,tick_upper = 0, tính thanh khoảnL_A = 100. - Vị trí B:
tick_lower = -60,tick_upper = 60, tính thanh khoảnL_B = 50.
| Tick | Được tham chiếu bởi | liquidity_gross | liquidity_net |
|---|---|---|---|
-120 | A lower | 100 | +100 |
-60 | B lower | 50 | +50 |
0 | A upper | 100 | −100 |
60 | B upper | 50 | −50 |
tick_current khác nhau:
tick_current = -180:liquidity = 0(trước bất kỳ vị trí nào)tick_current = -90:liquidity = 100(bên trong chỉ vị trí A)tick_current = -30:liquidity = 150(bên trong A và B)tick_current = 30:liquidity = 50(bên trong chỉ vị trí B)tick_current = 90:liquidity = 0(vượt qua cả hai)
liquidity_net (có thể âm) vào PoolState.liquidity. Đây là cơ chế chính xác của Uniswap v3.
Vị trí dưới dạng NFT
Một vị trí Raydium CLMM là một NFT. Mở một vị trí sẽ mint một mint mới hoàn toàn có cung cấp 1 vào ví của người gọi, và quyền kiểm soát mint của chương trình CLMM. Chương trình liên kết quyền sở hữu vị trí với bất kỳ ai giữ số dư trong một ATA của mint đó vào thời điểm CPI. Hậu quả:- Vị trí có thể chuyển nhượng. Một ví có thể bán hoặc airdrop một vị trí bằng cách chuyển NFT. Chủ sở hữu mới sau đó có thể gọi
CollectRewards,IncreaseLiquidity, v.v. - Vị trí có thể được định địa chỉ bên ngoài CLMM. Các marketplace và ví hiển thị các vị trí như các NFT khác. SDK đặt một
name/symbolhợp lý trên siêu dữ liệu mint. - PDA của một vị trí được lấy từ mint NFT. Bạn có thể tìm
PersonalPositionStatemà không cần biết ai đang giữ nó.
Vị trí Token-2022
Các pool CLMM mới hơn có thể mint vị trí dưới Token-2022 thay vì SPL Token cổ điển. Chương trình công bố hai hướng dẫn song song —OpenPosition và OpenPositionWithToken22Nft — với ngữ nghĩa giống hệt nhau ngoại trừ chương trình token nào sở hữu mint NFT. Khả năng tương thích ví và marketplace khác nhau; giao diện Raydium theo dõi cả hai.
Quy tắc phạm vi cho phép
Tại thời điểmOpenPosition, chương trình thực thi:
tick_lower < tick_upper.tick_lower % tick_spacing == 0vàtick_upper % tick_spacing == 0.MIN_TICK <= tick_lowervàtick_upper <= MAX_TICK.- Người gọi đã cung cấp các mảng tick chứa
tick_lowervàtick_upper— hoặc đã được khởi tạo hoặc thông qua mộtinit_tick_arraytrong cùng một giao dịch. - Tài khoản mở rộng bitmap, nếu vị trí này kéo dài vào phạm vi mở rộng.
InvalidTickIndex, NotApproved, hoặc InsufficientLiquidity tùy thuộc vào ràng buộc nào. Xem reference/error-codes.
”In-range” vs “out-of-range”
Một vị trí ở trong dải khitick_lower <= tick_current < tick_upper. Chỉ các vị trí trong dải mới đóng góp vào PoolState.liquidity và do đó chỉ chúng mới kiếm được phí swap.
Một vị trí ngoài dải:
- Giữ 100% một token (cái mà dải của nó đã đi qua). Cụ thể, nếu
tick_current < tick_lower, vị trí chỉ giữ token1 (nó đã bị “bán” bởi giá di chuyển); nếutick_current >= tick_upper, nó chỉ giữ token0. - Không kiếm được phí swap.
- Tiếp tục tích lũy phần thưởng nếu các luồng phần thưởng của pool phát hành cho tính thanh khoản ngoài dải — nhưng hành vi mặc định của Raydium là “chỉ phát hành cho in-range”, khớp với quy ước Uniswap v3. Xem
products/clmm/fees.
Những cạm bẫy tích hợp phổ biến
- Điểm cuối không khớp khoảng cách. Mã tính toán một tick từ giá mục tiêu phải snap thành bội số của
tick_spacingtrước khi truyền nó tớiOpenPosition. Các trình trợ giúp SDK (TickUtils.getTickWithPriceAndTickspacing) làm điều này; toán học tự tạo thường không làm. - Mảng tick bị thiếu. Mở một vị trí rộng có thể yêu cầu khởi tạo một số mảng tick; quên truyền chúng làm các tài khoản writable sẽ hoàn nguyên. SDK’s
openPositionFromBasetrả danh sách cho bạn. - Tick cũ sau một swap.
tick_currentcó thể vượt qua nhiều tick trong một swap. Nếu UX của bạn hiển thị một “tick hiện tại” từ một lệnh gọi RPC và sau đó mở một vị trí trong một lệnh gọi sau đó, vị trí tương đối so với giá trực tiếp có thể chênh lệch hàng chục tick. Tìm lại ngay trước khi ký. - NFT vị trí với siêu dữ liệu bổ sung. Nếu bạn xây dựng một ví nhận ra các vị trí Raydium, phát hiện chúng bằng thẩm quyền mint (= PDA của chương trình CLMM), chứ không phải bằng một trường siêu dữ liệu được mã hóa cứng.
Nơi đến tiếp theo
- Math — bước swap từng bước và dẫn xuất tăng trưởng phí mà ranh giới tick tham gia vào.
- Accounts — các bố cục
TickArrayStatevàPositionState. - Fees and rewards — cách in-range-ness kiểm soát tích lũy phí.
algorithms/clmm-math— dẫn xuất chung của các công thức tính thanh khoản tập trung.
raydium-io/raydium-clmm— modulestick_array,tick,position- “Uniswap v3 Core” whitepaper, §6 (ticks), §7 (fee growth)


