> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 2026-09-09 — CPMM: Anchor 1.0, excess-lamports recovery, and fixed fee owners

> CPMM chuyển sang Anchor 1.0.2 trên Agave 3.1.10 và thêm lệnh CollectExcessLamports dành cho admin để thu hồi lamports được giải phóng bởi SIMD-0437. CreateAmmConfig hiện ghi các chủ sở hữu phí giao thức và quỹ được mã hóa cứng thay vì người ký, danh sách trắng mint Token-2022 bốn địa chỉ bị xóa, và ClosePermissionPda chấp nhận cơ quan cấp quyền chuyên dụng. Lỗi 6015 được thêm vào.

<Info>
  **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 →](/reference/changelog/2026-09-09-cpmm-anchor-1-and-excess-lamports)
</Info>

<Info>
  Mục này bao gồm một bản cập nhật chương trình CPMM sắp tới. Nó đã được xác minh so với nhánh phát hành cục bộ trước khi triển khai. Xác nhận chương trình được triển khai trước khi dựa vào lệnh mới hoặc hành vi `CreateAmmConfig` đã thay đổi.
</Info>

Thay đổi chính của CPMM là một bước chuyển framework: Anchor từ `0.32.1` sang `=1.0.2`, và chuỗi công cụ xây dựng từ Agave 2.3.0 sang 3.1.10. Kèm theo đó là bốn thay đổi hành vi, ba trong số đó chỉ quan trọng đối với công cụ admin và một — việc xóa danh sách trắng mint — thay đổi mint Token-2022 nào có thể được sử dụng cho một **pool mới**.

Mọi thứ mà trader, LP hoặc người tạo pool gọi đều giữ nguyên danh sách tài khoản, đối số và toán học.

## TL;DR cho các nhà tích hợp

* **Không có lệnh nào hướng tới người dùng thay đổi.** `Initialize`, `InitializeWithPermission`, `Deposit`, `Withdraw`, `SwapBaseInput`, `SwapBaseOutput` và cả bốn đường dẫn `Collect*Fee` giống hệt nhau từng byte. Không có bố cục tài khoản nào thay đổi.
* **Một lệnh được thêm: `CollectExcessLamports`.** Chỉ dành cho admin, không có đối số, các tài khoản được truyền dưới dạng `remaining_accounts`. Nó trả về lamports vượt quá mức tối thiểu miễn phí thuê từ các vault, LP mint và PDA được kiểm soát bởi CPMM, và không chạm vào bất kỳ thứ gì khác. Xem [`products/cpmm/instructions`](/vi/products/cpmm/instructions#collectexcesslamports).
* **Một mã lỗi được thêm: `6015` `LamportsCalculateError`.** Các mã `6000`–`6014` không thay đổi.
* **`CreateAmmConfig` không còn sao chép người ký vào các trường chủ sở hữu phí.** Các config mới nhận các khóa `protocol_fee_owner` và `fund_fee_owner` được mã hóa cứng. **Các tài khoản `AmmConfig` hiện có không bị ảnh hưởng** — tiếp tục đọc `protocol_owner` / `fund_owner` từ tài khoản thay vì giả định bất kỳ giá trị nào.
* **Danh sách trắng `MINT_WHITELIST` Token-2022 bốn địa chỉ được mã hóa cứng đã biến mất.** Sổ đăng ký PDA `SupportMintAssociated` hiện là cách duy nhất của CPMM để vượt qua danh sách cho phép tiện ích. Các pool hiện có không bị ảnh hưởng; kiểm tra chạy chỉ khi tạo pool.
* **`ClosePermissionPda` chấp nhận cơ quan tạo PDA quyền chuyên dụng,** không chỉ admin được chia sẻ.
* **Cần làm mới IDL.** Một lệnh mới, một biến thể lỗi mới.
* **Gói client TypeScript được đổi tên.** `@coral-xyz/anchor` bị đóng băng ở `0.32.1`; client Anchor 1.x xuất bản dưới dạng `@anchor-lang/core`.

## `CollectExcessLamports`

Bước 1 của [SIMD-0437](/vi/solana-fundamentals/rent-and-reclaimable-rent) đã được triển khai trên mainnet vào ngày 3 tháng 9 năm 2026, giảm mức tối thiểu miễn phí thuê 9% với bốn bước nữa sắp tới. Mọi vault pool CPMM, LP mint, tài khoản `PoolState`, `AmmConfig`, `ObservationState`, `Permission` và `SupportMintAssociated` được tạo trước một bước hiện đã được tài trợ quá mức, và lamports trong tài khoản do chương trình sở hữu chỉ có thể được di chuyển bởi chương trình đó.

Lệnh này nhận bốn tài khoản cố định — ví tiền người ký/đích đến, PDA cơ quan `vault_and_lp_mint_auth_seed`, và **cả hai** chương trình token — sau đó bất kỳ số lượng tài khoản nguồn nào trong `remaining_accounts`. Nó phân phối dựa trên chủ sở hữu của mỗi tài khoản nguồn: một CPI tới `WithdrawExcessLamports` (discriminant `38`) của chương trình token cho tài khoản token hoặc mint, một khoản nợ trực tiếp cho PDA do CPMM sở hữu, và im lặng bỏ qua bất kỳ thứ gì khác.

Wrapped SOL là trường hợp đáng hiểu. Số dư lamport của tài khoản token gốc *là* số dư token của nó, vì vậy cả hai chương trình token đều từ chối `WithdrawExcessLamports` trên một. CPMM thay vào đó CPI `SyncNative` (gấp phần dư được quyên góp vào `amount` được bao bọc), đo lường mức độ tăng của số tiền, `UnwrapLamports` (discriminant `45`) cho chính xác delta đó, và sau đó yêu cầu số dư được bao bọc bằng giá trị trước khi đồng bộ hóa của nó — `LamportsCalculateError` nếu không. **Vault pool phía SOL giữ toàn bộ than流động của nó thông qua một lần quét**, và không có LP nào thấy thay đổi giá trên một.

Người ký có thể là admin chương trình được chia sẻ hoặc ví thu thập lamports chuyên dụng; các địa chỉ nằm trong [`reference/program-addresses`](/vi/reference/program-addresses#excess-lamports-collection-wallets).

## `CreateAmmConfig` ghi các chủ sở hữu phí cố định

Trước bản phát hành này, `create_amm_config` đặt cả hai trường chủ sở hữu phí từ người ký gọi:

```rust theme={null}
amm_config.protocol_owner = ctx.accounts.owner.key();
amm_config.fund_owner      = ctx.accounts.owner.key();
```

Nó hiện ghi các hằng số của chương trình:

```rust theme={null}
amm_config.protocol_owner = crate::protocol_fee_owner::ID;
amm_config.fund_owner      = crate::fund_fee_owner::ID;
```

Vì `CreateAmmConfig` được gated tới `crate::admin::ID`, hiệu ứng thực tế là một tầng phí mới được tạo được quét bởi các ví hoạt động chuyên dụng từ đầu thay vì bởi multisig admin, và admin không thể thu thập từ config mà nó vừa tạo mà không trước tiên xoay trường thông qua `UpdateAmmConfig` param `3` hoặc `4`.

Hai hằng số tuân theo cùng mô hình `cfg` devnet/mainnet như phần còn lại của các địa chỉ của chương trình, và trên devnet cả hai đều phân giải thành cùng một khóa. Xem [`reference/program-addresses`](/vi/reference/program-addresses#cpmm-fee-owner-wallets).

<Warning>
  **Đây không phải là một quá trình di chuyển.** Mọi `AmmConfig` đã tồn tại giữ bất kỳ `protocol_owner` và `fund_owner` nào mà nó được tạo với. Một công cụ thu thập bắt đầu mã hóa cứng các hằng số mới sẽ thất bại trên các config cũ hơn, và một công cụ giả định "khóa admin" sẽ thất bại trên các config mới. Đọc các trường.
</Warning>

## Danh sách trắng mint Token-2022 bị xóa

`is_supported_mint` từng đã đoạn mạch ngắn trên `MINT_WHITELIST` được mã hóa cứng của bốn địa chỉ trước khi lặp lại các tiện ích của mint. Mảng đó — và `HashSet` được xây dựng từ nó trên mỗi lệnh gọi — bị xóa. Những gì còn lại là:

1. Các mint SPL Token kế thừa vượt qua vô điều kiện.
2. Một mint có PDA `SupportMintAssociated` được khởi tạo tại `[b"support_mint", mint]` vượt qua vô điều kiện.
3. Nếu không, mọi tiện ích trên mint phải là một trong `TransferFeeConfig`, `MetadataPointer`, `TokenMetadata`, `InterestBearingConfig`, `ScaledUiAmount`.

PDA sổ đăng ký đã có trong chương trình một thời gian, với cặp `CreateSupportMintAssociated` / `CloseSupportMintAssociated` của riêng nó và cơ quan chuyên dụng của riêng nó cùng với admin được chia sẻ, và nó được tham khảo từ cả `Initialize` và `InitializeWithPermission`. Xóa mảng tĩnh có nghĩa là onboarding một mint hiện là một hành động trên chuỗi thuần túy thay vì một bản nâng cấp chương trình — đó là điểm.

**Các pool hiện có không bị ảnh hưởng**, vì kiểm tra mint chạy chỉ khi tạo pool. Những gì thay đổi là tạo một pool CPMM *mới* cho một trong bốn mint được đưa vào danh sách trắng trước đây yêu cầu mint đó phải có PDA sổ đăng ký — những cái quan trọng đã có trên mainnet. Bức tranh đầy đủ, bao gồm những gì sổ đăng ký làm và không miễn, nằm trong [`reference/token-2022-support`](/vi/reference/token-2022-support#bypass-paths).

## Mở rộng người ký `ClosePermissionPda`

`CreatePermissionPda` đã chấp nhận admin được chia sẻ hoặc cơ quan tạo PDA quyền chuyên dụng, trong khi `ClosePermissionPda` bị ghim vào admin với ràng buộc `address =`. Đường dẫn đóng hiện nhận cùng một cặp:

```rust theme={null}
constraint = (owner.key() == crate::admin::ID
           || owner.key() == crate::create_permission_pda_owner::ID) @ ErrorCode::InvalidOwner
```

Vì vậy, cơ quan cấp quyền cũng có thể thu hồi nó, mà không cần định tuyến qua multisig. Lỗi trên người ký không được phép là `InvalidOwner` (`6001`) bằng cách nào — ràng buộc `address =` cũ đã mang lỗi tùy chỉnh đó — vì vậy chỉ tập hợp các người ký được chấp nhận mở rộng.

## Thay đổi chuỗi công cụ và phụ thuộc

| Mục                                                                                  | Trước                             | Sau                                            |
| ------------------------------------------------------------------------------------ | --------------------------------- | ---------------------------------------------- |
| `anchor-lang` / `anchor-spl`                                                         | `0.32.1`                          | `=1.0.2`                                       |
| `Anchor.toml` `solana_version`                                                       | `2.3.0`                           | `3.1.10`                                       |
| `solana-sdk` / `-client` / `-account-decoder` / `-transaction-status` (client crate) | `2.3.0`                           | `3.0`                                          |
| `anchor-client` / `-lang` / `-spl` (client crate)                                    | `0.32.1`                          | `=1.0.2`                                       |
| README: `rustup default`                                                             | `1.81.0`                          | `1.91.0`                                       |
| README: Trình cài đặt Solana                                                         | `release.anza.xyz/v2.1.0`         | `release.anza.xyz/v3.1.10`                     |
| README: `avm install`                                                                | `0.31.0`                          | `1.0.2` (cộng với `avm use 1.0.2`)             |
| README: Kho Anchor                                                                   | `coral-xyz/anchor`                | `solana-foundation/anchor`                     |
| Hình ảnh Docker                                                                      | `solanafoundation/anchor:v0.32.1` | `solanafoundation/anchor:v1.0.2`               |
| `@coral-xyz/anchor`                                                                  | `0.32.1`                          | được thay thế bằng `@anchor-lang/core` `1.0.2` |
| `@solana/spl-token`                                                                  | `^0.4.8`                          | `^0.4.14`                                      |
| `typescript`                                                                         | `^4.3.5`                          | `^5.6.3`                                       |

Anchor 1.0 thay đổi hai điều tại mỗi trang web gọi CPI, điều này quan trọng nếu bạn tích hợp CPMM từ chương trình của riêng bạn: `CpiContext::new` nhận `Pubkey` của chương trình thay vì `AccountInfo` của nó, và `Context` có một tham số lifetime thay vì bốn. Trên phía client `RequestBuilder::instructions()` trả về `Vec<Instruction>` thay vì `Result<...>`, `CommitmentConfig` đến từ `anchor_client` thay vì `solana_sdk`, và `spl-associated-token-account` 8.0 di chuyển các trình trợ giúp địa chỉ của nó dưới `::address` và ID chương trình của nó thành `::program::ID`. Xem [`sdk-api/rust-cpi`](/vi/sdk-api/rust-cpi#cargo-dependencies).

Hai chi tiết hệ thống xây dựng, không có hiệu ứng trên chuỗi: crate chương trình khai báo tính năng `localnet` biên dịch ví cục bộ như `admin` từ biến môi trường `CPSWAP_LOCALNET_ADMIN` (vì vậy các bài kiểm tra được gated admin thực sự có thể ký — `yarn test:local-admin` kết nối nó), và khối `[profile.release]` trùng lặp trong `programs/cp-swap/Cargo.toml` bị xóa. Cargo bỏ qua `[profile]` bên ngoài gốc không gian làm việc, vì vậy khối gốc đã là khối có hiệu lực — bao gồm thực tế là `panic = "abort"` của khối cấp chương trình không bao giờ được áp dụng.

## Những gì không thay đổi

* **Mọi bố cục tài khoản.** `PoolState`, `AmmConfig`, `ObservationState`, `Permission`, `SupportMintAssociated` — cùng kích thước, cùng offset.
* **Mã lỗi `6000`–`6014`.**
* **Danh sách cho phép tiện ích chính nó.** Vẫn là cùng năm tiện ích.
* **Tỷ lệ phí, tích lũy phí và đường cong.** `CollectExcessLamports` di chuyển lamports không bao giờ là một phần của dự trữ của bất kỳ pool nào.
* **`spl_memo`.** Ràng buộc chương trình memo của `Withdraw` di chuyển từ `spl_memo::id()` sang `anchor_spl::memo::ID` — cùng một địa chỉ dưới xuất khẩu `anchor-spl` được đổi tên.
* **ID chương trình.** Không thay đổi.

## Trang được cập nhật

* `products/cpmm/instructions` — `CollectExcessLamports` được thêm với danh sách tài khoản và bảng phân phối theo chủ sở hữu; `CreateAmmConfig` nhận đối số `creator_fee_rate` và ghi chú về các chủ sở hữu phí cố định; hàng tóm tắt lệnh được thêm cho `CollectExcessLamports`, `CreateSupportMintAssociated`, `CloseSupportMintAssociated`; người ký `ClosePermissionPda` được sửa; điều kiện tiên quyết `Initialize` được viết lại cho bypass chỉ sổ đăng ký; hàng ma trận thay đổi trạng thái được thêm.
* `products/cpmm/accounts` — Phần Token-2022 được viết lại xung quanh PDA sổ đăng ký, với việc xóa danh sách trắng được gọi ra; người ký `ClosePermissionPda` được sửa.
* `products/cpmm/overview` — câu danh sách trắng được viết lại.
* `products/cpmm/code-demos` — Bộ xương CPI Rust được cập nhật cho Anchor 1.0.
* `reference/token-2022-support` — phần đường dẫn bypass được viết lại xung quanh PDA sổ đăng ký, với `MINT_WHITELIST` bị xóa được di chuyển vào phần "bypass bị xóa".
* `reference/error-codes` — `6015` được ghi lại.
* `reference/program-addresses` — các phần "CPMM support-mint registry authority", "CPMM fee-owner wallets" và "Excess-lamports collection wallets" mới; ghi chú `ClosePermissionPda` được sửa.
* `sdk-api/rust-cpi`, `solana-fundamentals/toolchain`, `integration-guides/cpi-integration` — Các chốt Anchor 1.0 và ghi chú di chuyển CPI.
* `solana-fundamentals/rent-and-reclaimable-rent` — phần "Những gì các chương trình Raydium quét ở phía của chính họ" mới.
