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 là tài liệu tham khảo hướng dẫn chính thức. Để xem mã thực tế soạn các hướng dẫn này, hãy xem
products/cpmm/code-demos. Để biết ý nghĩa mã lỗi, xem reference/error-codes.Nâng cấp chương trình 2026-09 đã xây dựng lại CPMM trên Anchor 1.0.2 / Solana 3.1.10, thêm hướng dẫn quản trị viên CollectExcessLamports, loại bỏ danh sách mint Token-2022 được mã hóa cứng, và thay đổi những gì CreateAmmConfig ghi vào protocol_owner / fund_owner. Không có hướng dẫn nào hướng tới người dùng thay đổi tài khoản, đối số hoặc toán học của nó. Xem mục nhật ký thay đổi 2026-09-09.Tóm tắt hướng dẫn
Mặt nạ trạng thái:
status của mỗi pool là u8 trong đó bit 0 = deposit bị vô hiệu hóa, bit 1 = withdraw bị vô hiệu hóa, bit 2 = swap bị vô hiệu hóa (PoolStatusBitIndex { Deposit, Withdraw, Swap } trong chương trình). Một bit rõ ràng có nghĩa là hoạt động được phép; một bit được đặt có nghĩa là nó bị tạm dừng. UpdatePoolStatus lấy u8 thô và ghi đè giá trị hiện có.
Các phần tiếp theo đi qua từng phần chi tiết. Thứ tự tài khoản tuân theo IDL CPMM; SDK và máy khách Rust trong raydium-cp-swap/programs/cp-swap/src/instructions khớp với thứ tự này.
Initialize
Tạo một pool CPMM mới.
Đối số
* pool_state chỉ ký trên đường dẫn keypair ngẫu nhiên; đường dẫn PDA chính tắc chạy mà không cần pool_state ký.
Điều kiện trước
- Mint được sắp xếp (
token_0_mint < token_1_minttheo thứ tự byte). - Không mint nào sử dụng tiện ích mở rộng ngoài danh sách cho phép CPMM (
TransferFeeConfig,MetadataPointer,TokenMetadata,InterestBearingConfig,ScaledUiAmount) — xemproducts/cpmm/accounts. Một mint có PDASupportMintAssociated(seed[b"support_mint", mint]) bỏ qua kiểm tra; sổ đăng ký đó là lối thoát duy nhất kể từ khi nâng cấp 2026-09 loại bỏ danh sách mint bốn được mã hóa cứng. creatorcó ít nhấtinit_amount_0vàinit_amount_1trong các ATA tương ứng.amm_config.disable_create_pool == false.
pool_statetồn tại vớilp_supply = sqrt(init_amount_0 * init_amount_1) − LOCKED_LP.- Người khởi động LP của
LOCKED_LP(100lamport của token LP) bị khóa vĩnh viễn trong pool —pool_state.lp_supplyghi lạiliquidity − 100trong khi100đơn vị LP vẫn nằm ngoài lưu thông, ngăn pool bị thoát hết và chia cho không. observation_stateđược khởi tạo;observation_index = 0vàpool_id = pool_state.key().create_pool_feelamport được chuyển từ người tạo đến người nhận và được đồng bộ hóa dưới dạng SOL gốc (nó là ATA wSOL).- Mặt nạ trạng thái của pool là
0(deposit / withdraw / swap đều được bật). enable_creator_fee = falsevàcreator_fee_on = BothToken.Initializekhông hỗ trợ bật phí người tạo — đường dẫn đó làInitializeWithPermission.open_timeđược tăng lênblock_timestamp + 1nếu người gọi truyền một giá trị<= block_timestamp. Swap bị từ chối trướcopen_time; deposit và withdrawal hoạt động ngay lập tức.
reference/error-codes)
InvalidInput— mint không được sắp xếp hoặc mint giống hệt nhau.NotSupportMint— tiện ích mở rộng Token-2022 bị chặn.ExceededSlippage— hiếm khi; nếuinit_amount_0/1dẫn đến LP bằng không do không khớp số thập phân.
Deposit
Thêm thanh khoản ở cả hai token theo tỷ lệ với pool.
Đối số
Toán học
k — cả kho và lp_supply đều được chia tỷ lệ theo cùng một hệ số.
Điều kiện sau
lp_supply += lp_token_amount.vault_0 += needed_token_0(ròng của bất kỳ phí chuyển Token-2022 nào trên đầu vào).vault_1 += needed_token_1(ròng của bất kỳ phí chuyển Token-2022 nào trên đầu vào).
ExceededSlippage, ZeroTradingTokens, InvalidStatus nếu deposit bị tạm dừng.
Withdraw
Đốt token LP và nhận cả hai token cơ bản theo tỷ lệ.
Đối số
(Giống hệt như
Deposit; lp_mint có thể ghi vì token LP được đốt.)
Toán học
lp_supply -= lp_token_amount.- Kho gửi
out_token_0/out_token_1(tổng; người dùng nhận ròng của bất kỳ phí chuyển Token-2022 nào).
SwapBaseInput
Hoán đổi đầu vào chính xác.
Đối số
Thứ tự input → output là theo hướng của người dùng, không phải theo
token_0 / token_1 chính tắc của pool. Chương trình tìm ra kho nào là kho nào bằng cách khớp mint.
Toán học — xem products/cpmm/math.
Điều kiện trước
open_time <= now.pool_statuscho phép swap.- Không mint nào bị tạm dừng hoặc đóng băng cho cơ quan này.
amount_in > 0.
ExceededSlippage—amount_out < minimum_amount_out.ZeroTradingTokens— giao dịch làm tròn thành không.NotApproved— pool bị tạm dừng để swap thông quaUpdatePoolStatus.InvalidInput— mint không khớp với bất kỳ mint kho nào của pool.
SwapBaseOutput
Hoán đổi đầu ra chính xác.
Đối số
SwapBaseInput.
Toán học — đường cong nghịch đảo với trần, xem products/cpmm/math.
Lỗi phổ biến — ExceededSlippage (gross_in > max_amount_in), ZeroTradingTokens, InvalidInput, NotApproved.
CollectProtocolFee
Quét phí giao thức tích lũy từ các kho đến đích giao thức.
Đối số — không có.
Tài khoản
Hiệu ứng
NotApproved nếu người ký không phải là protocol_owner.
CollectFundFee
Hình dạng giống như CollectProtocolFee nhưng được ký bởi fund_owner và xóa các bộ đếm fund_fees_*.
CollectCreatorFee
Được ký bởi pool_state.pool_creator. Nó chuyển toàn bộ số dư creator_fees_token_0 và creator_fees_token_1 đến các tài khoản token của người tạo, sau đó xóa cả hai bộ đếm. Nó trả về NoFeeCollect khi cả hai bộ đếm đều bằng không.
CollectCreatorFeePermissionless
Bất kỳ ai cũng có thể kích hoạt bộ sưu tập phí người tạo. Hướng dẫn luôn gửi toàn bộ số dư tích lũy đến các tài khoản token liên kết chính tắc được sở hữu bởi pool_state.pool_creator; người gọi không thể chọn người tạo hoặc đích khác. Nếu bất kỳ ATA nào bị thiếu, người trả tiền sẽ tài trợ cho việc tạo nó.
CollectCreatorFee gốc vẫn có thể gọi được, vì vậy các máy khách hiện có vẫn tương thích.
Đối số — không có.
Tài khoản
Hiệu ứng
- Chuyển tất cả
creator_fees_token_0vàcreator_fees_token_1từ kho pool đến ATA người tạo. - Xóa cả hai bộ đếm phí người tạo và cập nhật
pool_state.recent_epoch. - Trả về
NoFeeCollectkhi cả hai bộ đếm đều bằng không.
UpdatePoolStatus
Tạm dừng hoặc tiếp tục các hoạt động riêng lẻ trên pool. Trường status là một mặt nạ bit:
Đối số
Khóa quản trị viên là cơ quan nâng cấp trên chương trình CPMM — trong thực tế, multisig Raydium. Xem
security/admin-and-multisig.
CreateAmmConfig
Tạo một tầng phí mới.
Đối số
Điều kiện trước
- Không có
AmmConfighiện có với cùngindex. protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
Thay đổi trong 2026-09: chủ sở hữu phí của config mới không còn đến từ người ký.
create_amm_config hiện ghi protocol_fee_owner::ID được mã hóa cứng của chương trình vào protocol_owner và fund_fee_owner::ID vào fund_owner, thay vì sao chép khóa người ký quản trị viên vào cả hai. Địa chỉ nằm trong reference/program-addresses.Hậu quả: một AmmConfig mới được tạo ngay lập tức được quét bởi các ví phí chuyên dụng thay vì khóa quản trị viên, và quản trị viên không thể thu thập từ một config mà nó vừa tạo mà không trước tiên xoay trường. Các tài khoản AmmConfig hiện có không được viết lại — bất kỳ gì được lưu trữ trên chúng vẫn chi phối, vì vậy luôn đọc protocol_owner / fund_owner từ tài khoản thay vì giả định bất kỳ giá trị nào. Các tham số UpdateAmmConfig 3 và 4 vẫn xoay chúng.UpdateAmmConfig
Thay đổi tỷ lệ phí hoặc quyền sở hữu trên AmmConfig hiện có. Lấy param: u8 (phân biệt cho trường nào để cập nhật) và value: u64. Ngữ nghĩa giá trị theo tham số nằm trong nguồn; thường:
param = 0→trade_fee_rateparam = 1→protocol_fee_rateparam = 2→fund_fee_rateparam = 3→new_protocol_owner(chuyển bytePubkeydưới dạng diễn giải lại)param = 4→new_fund_ownerparam = 5→create_pool_feeparam = 6→disable_create_pool
AmmConfig này trên swap tiếp theo. Không có di chuyển; pool chỉ đơn giản đọc các giá trị mới.
CollectExcessLamports
Quét quản trị viên của lamport nằm trên mức tối thiểu miễn phí thuê trên các tài khoản CPMM kiểm soát. Được thêm vào nâng cấp 2026-09 để giao thức có thể thu hồi quá mức tài trợ mà SIMD-0437 rent reduction để lại trên các tài khoản được tạo trước mỗi bước.
Chỉ phần dư di chuyển. Số dư token, dữ liệu tài khoản, chủ sở hữu, trạng thái pool và đường cong không bị chạm, và hướng dẫn là no-op đối với một tài khoản đã ở mức tối thiểu của nó — vì vậy nó an toàn để chạy lại sau mỗi bước triển khai.
Đối số — không có.
Tài khoản
Cách xử lý mỗi tài khoản nguồn
Chương trình gửi đi trên
owner của tài khoản nguồn:
Vì nó lấy danh sách
remaining_accounts không giới hạn, kích thước giao dịch là giới hạn thực tế — cùng một ràng buộc như quét phía ví được mô tả trong solana-fundamentals/rent-and-reclaimable-rent.
Lỗi phổ biến — InvalidOwner (6001, người ký sai), LamportsCalculateError (6015, vòng wSOL không ròng thành không), và InsufficientFunds từ đường dẫn sở hữu chương trình khi một tài khoản giữ ít hơn mức tối thiểu thuê của chính nó.
Không có trình tạo SDK. @raydium-io/raydium-sdk-v2 không gửi trình tạo cho hướng dẫn này, cũng không có kho raydium-sdk-V2-demo — nó là một đường dẫn quản trị viên. Mã hóa nó bằng tay, theo cách quét phía ví trong solana-fundamentals/rent-and-reclaimable-rent làm cho hướng dẫn chương trình token.
Ma trận thay đổi trạng thái
Tiếp theo đi đâu
products/cpmm/code-demos— mẫu TypeScript có thể chạy được cho các mẫu trên.reference/error-codes— bảng lỗi Anchor hoàn chỉnh.products/cpmm/fees— mô hình tích lũy phí mà các hướng dẫnCollect*Feethoát ra.

