> ## 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、超額 lamports 回收與固定費用所有者

> CPMM 升級至 Anchor 1.0.2（基於 Agave 3.1.10），新增管理員 CollectExcessLamports 指令以回收 SIMD-0437 釋放的租金。CreateAmmConfig 現在寫入硬編碼的協議與基金費用所有者而非簽署者，移除四地址 Token-2022 鑄幣廠白名單，ClosePermissionPda 接受專用授權權限。新增錯誤代碼 6015。

<Info>
  **本頁內容由 AI 自動翻譯，所有內容以英文版本為準。**

  [查看英文版 →](/reference/changelog/2026-09-09-cpmm-anchor-1-and-excess-lamports)
</Info>

<Info>
  本條目涵蓋即將推出的 CPMM 程式更新。在部署前已針對本地發佈分支進行驗證。在依賴新指令或變更的 `CreateAmmConfig` 行為之前，請確認已部署的程式。
</Info>

CPMM 的主要變更是框架升級：Anchor 從 `0.32.1` 升至 `1.0.2`，構建工具鏈從 Agave 2.3.0 升至 3.1.10。隨之而來的是四項行為變更，其中三項僅影響管理工具，一項——鑄幣廠白名單移除——會改變哪些 Token-2022 鑄幣廠可用於**新**流動性池。

交易者、流動性提供者或流動性池創建者調用的所有內容都保持其帳戶列表、參數和數學邏輯不變。

## 集成者速覽

* **沒有面向用戶的指令改變。** `Initialize`、`InitializeWithPermission`、`Deposit`、`Withdraw`、`SwapBaseInput`、`SwapBaseOutput` 和全部四個 `Collect*Fee` 路徑在位元組層面完全相同。沒有帳戶佈局改變。
* **新增一個指令：`CollectExcessLamports`。** 僅限管理員，無參數，來源帳戶作為 `remaining_accounts` 傳遞。它從 CPMM 控制的金庫、LP 鑄幣廠和 PDA 返回超過租金豁免最低額的 lamports，不觸及其他任何內容。詳見 [`products/cpmm/instructions`](/zh-Hant/products/cpmm/instructions#collectexcesslamports)。
* **新增一個錯誤代碼：`6015` `LamportsCalculateError`。** 代碼 `6000`–`6014` 保持不變。
* **`CreateAmmConfig` 不再將簽署者複製到費用所有者欄位。** 新配置獲得硬編碼的 `protocol_fee_owner` 和 `fund_fee_owner` 鍵。**現有 `AmmConfig` 帳戶保持不變**——應從帳戶讀取 `protocol_owner` / `fund_owner`，而不是假設任一值。
* **硬編碼的四地址 Token-2022 `MINT_WHITELIST` 已移除。** `SupportMintAssociated` PDA 登錄表現在是 CPMM 繞過擴展允許清單的唯一方式。現有流動性池不受影響；檢查僅在流動性池創建時運行。
* **`ClosePermissionPda` 接受專用權限 PDA 創建者權限，** 不僅限於共享管理員。
* **需要 IDL 刷新。** 一個新指令，一個新錯誤變體。
* **TypeScript 客戶端套件已重命名。** `@coral-xyz/anchor` 凍結在 `0.32.1`；Anchor 1.x 客戶端發佈為 `@anchor-lang/core`。

## `CollectExcessLamports`

[SIMD-0437](/zh-Hant/solana-fundamentals/rent-and-reclaimable-rent) 的第 1 步於 2026 年 9 月 3 日在主網上線，將租金豁免最低額降低 9%，還有四個步驟待來。在步驟之前創建的每個 CPMM 流動性池金庫、LP 鑄幣廠、`PoolState`、`AmmConfig`、`ObservationState`、`Permission` 和 `SupportMintAssociated` 帳戶現在都資金過剩，而程式擁有的帳戶中的 lamports 只能由該程式移動。

該指令接受四個固定帳戶——簽署者/目標錢包、`vault_and_lp_mint_auth_seed` 權限 PDA 和**兩個**代幣程式——然後在 `remaining_accounts` 中接受任意數量的來源帳戶。它根據每個來源帳戶的所有者進行分派：對代幣帳戶或鑄幣廠的代幣程式 `WithdrawExcessLamports`（判別式 `38`）進行 CPI，對 CPMM 擁有的 PDA 進行直接扣款，對其他任何內容則無聲跳過。

包裝 SOL 是值得理解的情況。原生代幣帳戶的 lamport 餘額*就是*其代幣餘額，因此兩個代幣程式都拒絕對其進行 `WithdrawExcessLamports`。CPMM 改為 CPI `SyncNative`（將捐贈的超額折疊到包裝的 `amount` 中），測量金額增長了多少，對該增量進行 `UnwrapLamports`（判別式 `45`），然後要求包裝餘額等於其同步前值——如果不相等則返回 `LamportsCalculateError`。**SOL 端流動性池金庫通過掃描保持其完整流動性**，沒有 LP 看到跨掃描的價格變化。

簽署者可以是共享程式管理員或專用 lamports 收集錢包；地址位於 [`reference/program-addresses`](/zh-Hant/reference/program-addresses#excess-lamports-collection-wallets)。

## `CreateAmmConfig` 寫入固定費用所有者

在此版本之前，`create_amm_config` 從調用簽署者設置兩個費用所有者欄位：

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

現在它寫入程式自己的常數：

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

由於 `CreateAmmConfig` 受限於 `crate::admin::ID`，實際效果是新創建的費用層級從一開始就由專用運營錢包掃描，而不是由管理員多簽，管理員無法從其剛創建的配置中收集費用，除非先通過 `UpdateAmmConfig` 參數 `3` 或 `4` 輪換該欄位。

這兩個常數遵循與程式其餘地址相同的 devnet/mainnet `cfg` 模式，在 devnet 上兩者都解析為相同的鍵。詳見 [`reference/program-addresses`](/zh-Hant/reference/program-addresses#cpmm-fee-owner-wallets)。

<Warning>
  **這不是遷移。** 每個已存在的 `AmmConfig` 保持其創建時的 `protocol_owner` 和 `fund_owner`。開始硬編碼新常數的收集工具將在舊配置上失敗，假設「管理員鍵」的工具將在新配置上失敗。請讀取這些欄位。
</Warning>

## Token-2022 鑄幣廠白名單已移除

`is_supported_mint` 曾在迭代鑄幣廠擴展之前在硬編碼的四地址 `MINT_WHITELIST` 上短路。該陣列——以及每次調用時從其構建的 `HashSet`——已刪除。保留的是：

1. 舊版 SPL Token 鑄幣廠無條件通過。
2. 在 `[b"support_mint", mint]` 處有初始化 `SupportMintAssociated` PDA 的鑄幣廠無條件通過。
3. 否則鑄幣廠上的每個擴展必須是 `TransferFeeConfig`、`MetadataPointer`、`TokenMetadata`、`InterestBearingConfig`、`ScaledUiAmount` 之一。

登錄表 PDA 已在程式中存在一段時間，具有自己的 `CreateSupportMintAssociated` / `CloseSupportMintAssociated` 對及其自己的專用權限（與共享管理員並行），並從 `Initialize` 和 `InitializeWithPermission` 中查詢。移除靜態陣列意味著鑄幣廠上線現在純粹是鏈上操作，而不是程式升級——這正是目的。

**現有流動性池不受影響**，因為鑄幣廠檢查僅在流動性池創建時運行。改變的是為四個先前白名單鑄幣廠之一創建*新* CPMM 流動性池現在要求該鑄幣廠具有登錄表 PDA——在主網上重要的那些已經有了。完整圖景，包括登錄表做什麼和不做什麼豁免，位於 [`reference/token-2022-support`](/zh-Hant/reference/token-2022-support#bypass-paths)。

## `ClosePermissionPda` 簽署者擴寬

`CreatePermissionPda` 已接受共享管理員或專用權限 PDA 創建者權限，而 `ClosePermissionPda` 被固定為帶有 `address =` 約束的管理員。關閉路徑現在接受相同的對：

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

因此發出授權的權限也可以撤銷它，無需通過多簽。未授權簽署者上的錯誤是 `InvalidOwner`（`6001`）——舊的 `address =` 約束已經帶有該自定義錯誤——因此只有接受的簽署者集合擴寬。

## 工具鏈和依賴項變更

| 項目                                                                               | 之前                                | 之後                               |
| -------------------------------------------------------------------------------- | --------------------------------- | -------------------------------- |
| `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`（客戶端 crate） | `2.3.0`                           | `3.0`                            |
| `anchor-client` / `-lang` / `-spl`（客戶端 crate）                                    | `0.32.1`                          | `=1.0.2`                         |
| README：`rustup default`                                                          | `1.81.0`                          | `1.91.0`                         |
| README：Solana 安裝程式                                                               | `release.anza.xyz/v2.1.0`         | `release.anza.xyz/v3.1.10`       |
| README：`avm install`                                                             | `0.31.0`                          | `1.0.2`（加上 `avm use 1.0.2`）      |
| README：Anchor 倉庫                                                                 | `coral-xyz/anchor`                | `solana-foundation/anchor`       |
| Docker 映像                                                                        | `solanafoundation/anchor:v0.32.1` | `solanafoundation/anchor:v1.0.2` |
| `@coral-xyz/anchor`                                                              | `0.32.1`                          | 由 `@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 在每個 CPI 調用位置改變兩件事，如果你從自己的程式集成 CPMM 這很重要：`CpiContext::new` 接受程式的 `Pubkey` 而不是其 `AccountInfo`，`Context` 有一個生命週期參數而不是四個。在客戶端，`RequestBuilder::instructions()` 返回 `Vec<Instruction>` 而不是 `Result<...>`，`CommitmentConfig` 來自 `anchor_client` 而不是 `solana_sdk`，`spl-associated-token-account` 8.0 將其地址幫助程式移到 `::address` 下，其程式 ID 移到 `::program::ID`。詳見 [`sdk-api/rust-cpi`](/zh-Hant/sdk-api/rust-cpi#cargo-dependencies)。

兩個構建系統細節，都沒有鏈上效果：程式 crate 聲明一個 `localnet` 功能，從 `CPSWAP_LOCALNET_ADMIN` 環境變數將本地錢包編譯為 `admin`（因此管理員門控測試實際上可以簽署——`yarn test:local-admin` 連接它），`programs/cp-swap/Cargo.toml` 中的重複 `[profile.release]` 塊已刪除。Cargo 忽略工作區根外的 `[profile]`，因此根塊已經是生效的——包括程式級塊的 `panic = "abort"` 從未應用的事實。

## 未改變的內容

* **每個帳戶佈局。** `PoolState`、`AmmConfig`、`ObservationState`、`Permission`、`SupportMintAssociated`——相同大小、相同偏移。
* **錯誤代碼 `6000`–`6014`。**
* **擴展允許清單本身。** 仍然是相同的五個擴展。
* **費率、費用累積和曲線。** `CollectExcessLamports` 移動從未成為任何流動性池儲備一部分的 lamports。
* **`spl_memo`。** `Withdraw` 的備忘錄程式約束從 `spl_memo::id()` 移至 `anchor_spl::memo::ID`——在重命名的 `anchor-spl` 導出下相同地址。
* **程式 ID。** 未改變。

## 更新的頁面

* `products/cpmm/instructions` — 新增 `CollectExcessLamports` 及其帳戶列表和按所有者分派表；`CreateAmmConfig` 獲得其 `creator_fee_rate` 參數和固定費用所有者的說明；為 `CollectExcessLamports`、`CreateSupportMintAssociated`、`CloseSupportMintAssociated` 新增指令摘要行；`ClosePermissionPda` 簽署者已更正；`Initialize` 前置條件為僅登錄表繞過重寫；新增狀態變更矩陣行。
* `products/cpmm/accounts` — Token-2022 部分圍繞登錄表 PDA 重寫，白名單移除已標註；`ClosePermissionPda` 簽署者已更正。
* `products/cpmm/overview` — 白名單句子已重寫。
* `products/cpmm/code-demos` — Rust CPI 骨架已更新為 Anchor 1.0。
* `reference/token-2022-support` — 繞過路徑部分圍繞登錄表 PDA 重寫，已移除的 `MINT_WHITELIST` 移至「已移除繞過」部分。
* `reference/error-codes` — `6015` 已記錄。
* `reference/program-addresses` — 新增「CPMM 支持鑄幣廠登錄表權限」、「CPMM 費用所有者錢包」和「超額 lamports 收集錢包」部分；`ClosePermissionPda` 說明已更正。
* `sdk-api/rust-cpi`、`solana-fundamentals/toolchain`、`integration-guides/cpi-integration` — Anchor 1.0 引腳和 CPI 遷移說明。
* `solana-fundamentals/rent-and-reclaimable-rent` — 新增「Raydium 程式在其自身端掃描的內容」部分。
