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 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ố
Tài khoản (W = có thể ghi, S = ký) * 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_mint theo 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) — xem products/cpmm/accounts. Một mint có PDA SupportMintAssociated (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.
  • creator có ít nhất init_amount_0init_amount_1 trong các ATA tương ứng.
  • amm_config.disable_create_pool == false.
Điều kiện sau
  • pool_state tồn tại với lp_supply = sqrt(init_amount_0 * init_amount_1) − LOCKED_LP.
  • Người khởi động LP của LOCKED_LP (100 lamport của token LP) bị khóa vĩnh viễn trong pool — pool_state.lp_supply ghi lại liquidity − 100 trong khi 100 đơ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 = 0pool_id = pool_state.key().
  • create_pool_fee lamport đượ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 = falsecreator_fee_on = BothToken. Initialize không hỗ trợ bật phí người tạo — đường dẫn đó là InitializeWithPermission.
  • open_time được tăng lên block_timestamp + 1 nếu người gọi truyền một giá trị <= block_timestamp. Swap bị từ chối trước open_time; deposit và withdrawal hoạt động ngay lập tức.
Lỗi phổ biến (danh sách đầy đủ trong 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ếu init_amount_0/1 dẫ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ố
Tài khoản Toán học
Không thay đổi tính tỷ lệ của 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).
Lỗi phổ biếnExceededSlippage, 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ố
Tài khoản (Giống hệt như Deposit; lp_mint có thể ghi vì token LP được đốt.) Toán học
Điều kiện sau
  • 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ố
Tài khoản 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_status cho 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.
Lỗi phổ biến
  • ExceededSlippageamount_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 qua UpdatePoolStatus.
  • 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ố
Tài khoản — giống như SwapBaseInput. Toán học — đường cong nghịch đảo với trần, xem products/cpmm/math. Lỗi phổ biếnExceededSlippage (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
Không thay đổi số dư hiệu quả của đường cong (phí tích lũy đã bị loại trừ). Lỗi phổ biếnNotApproved 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_0creator_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_0creator_fees_token_1 từ 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ề NoFeeCollect khi 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ố
Tài khoản 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ố
Tài khoản Điều kiện trước
  • Không có AmmConfig hiện có với cùng index.
  • 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_ownerfund_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 34 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 = 0trade_fee_rate
  • param = 1protocol_fee_rate
  • param = 2fund_fee_rate
  • param = 3new_protocol_owner (chuyển byte Pubkey dưới dạng diễn giải lại)
  • param = 4new_fund_owner
  • param = 5create_pool_fee
  • param = 6disable_create_pool
Các thay đổi được ký bởi quản trị viên và ảnh hưởng đến mọi pool được ràng buộc với 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ếnInvalidOwner (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

Nguồn: