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ẽ chạm vào:
  • sqrt_price_x64tick_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 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à bitmap nội tuyến bao phủ phạm vi “gần spot” — ±1.024 tick array. Đối với các pool có vị trí đạt xa, theo dõi tràn sống trong tài khoản 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. 12 đị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[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). 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). Để dẫn xuất lại đị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 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

Một bộ tầng phí CLMM được công bố điển hình (xác nhận so với GET https://api-v3.raydium.io/main/clmm-config): protocol_fee_ratefund_fee_rate là các phân số của phí giao dịch; cùng quy ước 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 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 nhóm:
  • order_phase là id nhóm. Nó tăng mỗi khi một nhóm 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 nhóm hiện tại (mới nhất).
  • part_filled_orders_remaining theo dõi nhóm trước đó hiện đang được điền bởi các swap đang diễn ra.
  • unfilled_ratio_x64 là bộ nhân Q64.64 được mang trên nhóm: khi swap điền X% của nhóm, 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:
  • 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 tick array đượ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 tạo ra nó, trả tiền cho tiền thuê.
  • Một tick array không bao giờ được đóng bởi chương trình. Sau khi được phân bổ, 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 tiền thuê thêm. Không có đường dẫn dọn dẹp do ClosePosition cho các tick array.

TickArrayBitmapExtension

PoolState.tick_array_bitmap (nội tuyến) bao phủ phạm vi “gần spot” — ±1.024 tick array. 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à của ba tài khoản cộng với một mint:

Position NFT mint

Một mint SPL Token hoặc Token-2022 với cung cấp 1. Position NFT trong ví của chủ sở hữu là 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 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 ProtocolPositionState PDA. 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ư 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 tổng hợp phạm vi hiện được dẫn xuất trực tiếp từ hai tick điểm cuối (liquidity_gross, liquidity_netfee_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ữ 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.

DynamicFeeConfigDynamicFeeInfo

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 trên 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à 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ó tại thời điểm 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/mathproducts/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 nhóm TickState.
  2. (tùy chọn) Tăng / Giảmincrease_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 nhóm đượ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 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

Tài khoản khả năng có sự tồn tại là khoản cấp: nếu Permission PDA được dẫn xuất 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 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.

Dẫn xuất 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 tick array đã đượ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 tick array hiện có là miễn phí; chỉ vị trí đầu tiên chạm vào một mảng chưa được khởi tạo bao giờ trả tiền cho tiền thuê của nó.

Đọc ở đâu

Nguồn: