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 →
ID chương trình và seed PDA cho CPMM được liệt kê chính thức trong reference/program-addresses. Trang này tập trung vào mục đích của mỗi tài khoản và các bất biến nó duy trì, không phải các địa chỉ được mã hóa cứng.

Sáu tài khoản của một pool CPMM

Mỗi pool CPMM được mô tả hoàn toàn bởi sáu địa chỉ dẫn xuất từ chương trình (PDA) dưới chương trình CPMM, cộng với một tài khoản AmmConfig dùng chung mà nó tham chiếu. Khi bạn có hai mint, bạn có thể dẫn xuất mọi thứ một cách xác định mà không cần chạm vào mạng. Và cấu hình dùng chung: Và một tài khoản tùy chọn cho mỗi người tạo:

Dẫn xuất một pool từ không có gì ngoài hai mint

Luôn sắp xếp mint trước khi dẫn xuất PDA pool. Seed băm hai mint theo thứ tự byte, không phải theo thứ tự người dùng. Hai pool với (A, B) và (B, A) sẽ va chạm trên chuỗi — sắp xếp là cách chương trình làm cho ánh xạ chính tắc.
ID pool không phải lúc nào cũng là PDA chính tắc. Initialize chấp nhận một keypair signer tùy ý làm pool_state ngoài PDA ở trên. Nếu tài khoản được truyền không khớp với PDA chính tắc, chương trình yêu cầu nó phải là một signer — tức là người tạo truyền một keypair mới mà họ ký. Đây là phòng chống front-run: bất kỳ bên thứ ba nào cố gắng chiếm PDA chính tắc có thể bị vượt qua bởi người tạo hợp pháp sử dụng một keypair ngẫu nhiên thay thế. Các PDA hạ lưu (lpMint, vault0, vault1, observation) vẫn được dẫn xuất từ poolState.key(), vì vậy chúng vẫn duy nhất cho bất kỳ địa chỉ nào được sử dụng. Khi bạn lập chỉ mục các pool, luôn khám phá ID pool từ trạng thái trên chuỗi (ví dụ: các tài khoản PoolState dưới chương trình CPMM), không phải bằng cách dẫn xuất PDA chính tắc — cách sau sẽ bỏ lỡ các pool keypair ngẫu nhiên.

Bố cục tài khoản

Các định nghĩa Rust đầy đủ nằm trong nguồn raydium-cp-swap. Các trường dưới đây là những trường bạn sẽ đọc từ một tích hợp.

PoolState

Những gì thực sự cần đọc:
  • lp_supply — tổng LP nội bộ của pool. Nó không bằng cung cấp của LP mint: nó chính xác cao hơn 100 đơn vị cơ sở, vì 100 đơn vị bị khóa được tính ở đây nhưng không bao giờ được mint. Tất cả toán học chia sẻ LP (deposit, withdraw) chia cho lp_supply, vì vậy hãy sử dụng trường này và không thay thế cung cấp trên chuỗi của mint.
  • protocol_fees_token{0,1}, fund_fees_token{0,1} — phí tích lũy chưa được quét. Những phí này không ảnh hưởng đến giá swap; chúng nằm trong vault cho đến khi CollectProtocolFee / CollectFundFee được gọi. protocol_fees_token{0,1} cũng nhận được phần chia của giao thức từ phí người tạo khi phí người tạo được thu thập, vì vậy nó tăng bên ngoài swap — xem products/cpmm/fees.
  • status — một bitmask kiểm soát xem Swap, Deposit, Withdraw có được phép hay không. Được cập nhật bởi quản trị viên thông qua UpdatePoolStatus. SDK kiểm tra điều này trước khi xây dựng giao dịch; nếu bạn đang CPI trực tiếp, hãy kiểm tra nó yourself.
  • token0_program / token1_program — chương trình token để CPI vào cho mỗi vault. Một có thể là SPL Token cổ điển và cái kia là Token-2022; chúng độc lập.
  • open_time — một dấu thời gian Unix. Swap trước thời điểm này sẽ thất bại. Deposit được phép trước open_time để pool có thể được seeded.
  • creator_fee_on / enable_creator_fee — cùng nhau kiểm soát xem phí người tạo tùy chọn có hoạt động cho pool này hay không và nó được thu từ phía nào của swap. enable_creator_fee == false loại bỏ hoàn toàn đường dẫn phí người tạo. Khi được bật, creator_fee_on chọn: 0 = lấy phí từ bất kỳ token nào là đầu vào swap (BothToken); 1 = lấy phí từ token_0 chỉ (bỏ qua trên swap token_1 → token_0); 2 = lấy phí từ token_1 chỉ. Được đặt tại tạo pool thông qua InitializeWithPermission; không thể thay đổi sau.
  • creator_fees_token_{0,1} — phí người tạo tích lũy, được quét bởi CollectCreatorFee hoặc CollectCreatorFeePermissionless. Cả hai đường dẫn đều xóa các bộ đếm đầy đủ, nhưng kể từ bản nâng cấp creator-fee-share ngày 2026-09-19, chỉ một phần số dư rời khỏi pool: phần chia của giao thức được thêm vào protocol_fees_token_{0,1} và phần còn lại được chuyển đến người tạo. Đường dẫn không có quyền sửa đổi các người nhận thành các ATA chính tắc của pool_creator. PoolState chính nó không thay đổi — không có bộ đếm riêng cho số tiền được chia sẻ.

AmmConfig

Ba điều cần cẩn thận:
  1. trade_fee_rate và creator_fee_rate là phân số của khối lượng, cả hai được biểu thị bằng đơn vị 1/1_000_000. 2500 có nghĩa là 0.25% của khối lượng giao dịch. protocol_fee_rate và fund_fee_rate là phân số của phí giao dịch (không phải của khối lượng), trong cùng mẫu số 1/1_000_000. Phí người tạo không là phân số của phí giao dịch — nó là tỷ lệ độc lập của riêng nó. Số học đầy đủ nằm trong products/cpmm/fees.
  2. index là một u16, vì vậy seed hash sử dụng 2 byte big-endian. Sai một byte trong thứ tự byte là một lỗi tích hợp phổ biến.
  3. AmmConfig là bất biến ở cấp pool. Một pool trỏ đến một AmmConfig tại tạo và không bao giờ chuyển đổi. Thay đổi phí lan truyền vì pool đọc cấu hình mỗi swap — nhưng pool không thể được di chuyển giữa các tầng phí.
Một lưu ý về phí người tạo: tỷ lệ chính nó (creator_fee_rate) nằm trên AmmConfig và được chia sẻ trên tầng phí. Liệu một pool cụ thể có thực sự tính phí hay không (enable_creator_fee) và nó hạ cánh ở phía nào của swap (creator_fee_on) nằm trên PoolState. Phí người tạo độc lập với phí giao dịch — nó là tỷ lệ riêng của nó, tích lũy vào các bộ đếm riêng của nó (creator_fees_token_{0,1}), và không bao giờ giảm phần chia LP / giao thức / quỹ của phí giao dịch. Quét được thực hiện thông qua CollectCreatorFee hoặc CollectCreatorFeePermissionless bị ràng buộc bởi đích, và cả hai đường dẫn đều trao một phần số dư tích lũy cho giao thức trên đường đi — tại creator_fee_share_rate, hoặc tại tỷ lệ trên PDA CreatorFeeShare khi một tồn tại cho cặp (creator, amm_config) đó. Xem products/cpmm/fees để biết cơ chế đầy đủ.

Permission

Một tài khoản kiểm soát truy cập nhỏ được sử dụng bởi InitializeWithPermission. Chương trình CPMM hỗ trợ một đường dẫn tạo pool có quyền hạn để các chương trình khác (ví dụ: LaunchLab khi nâng cấp token lên CPMM) có thể chứng minh rằng họ có quyền tạo pool chống lại một AmmConfig nhất định.
PDA Permission được tạo thông qua CreatePermissionPda bởi quản trị viên CPMM hoặc một quyền tạo PDA permission chuyên dụng. Kể từ bản nâng cấp 2026-09, ClosePermissionPda chấp nhận hai signer giống nhau; trước đó nó chỉ dành cho quản trị viên. Người dùng cuối không tương tác trực tiếp với tài khoản này — nó là đường ống cho các luồng cross-program. Xem security/admin-and-multisig để biết ranh giới vai trò và reference/program-addresses để biết các địa chỉ chính tắc.

CreatorFeeShare

Một tài khoản tùy chọn ghi đè phần chia của giao thức về phí người tạo cho một cặp (pool creator, AmmConfig). Được thêm bởi bản nâng cấp creator-fee-share ngày 2026-09-19.
Cách nó hoạt động:
  • Nó là tùy chọn, nhưng tài khoản không bao giờ tùy chọn trong lệnh. CollectCreatorFee và CollectCreatorFeePermissionless cả hai khai báo creator_fee_share với ràng buộc seed ở trên và lấy nó trên mỗi lệnh gọi. Chương trình sau đó kiểm tra xem tài khoản có trống hoặc sở hữu bởi nước ngoài hay không; nếu vậy nó quay lại AmmConfig.creator_fee_share_rate. Vì vậy, một client phải luôn dẫn xuất và truyền địa chỉ, cho dù tài khoản có tồn tại hay không.
  • share_rate được giới hạn ở FEE_RATE_DENOMINATOR_VALUE (1_000_000) tại tạo, và lại khi chia chạy. 1_000_000 định tuyến toàn bộ phí người tạo cho giao thức; 0 không định tuyến bất kỳ phí nào.
  • Được tạo và đóng bởi quản trị viên hoặc một quyền chuyên dụng thông qua CreateCreatorFeeShare / CloseCreatorFeeShare. Đóng nó trả lại tiền thuê cho người ký và cặp quay lại mặc định cấu hình; người tạo pool không phải là signer trên bất kỳ đường dẫn nào.
  • Nó được khóa trên người tạo, không phải pool. Một tài khoản quản lý mọi pool mà người tạo đó có trên AmmConfig đó. Một người tạo có pool trên hai tầng phí cần hai tài khoản để được bao phủ trên cả hai.
Số học chia mà nó điều khiển nằm trong products/cpmm/fees.

Vault và Token-2022

vault0 và vault1 được sở hữu bởi PDA authority của CPMM, và chủ sở hữu token-program của chúng (token_program) là SPL Token hoặc Token-2022, được xác định tại tạo pool bởi chương trình của mint. Pool xử lý hai trường hợp một cách minh bạch — bạn truyền ID token-program đúng cho mỗi phía trong các tài khoản lệnh Swap / Deposit / Withdraw. CPMM thực thi một danh sách cho phép extension nghiêm ngặt tại tạo pool (is_supported_mint trong utils/token.rs). Một mint Token-2022 có thể được sử dụng trong một pool CPMM chỉ nếu mọi extension mà nó mang đều nằm trong danh sách này:
  • TransferFeeConfig. Được áp dụng bởi mint trên mỗi lần chuyển. Pool nằm ở phía nhận cho deposit SwapBaseInput và phía gửi cho rút. Chương trình tính toán số tiền ròng hạ cánh trong vault và đặt đường cong tương ứng. Xem algorithms/token-2022-transfer-fees.
  • MetadataPointer và TokenMetadata. Siêu dữ liệu trên mint tiêu chuẩn. Không ảnh hưởng đến toán học swap.
  • InterestBearingConfig. Số tiền UI của mint tích lũy lãi. Vault lưu trữ số tiền thô; đường cong hoạt động chỉ trên số tiền thô. UI hiển thị APR nên gọi các trợ giúp Token-2022 để hiển thị số tiền UI.
  • ScaledUiAmount. Extension mở rộng quy mô hiển thị UI. Cách xử lý giống như InterestBearingConfig — đường cong sử dụng số tiền thô.
Bất kỳ extension nào khác — PermanentDelegate, TransferHook, DefaultAccountState, NonTransferable, ConfidentialTransfer, Group/GroupMember, MintCloseAuthority, v.v. — khiến Initialize từ chối với NotSupportMint. Một ngoại lệ là một sổ đăng ký cho mỗi mint: nếu một PDA SupportMintAssociated tồn tại tại seed [b"support_mint", mint], mint được chấp nhận bất kể tập extension của nó. PDA đó được tạo và xóa bởi quản trị viên (hoặc một quyền hỗ trợ mint chuyên dụng) thông qua CreateSupportMintAssociated / CloseSupportMintAssociated, vì vậy onboarding một mint cụ thể không còn cần nâng cấp chương trình.
Thay đổi trong 2026-09. CPMM trước đây cũng mang một MINT_WHITELIST bốn địa chỉ được mã hóa cứng đã bỏ qua kiểm tra extension. Mảng đó đã bị xóa; PDA sổ đăng ký hiện là bypass duy nhất. Bất kỳ mint nào dựa vào danh sách được mã hóa cứng cần một PDA SupportMintAssociated trước khi có thể tạo một pool mới cho nó — các pool hiện có không bị ảnh hưởng, vì kiểm tra chỉ chạy tại tạo pool.
Danh sách extension được kiểm duyệt nằm trong nguồn CP-Swap dưới programs/cp-swap/src/utils/token.rs và có thể thay đổi với các bản nâng cấp chương trình trong tương lai. Xem reference/token-2022-support để biết ma trận cross-program.

Observation

Tài khoản observation là một ring buffer của các mục ObservationState, mỗi mục lưu trữ một block_timestamp và một giá tích lũy. Trên mỗi swap, chương trình nối thêm một observation mới nếu đủ thời gian đã trôi qua kể từ observation cuối cùng. TWAP được tính toán bằng cách đọc hai observation và chia Δcumulative / Δtime.
Ring buffer được định kích thước cho 100 observation. Mỗi observation là 40 byte (8 + 16 + 16), vì vậy mảng một mình là 4,000 byte; ObservationState::LEN chính xác là 4,075 byte (8 + 1 + 2 + 32 + 4,000 + 8 × 4). Hai quy tắc người tiêu dùng:
  • Không sử dụng một observation duy nhất làm giá. Nó là một tích lũy, không phải giá spot. Sử dụng hai trong số chúng để tính toán TWAP.
  • Chọn observation cách nhau ít nhất một block. Swap trong cùng một block có thể không tạo ra một observation mới; đọc lại-lại có thể trả về cùng một bản ghi.
Thêm toán học trong products/clmm/accounts.

Vòng đời tài khoản

Các pool CPMM và PDA của chúng không bao giờ được đóng. Permission, SupportMintAssociated và CreatorFeeShare là những ngoại lệ — chúng là các bản ghi quản lý quản trị viên độc lập, không phải trạng thái pool, và mỗi bản ghi có một lệnh đóng rõ ràng. Ngay cả ở mức thanh khoản bằng không, poolState vẫn tồn tại. Điều này là cố ý: re-seeding cùng một pool sau này bảo tồn bộ đệm observation lịch sử của nó và dẫn xuất PDA của nó vẫn ổn định.

Những gì cần đọc ở đâu

Nguồn: