> ## 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-30 — CLMM：Anchor 1.0、超额 lamports 回收和固定费用所有者

> CLMM 升级到 Anchor 1.0.2（基于 Agave 3.1.10），并添加了管理员 CollectExcessLamports 指令以回收 SIMD-0437 释放的租金，每次扫描一个池，使用池 PDA 作为签名者。CreateAmmConfig 现在写入硬编码的协议和基金费用所有者，而不是签名者。错误代码 6052 已添加。没有用户面向的指令或账户布局发生变化。

<Info>
  **本页内容由 AI 自动翻译，所有内容以英文版本为准。**

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

<Info>
  本条目涵盖即将发布的 CLMM 程序更新。在部署前已根据 `raydium-clmm` 的 `chore/upgrade-anchor` 分支（head `a72f9e1`）进行验证。在依赖新指令或更改的 `CreateAmmConfig` 行为之前，请确认已部署的程序。
</Info>

CLMM 现在获得了 CPMM 和 LaunchLab 在 [2026-09-09](/zh/reference/changelog/2026-09-09-cpmm-anchor-1-and-excess-lamports) 发布的相同框架升级。Anchor 从 `0.32.1` 升级到 `=1.0.2`，构建工具链从 Agave 2.3.0 升级到 3.1.10。两项管理员端的变更随之而来：新的 `CollectExcessLamports` 指令和 `CreateAmmConfig` 中的固定费用所有者。

交易者、LP、限价单用户或池创建者调用的每条指令都保持其账户列表、参数和数学逻辑不变。

## 集成者速览

* **没有用户面向的指令发生变化。** `CreatePool`、`CreateCustomizablePool`、`CreatePermissionedPool`、所有 `OpenPosition*` / `IncreaseLiquidity*` / `DecreaseLiquidity*` 路径、`ClosePosition`、`Swap` / `SwapV2` / `SwapRouterBaseIn`、五条限价单指令和奖励指令在网络上字节相同。没有账户布局发生变化。
* **添加了一条指令：`CollectExcessLamports`。** 它仅限管理员使用，不接受参数。它每次扫描**一个池**：池自身的 `PoolState` 始终被扫描，池 PDA 为其金库签名，你在 `remaining_accounts` 中传入这些金库。`remaining_accounts` 中任何其他 CLMM 拥有的账户也会被扫描。参见 [`products/clmm/instructions`](/zh/products/clmm/instructions#collectexcesslamports)。
* **添加了一个错误代码：`6052` `LamportsCalculateError`。** 代码 `6000`–`6051` 保持不变。
* **`CreateAmmConfig` 不再将签名者复制到 `owner` / `fund_owner`。** 新配置获得硬编码的 `protocol_fee_owner` 和 `fund_fee_owner` 密钥。在主网上，这些是已存储在所有 21 个现有配置上的相同两个密钥。**现有的 `AmmConfig` 账户保持不变**，因此继续从账户中读取这些字段。
* **刷新你的 IDL。** 它添加了一条指令和一个错误变体，共 39 条指令和 53 个错误。
* **你现在可以在一个 crate 中放置 CPMM 和 CLMM。** 两个仓库在其 `chore/upgrade-anchor` 分支上都固定了 `anchor-lang` / `anchor-spl` `=1.0.2`，因此单个程序可以 CPI 到两者。参见 [`sdk-api/rust-cpi`](/zh/sdk-api/rust-cpi#cargo-dependencies)。
* **TypeScript 客户端包已重命名。** 测试套件从 `@coral-xyz/anchor` `0.32.1` 移至 `@anchor-lang/core` `1.0.2`。

## `CollectExcessLamports`

[SIMD-0437](/zh/solana-fundamentals/rent-and-reclaimable-rent) 的第 1 步在 2026 年 9 月 3 日在主网上激活。在步骤之前创建的每个 CLMM 账户现在都资金过多，只有 CLMM 程序可以将 lamports 移出它拥有的账户。这涵盖池金库、奖励金库、`PoolState`、`AmmConfig`、`ObservationState`、`TickArrayBitmapExtension` 等。

该指令接受四个固定账户，然后在 `remaining_accounts` 中接受任意数量的源账户：

| # | 账户                               | 角色                                                                          |
| - | -------------------------------- | --------------------------------------------------------------------------- |
| 1 | `collect_lamports_wallet` (W, S) | 签名者和目标。它必须是共享程序管理员或专用 CLMM 收集 lamports 钱包，否则调用失败并返回 `NotApproved` (`6000`)。 |
| 2 | `pool_state` (W)                 | 通过其 PDA 种子为代币程序 CPI 签名，并始终被扫描自身。                                            |
| 3 | `token_program`                  | SPL Token。                                                                  |
| 4 | `token_program_2022`             | Token-2022。两者都是必需的；程序根据源账户选择一个。                                             |

**池是签名权限，而不是程序范围的 PDA。** CPMM 使用一个全局 `vault_and_lp_mint_auth_seed` 权限签名。CLMM 代币金库由其 `PoolState` 拥有，因此单次调用只能为插槽 2 中传入的池签名。每个代币程序源必须以该池作为其权限：`token_vault_0`、`token_vault_1` 或池的奖励金库之一。来自另一个池或用户代币账户的代币账户会失败代币程序的所有者检查并回滚整个指令。程序不会跳过它。位置 NFT 铸币也不可扫描，因为当位置打开时其铸币权限被撤销。逐个池扫描。

该指令进行两次传递，顺序是固定的：

1. **代币程序 CPI 优先。** 对于由 SPL Token 或 Token-2022 拥有的每个源，非原生账户获得 `WithdrawExcessLamports`（判别式 `38`）。原生 wSOL 金库获得 `SyncNative` → `UnwrapLamports`（判别式 `45`）往返，以检查包装余额等于其同步前值。如果不相等，调用失败并返回 `LamportsCalculateError`。**SOL 端金库保持其完整流动性**，扫描过程中没有交换报价变化。
2. **直接扣款其次。** 传递 2 首先扣款 `pool_state`，然后扣款每个由 CLMM 程序拥有的源，直到 `rent.minimum_balance(data_len)`。

由任何其他程序拥有的源被静默跳过。这个两次传递顺序是 CPMM 在 [2026-09-19](/zh/reference/changelog/2026-09-19-cpmm-creator-fee-protocol-share) 采用的。CLMM 从其首次发布就有了。如果 PDA 在 CPI 之前被扣款，运行时会以 `UnbalancedInstruction` 中止，因此调用者可以按任何顺序传入源。

<Warning>
  **程序拥有的传递不检查账户属于哪个池或用户。** 任何由 CLMM 程序拥有的账户都符合条件，包括一些用户支付租金的账户：`PersonalPositionState`、`LimitOrderState` 和 `TickArrayState`。只有超过租金豁免最低限额的超额部分会移动。账户保持其数据并保持租金豁免。当位置或订单稍后关闭时，程序退款账户此时持有的任何余额。扫描后，该余额是当前租金最低限额。
</Warning>

钱包地址列在 [`reference/program-addresses`](/zh/reference/program-addresses#excess-lamports-collection-wallets)。

## `CreateAmmConfig` 写入固定费用所有者

在此版本之前，`create_amm_config` 从调用签名者设置两个费用所有者字段：

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

现在它写入程序自己的常量：

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

`CreateAmmConfig` 仍然限制在 `crate::admin::ID`。在此版本之前，每个新费用等级都以管理员开始，两个字段都需要使用 `UpdateAmmConfig` 参数 `3` / `4` 进行轮换。现在它以操作钱包开始。在主网上，常量是已存储为 `owner` / `fund_owner` 在所有 21 个现有配置上的相同密钥。程序现在写入操作人员过去手动设置的值。

收集签名者不变。`CollectProtocolFee` 接受 `amm_config.owner` **或** `crate::admin::ID`，`CollectFundFee` 接受 `amm_config.fund_owner` **或** `crate::admin::ID`，此版本前后都是如此。

在 devnet 上，两个常量解析为相同的密钥。参见 [`reference/program-addresses`](/zh/reference/program-addresses#clmm-fee-owner-wallets)。

<Warning>
  **这不是迁移。** 每个现有的 `AmmConfig` 保持其已有的 `owner` 和 `fund_owner`。读取字段而不是硬编码常量或管理员密钥。
</Warning>

## 工具链和依赖项变更

| 项目                                                                               | 之前                                        | 之后                                                                                                   |
| -------------------------------------------------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `anchor-lang` / `anchor-spl`（程序）                                                 | `=0.32.1`                                 | `=1.0.2`                                                                                             |
| `Anchor.toml` 工具链                                                                | `[tool-chain]`、`solana-version = "2.3.0"` | `[toolchain]`、`solana_version = "3.1.10"`                                                            |
| 工作区 `Cargo.toml`                                                                 | —                                         | `[workspace.metadata.cli] solana = "3.1.10"`                                                         |
| `anchor-client` / `anchor-lang`（客户端 crate）                                       | `0.32.1`                                  | `1.0.2`                                                                                              |
| `solana-sdk` / `-client` / `-account-decoder` / `-transaction-status`（客户端 crate） | `2.3.0`                                   | `3`                                                                                                  |
| `spl-token` / `spl-token-2022`（客户端 crate）                                        | `7.0.0` / `7.0.0`                         | `9.0` / `11.0`                                                                                       |
| `spl-associated-token-account` / `spl-memo` / `spl-token-client`（客户端 crate）      | `6.0.0` / `6.0.0` / `0.14.0`              | `8.0` / `7.0` / `0.19`                                                                               |
| `mpl-token-metadata`（客户端 crate）                                                  | `5.1.0`                                   | `=5.1.2-alpha.2`                                                                                     |
| 新客户端 crate                                                                       | —                                         | `solana-system-interface` `3.2`、`solana-commitment-config` `3`、`solana-compute-budget-interface` `3` |
| Docker 镜像                                                                        | `solanafoundation/anchor:v0.32.1`         | `solanafoundation/anchor:v1.0.2`                                                                     |
| `@coral-xyz/anchor`                                                              | `0.32.1`                                  | 由 `@anchor-lang/core` `1.0.2` 替代                                                                     |
| `typescript`                                                                     | `^4.3.5`                                  | `^5.6.3`                                                                                             |

Anchor 1.0 在 CPI 调用站点的变更与 CPMM 集成者已处理的相同。`CpiContext::new` 接受程序的 `Pubkey` 而不是其 `AccountInfo`，`Context` 有一个生命周期参数而不是四个。在客户端 crate 中，`RequestBuilder::instructions()` 现在返回 `Vec<Instruction>` 而不是 `Result`，`system_program` 移至 `solana-system-interface`。参见 [`sdk-api/rust-cpi`](/zh/sdk-api/rust-cpi#cargo-dependencies)。

没有链上效果的构建系统细节：

* **Localnet 管理员。** `localnet` 功能不再编译由提交的 fixture 支持的固定测试密钥。相反，它在构建时从 `CLMM_LOCALNET_ADMIN` 环境变量读取管理员，`yarn test:local-admin` 从你的本地钱包设置。fixture 的 `.gitignore` 例外已删除。
* **发布配置文件。** `programs/amm/Cargo.toml` 中的重复 `[profile.release]` 块已删除。Cargo 忽略工作区根外的 `[profile]`，因此根块已是有效的，程序级 `panic = "abort"` 从未应用。
* **Anchor.toml。** `seeds = false` 变为 `resolution = true` 加 `skip-lint = false`，陈旧的 `[registry]` URL 已删除。
* **Lints。** `programs/amm/Cargo.toml` 为 Anchor 和 Solana 宏发出的功能 cfg 添加了 `[lints.rust] unexpected_cfgs` 允许列表。
* **README。** 在此分支上，README 仍然告诉你从 `coral-xyz/anchor` 运行 `rustup default 1.86.0` 和 `avm install 0.32.1`。改为遵循 `Anchor.toml` 和 [`solana-fundamentals/toolchain`](/zh/solana-fundamentals/toolchain)。

## 未发生变化的内容

* **每个账户布局。** `PoolState`、`AmmConfig`、`TickArrayState`、`TickArrayBitmapExtension`、`PersonalPositionState`、`ObservationState`、`LimitOrderState`、`DynamicFeeConfig`、`Permission` 和 `SupportMintAssociated` 保持相同的大小和偏移。
* **错误代码 `6000`–`6051`。**
* **交换、流动性、费用、动态费用和限价单数学。** `CollectExcessLamports` 移动从未是任何池储备一部分的 lamports。
* **位置 NFT 冻结**来自 [2026-08-17](/zh/reference/changelog/2026-08-17-clmm-restricted-position-nft-freeze)，包括池作为冻结权限规则和 `ClosePosition` 解冻路径。
* **`spl_memo`。** `DecreaseLiquidityV2` 的备忘录程序约束从 `spl_memo::id()` 移至 `anchor_spl::memo::ID`。两者都命名相同地址；`anchor-spl` 只是重命名了导出。
* **程序 ID。**

## 更新的页面

* `products/clmm/instructions`：升级横幅；`CollectExcessLamports` 部分包含其账户列表、两次传递调度表和按池范围；库存、管理员门控和状态变更矩阵行；`CollectProtocolFee` / `CollectFundFee` 上的费用所有者注释。
* `products/clmm/accounts`：`AmmConfig` 所有者注释和关于 `CreateAmmConfig` 写入内容的注释。
* `products/clmm/code-demos`：版本横幅和 Rust CPI 骨架移至 Anchor 1.0。
* `products/cpmm/code-demos`："无法与 CLMM 共享 crate"注释已删除。
* `reference/error-codes`：`6052` 已记录。
* `reference/program-addresses`：新的"CLMM 费用所有者钱包"部分；CLMM 添加到"超额 lamports 收集钱包"。
* `sdk-api/rust-cpi`、`sdk-api/anchor-idl`、`solana-fundamentals/toolchain`：`raydium-clmm` 的 Anchor 1.0 固定，crate 分割警告已停用。
* `solana-fundamentals/rent-and-reclaimable-rent`：CLMM 添加到"Raydium 程序在其自身端扫描的内容"。
* `security/admin-and-multisig`：CLMM 超额 lamports 收集器角色。
* `protocol-overview/versions-and-migration`：CLMM 升级历史项目符号。
