Skip to main content
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 →
Trang này mô tả bố cục và vai trò của từng tài khoản. Các seed là chính thức và được liệt kê trong reference/program-addresses. Một pool CLMM sử dụng nhiều tài khoản hơn pool CPMM vì tính thanh khoản được lưu trữ một cách thưa thớt trên phạm vi tick; hiểu được tính thưa thớt này là phần chính của trang này.

Danh sách tài khoản

Một pool CLMM đang hoạt động được mô tả bởi các họ tài khoản sau. Tất cả đều được sở hữu bởi chương trình CLMM ngoại trừ hai mint và các vault của chúng.

PoolState

Trạng thái trực tiếp của pool, được đọc trên mỗi swap và mỗi thay đổi vị trí.
Các trường bạn thực sự sẽ sử dụng:
  • sqrt_price_x64 và tick_current là trạng thái giá của pool. Chúng được cập nhật cùng nhau trên mỗi swap. tick_current là sàn của log_{1.0001}(price).
  • liquidity là thanh khoản hoạt động — tổng các giá trị L cho tất cả các vị trí có phạm vi chứa tick_current. Nó thay đổi mỗi khi một swap vượt qua một tick và mỗi khi một vị trí được mở/đóng/thay đổi kích thước.
  • fee_growth_global_{0,1}_x64 là các phí tích lũy kiếm được trên mỗi đơn vị thanh khoản trên toàn bộ lịch sử pool. Các vị trí đọc điều này để tính toán những gì được nợ cho chúng.
  • tick_spacing được khóa vào AmmConfig khi khởi tạo và không bao giờ thay đổi. Nó xác định chỉ số tick nào được phép là điểm cuối vị trí.
  • tick_array_bitmap là một bitmap nội tuyến bao phủ phạm vi tick thường được sử dụng xung quanh giá spot. Đối với các pool có vị trí đạt xa, theo dõi tràn sống trong TickArrayBitmapExtension riêng biệt.
  • fee_on được cố định khi tạo pool. 0 (FromInput) tái tạo hành vi Uniswap-V3 cổ điển. 1 và 2 định tuyến phí swap sang một bên của sách — xem products/clmm/fees để biết các sự đánh đổi.
  • seed_index là [0, 0] cho mỗi pool được tạo thông qua CreatePool / CreateCustomizablePool (một pool chính thức cho mỗi cặp). Một giá trị khác không có nghĩa là pool được tạo qua CreatePermissionedPool và chỉ mục là một phần của các seed PDA của pool, cho phép nhiều pool cùng tồn tại cho cùng một (config, mint0, mint1). Để tái tạo địa chỉ của pool như vậy, bạn phải biết seed_index của nó.
  • dynamic_fee_info mang trạng thái biến động cho phí động. Khi được bật, mỗi swap tính toán lại một dynamic_fee_component trên AmmConfig.trade_fee_rate. Bố cục được ghi chép dưới DynamicFeeInfo bên dưới; các pool không có phí động để toàn bộ struct bằng không.

AmmConfig

Kể từ bản nâng cấp 2026-09, CreateAmmConfig ghi protocol_fee_owner::ID được mã hóa cứng của chương trình vào owner và fund_fee_owner::ID vào fund_owner. Trước đó, nó sao chép khóa người ký admin vào cả hai. Các config hiện có giữ bất kỳ thứ gì chúng được tạo hoặc xoay vòng, vì vậy hãy đọc cả hai trường từ tài khoản. Các tham số UpdateAmmConfig 3 / 4 vẫn xoay vòng chúng. Các địa chỉ nằm trong reference/program-addresses. Một bộ tầng phí CLMM được xuất bản điển hình (xác nhận so với GET https://api-v3.raydium.io/main/clmm-config): protocol_fee_rate và fund_fee_rate là các phân số của phí giao dịch; quy ước tương tự như CPMM. Xem products/clmm/fees.

TickArrayState

CLMM không lưu trữ một bản ghi duy nhất cho mỗi tick. Điều đó sẽ là hàng tỷ tài khoản. Thay vào đó, nó nhóm TICK_ARRAY_SIZE tick liền kề được khởi tạo hoặc không (thường là 60 hoặc 88 tùy thuộc vào phiên bản chương trình) thành một TickArrayState được tạo một cách lười biếng khi sử dụng lần đầu tiên.
Bốn trường lệnh giới hạn bằng không trên bất kỳ tick nào chưa bao giờ được sử dụng cho lệnh giới hạn. Khi các lệnh được mở trên một tick, chương trình theo dõi chúng như một chuỗi các cohort:
  • order_phase là id cohort. Nó tăng mỗi khi một cohort chuyển từ “tất cả chưa điền” sang “một phần điền”.
  • orders_amount là tổng token đầu vào của cohort hiện tại (mới nhất).
  • part_filled_orders_remaining theo dõi cohort trước đó hiện đang được điền bởi các swap đang diễn ra.
  • unfilled_ratio_x64 là một bộ nhân Q64.64 được mang trên cohort: khi một swap điền X% của cohort, tỷ lệ được nhân với (1 − X). Mỗi lệnh mở lưu trữ ảnh chụp (order_phase, unfilled_ratio_x64) của riêng nó tại thời điểm mở, vì vậy toán học giải quyết giảm xuống so sánh ảnh chụp.
Quy tắc:
  • Một tick điểm cuối vị trí t phải thỏa mãn t % tick_spacing == 0. Chương trình từ chối các vị trí không cách đều.
  • Mảng của tick được đặt tại floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing).
  • Một mảng tick được khởi tạo một cách lười biếng: vị trí hoặc swap đầu tiên chạm vào một mảng chưa được khởi tạo sẽ tạo nó, trả tiền thuê.
  • Một mảy tick không bao giờ được đóng bởi chương trình. Sau khi được cấp phát, nó tồn tại suốt đời của pool, ngay cả sau khi mỗi tick bên trong nó quay trở lại liquidity_gross == 0. Các vị trí và swap tiếp theo tái sử dụng tài khoản hiện có mà không cần thuê thêm. Không có đường dẫn dọn dẹp do ClosePosition cho các mảy tick.

TickArrayBitmapExtension

PoolState.tick_array_bitmap (nội tuyến) bao phủ phạm vi “gần spot” — ±512 mảy tick (TICK_ARRAY_BITMAP_SIZE = 512; trường [u64; 16] là 1,024 bit chia đều giữa các chỉ mục bắt đầu âm và dương, vì vậy chỉ mục mảy −512 … +511). Ngoài phạm vi đó (cho các giá trị tick cực đoan), chương trình duy trì một tài khoản mở rộng:
Nếu phạm vi vị trí của bạn là “bình thường”, bạn không bao giờ nghĩ về tài khoản mở rộng. Các vị trí toàn phạm vi (ví dụ: (MIN_TICK, MAX_TICK)) yêu cầu nó; SDK giải quyết nó cho bạn.

Vị trí

Một vị trí CLMM là một gói gồm ba tài khoản cộng với một mint:

Position NFT mint

Một mint SPL Token hoặc Token-2022 có cung cấp 1. NFT vị trí trong ví của chủ sở hữu là một ATA giữ token duy nhất đó. Chương trình khóa ủy quyền cho chủ sở hữu hiện tại của số dư ATA của NFT, không phải cho một Pubkey được lưu trữ trong trạng thái. Các mint NFT vị trí mới đặt pool_state làm quyền đóng băng của chúng trước khi mint token duy nhất và loại bỏ quyền mint. Đặt quyền đóng băng không tự nó đóng băng tài khoản NFT. Tài khoản vẫn không bị đóng băng và có thể chuyển được trừ khi cả hai điều kiện giữ: người gọi sử dụng OpenPositionV2 hoặc OpenPositionWithToken22Nft, và ít nhất một mint vault cơ bản có quyền đóng băng xuất hiện trên danh sách nhà phát hành bị hạn chế của CLMM. Chỉ khi đó CLMM mới đóng băng tài khoản NFT sau khi mint. Điều này không thay đổi bất kỳ byte PersonalPositionState hoặc PoolState nào.

PersonalPositionState

Một cho mỗi vị trí mở. Được khóa từ mint NFT.

ProtocolPositionState (không dùng nữa)

Các bản phát hành CLMM cũ hơn lưu trữ sổ cái tổng hợp theo (pool, tick_lower, tick_upper) trong một PDA ProtocolPositionState. Các bản phát hành mới không còn tạo hoặc đọc tài khoản này. Slot vẫn xuất hiện trên danh sách tài khoản OpenPosition / IncreaseLiquidity / DecreaseLiquidity như một UncheckedAccount để tương thích ABI, nhưng chương trình không ghi vào nó. Các tài khoản hiện có trên chuỗi là dư thừa; admin có thể gọi CloseProtocolPosition để lấy lại tiền thuê cho chúng.Sổ cái phạm vi tổng hợp hiện được lấy trực tiếp từ hai tick điểm cuối (liquidity_gross, liquidity_net và fee_growth_outside_* / reward_growths_outside_x64 theo tick) trong TickArrayState. Công thức tăng trưởng phí bên trong fee_growth_inside = global − outside_lower − outside_upper tiếp tục hoạt động mà không cần tài khoản vị trí tổng hợp.

Quan sát

Bộ đệm quan sát của CLMM lưu trữ một tick tích lũy, không phải giá tích lũy. Các người tiêu dùng bên ngoài tính toán giá trung bình hình học trên một khoảng từ (tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) và sau đó price = 1.0001 ** tick. Xem algorithms/clmm-math.

DynamicFeeConfig và DynamicFeeInfo

Các tham số phí động sống ở hai nơi. Mẫu có thể tái sử dụng — DynamicFeeConfig — được quản lý bởi admin và được chia sẻ trên các pool chọn tham gia. Trạng thái thời gian chạy cho mỗi pool — DynamicFeeInfo — được nhúng trong PoolState và được cập nhật bởi mỗi swap.

DynamicFeeConfig

Seed PDA: ["dynamic_fee_config", index.to_be_bytes()]. Được tạo qua create_dynamic_fee_config (được gated bởi admin) và được sửa đổi qua update_dynamic_fee_config. Một pool được tạo với enable_dynamic_fee = true chụp năm tham số hiệu chỉnh của config (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) vào DynamicFeeInfo của riêng nó khi tạo; các chỉnh sửa sau này đối với DynamicFeeConfig không ảnh hưởng retroactively đến các pool hiện có.

DynamicFeeInfo (nhúng trong PoolState)

Bốn trường dưới cùng là trạng thái; năm trường trên cùng là hiệu chỉnh được sao chép từ DynamicFeeConfig. Toán học phí và các quy tắc phân rã được ghi chép dưới products/clmm/math và products/clmm/fees. Các hằng số được sử dụng bởi công thức:

LimitOrderState

Một tài khoản cho mỗi lệnh giới hạn mở.
Vòng đời:
  1. Mở — người dùng gọi open_limit_order, gửi total_amount của token đầu vào, lệnh được ràng buộc với một cohort TickState.
  2. (tùy chọn) Tăng / Giảm — increase_limit_order thêm vào total_amount; decrease_limit_order trả lại các token chưa điền (và bất kỳ đầu ra đã giải quyết nào cho đến thời điểm đó).
  3. Giải quyết — khi cohort được điền hoàn toàn hoặc một phần, chủ sở hữu hoặc người giữ gìn hoạt động gọi settle_limit_order để đẩy token đầu ra đến ATA của chủ sở hữu.
  4. Đóng — khi unfilled_amount == 0, tài khoản có thể đóng được. Tiền thuê luôn quay trở lại owner.
Seed PDA: [owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. Lệnh PDA do đó là duy nhất cho mỗi (owner, nonce_index, order_nonce).

LimitOrderNonce

Bộ đếm cho mỗi (wallet, nonce_index) cho phép một người dùng duy nhất chạy nhiều đường ống lệnh giới hạn song song mà không va chạm trên các PDA.
Seed PDA: [user_wallet.as_ref(), &[nonce_index]]. Hầu hết các client sử dụng nonce_index = 0 và để order_nonce mang cardinality.

Permission

Một tài khoản khả năng có sự tồn tại là khoản cấp: nếu một PDA Permission được tạo cho một quyền nhất định, quyền đó có thể gọi CreatePermissionedPool. Nó không lưu trữ gì ngoài quyền nó được tạo cho.
Seed PDA: ["permission", authority.as_ref()]. Được tạo bởi một admin qua CreatePermissionPda và bị phá hủy qua ClosePermissionPda (tiền thuê hoàn lại cho người gọi). Cả hai hướng dẫn admin chấp nhận admin chương trình hoặc khóa permission_pda_admin chuyên dụng. Đóng PDA sẽ thu hồi khoản cấp — quyền không còn có thể tạo các pool bổ sung, nhưng các pool nó đã tạo không bị ảnh hưởng.

Tạo các tài khoản chính

Các chuỗi seed chính xác phải luôn được kiểm tra kỹ lưỡng so với IDL trên chuỗi và reference/program-addresses.

Tham chiếu nhanh vòng đời

Các tài khoản TickArrayState không bao giờ được đóng bởi chương trình — chúng tồn tại suốt đời của pool. Khi một mảy tick đã được khởi tạo, nó vẫn trên chuỗi ngay cả khi mỗi tick bên trong nó quay trở lại liquidity_gross == 0. Tái sử dụng một mảy tick hiện có là miễn phí; chỉ vị trí đầu tiên chạm vào một mảy chưa được khởi tạo mới trả tiền thuê của nó.

Đọc ở đâu

Nguồn: