> ## 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 переходит на Anchor 1.0.2 с Agave 3.1.10 и добавляет инструкцию admin CollectExcessLamports для возврата ренты, освобождённой SIMD-0437. CreateAmmConfig теперь записывает жёсткие адреса владельцев протокольного и фондового сборов вместо адреса подписывающей стороны, четырёхадресный whitelist минтов Token-2022 удалён, а ClosePermissionPda принимает выделенный орган выдачи разрешений. Добавлена ошибка 6015.

<Info>
  **Эта страница переведена с помощью ИИ. За эталон принимается английская версия.**

  [Открыть английскую версию →](/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. Вместе с этим идут четыре изменения поведения, три из которых касаются только инструментов администратора, а одно — удаление whitelist минтов — влияет на то, какие минты Token-2022 можно использовать для **нового** пула.

Все инструкции, которые вызывают трейдеры, LP и создатели пулов, сохраняют список аккаунтов, аргументы и математику.

## TL;DR для интеграторов

* **Ни одна инструкция, видимая пользователю, не изменилась.** `Initialize`, `InitializeWithPermission`, `Deposit`, `Withdraw`, `SwapBaseInput`, `SwapBaseOutput` и все четыре пути `Collect*Fee` побайтово идентичны. Ни один макет аккаунта не изменился.
* **Добавлена одна инструкция: `CollectExcessLamports`.** Только для администратора, без аргументов, источники передаются как `remaining_accounts`. Она возвращает lamports сверх минимума, освобождённого от ренты, из хранилищ, контролируемых CPMM, LP минтов и PDA, и ничего больше не трогает. См. [`products/cpmm/instructions`](/ru/products/cpmm/instructions#collectexcesslamports).
* **Добавлен один код ошибки: `6015` `LamportsCalculateError`.** Коды `6000`–`6014` не изменились.
* **`CreateAmmConfig` больше не копирует адрес подписывающей стороны в поля владельцев сборов.** Новые конфигурации получают жёсткие адреса `protocol_fee_owner` и `fund_fee_owner`. **Существующие аккаунты `AmmConfig` не трогаются** — продолжайте читать `protocol_owner` / `fund_owner` из аккаунта вместо предположения о каком-либо значении.
* **Жёсткий четырёхадресный `MINT_WHITELIST` Token-2022 удалён.** Реестр PDA `SupportMintAssociated` теперь является единственным способом обхода списка разрешённых расширений CPMM. Существующие пулы не затронуты; проверка выполняется только при создании пула.
* **`ClosePermissionPda` принимает выделенный орган создания permission-PDA,** а не только общего администратора.
* **Требуется обновление IDL.** Одна новая инструкция, один новый вариант ошибки.
* **Пакет TypeScript клиента переименован.** `@coral-xyz/anchor` заморожен на `0.32.1`; клиент Anchor 1.x публикуется как `@anchor-lang/core`.

## `CollectExcessLamports`

Шаг 1 [SIMD-0437](/ru/solana-fundamentals/rent-and-reclaimable-rent) вышел на mainnet 3 сентября 2026 года, сократив минимум, освобождённый от ренты, на 9% с четырьмя дополнительными шагами впереди. Каждое хранилище пула CPMM, LP минт, аккаунты `PoolState`, `AmmConfig`, `ObservationState`, `Permission` и `SupportMintAssociated`, созданные до шага, теперь переполнены, и lamports в аккаунте, принадлежащем программе, могут быть перемещены только этой программой.

Инструкция принимает четыре фиксированных аккаунта — кошелёк подписывающей стороны/назначения, PDA органа `vault_and_lp_mint_auth_seed` и **оба** программы токенов — затем любое количество исходных аккаунтов в `remaining_accounts`. Она распределяет по владельцу каждого исходного аккаунта: CPI к `WithdrawExcessLamports` программы токенов (дискриминант `38`) для аккаунта токена или минта, прямой дебет для PDA, принадлежащего CPMM, и молча пропускает всё остальное.

Wrapped SOL — это случай, который стоит понять. Баланс lamports нативного аккаунта токена *является* его балансом токена, поэтому обе программы токенов отклоняют `WithdrawExcessLamports` на нём. CPMM вместо этого вызывает CPI `SyncNative` (складывая пожертвованный избыток в завёрнутый `amount`), измеряет, насколько вырос amount, вызывает `UnwrapLamports` (дискриминант `45`) ровно на эту дельту, а затем требует, чтобы завёрнутый баланс равнялся его значению до синхронизации — `LamportsCalculateError`, если это не так. **Хранилище пула на стороне SOL сохраняет полную ликвидность через sweep**, и ни один LP не видит изменения цены через один.

Подписывающей стороной может быть либо общий администратор программы, либо выделенный кошелёк для сбора lamports; адреса находятся в [`reference/program-addresses`](/ru/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`.

Две константы следуют тому же шаблону `cfg` devnet/mainnet, что и остальные адреса программы, и на devnet обе разрешаются в один и тот же ключ. См. [`reference/program-addresses`](/ru/reference/program-addresses#cpmm-fee-owner-wallets).

<Warning>
  **Это не миграция.** Каждый `AmmConfig`, который уже существует, сохраняет любые `protocol_owner` и `fund_owner`, с которыми он был создан. Инструмент сбора, который начнёт жёстко кодировать новые константы, не будет работать на старых конфигурациях, а инструмент, который предполагает «ключ администратора», не будет работать на новых. Читайте поля.
</Warning>

## Whitelist минтов Token-2022 удалён

`is_supported_mint` раньше выполнял короткое замыкание на жёстком `MINT_WHITELIST` из четырёх адресов перед итерацией расширений минта. Этот массив — и `HashSet`, построенный из него при каждом вызове — удалён. Что остаётся:

1. Минты Legacy SPL Token проходят безусловно.
2. Минт с инициализированным PDA `SupportMintAssociated` в `[b"support_mint", mint]` проходит безусловно.
3. В противном случае каждое расширение на минте должно быть одним из `TransferFeeConfig`, `MetadataPointer`, `TokenMetadata`, `InterestBearingConfig`, `ScaledUiAmount`.

PDA реестра находится в программе уже некоторое время, со своей собственной парой `CreateSupportMintAssociated` / `CloseSupportMintAssociated` и своим собственным выделенным органом наряду с общим администратором, и он консультируется как из `Initialize`, так и из `InitializeWithPermission`. Удаление статического массива означает, что подключение минта теперь является чисто on-chain действием, а не обновлением программы — что и является смыслом.

**Существующие пулы не затронуты**, потому что проверка минта выполняется только при создании пула. Что изменяется, так это то, что создание *нового* пула CPMM для одного из четырёх ранее внесённых в whitelist минтов требует, чтобы этот минт имел PDA реестра — те, которые имеют значение, уже есть на mainnet. Полная картина, включая то, что реестр делает и не делает, находится в [`reference/token-2022-support`](/ru/reference/token-2022-support#bypass-paths).

## Расширение подписывающей стороны `ClosePermissionPda`

`CreatePermissionPda` уже принимала либо общего администратора, либо выделенный орган создания permission-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` (клиентский крейт) | `2.3.0`                           | `3.0`                                  |
| `anchor-client` / `-lang` / `-spl` (клиентский крейт)                                    | `0.32.1`                          | `=1.0.2`                               |
| README: `rustup default`                                                                 | `1.81.0`                          | `1.91.0`                               |
| README: Solana installer                                                                 | `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 repo                                                                      | `coral-xyz/anchor`                | `solana-foundation/anchor`             |
| Docker image                                                                             | `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` имеет один параметр lifetime вместо четырёх. На стороне клиента `RequestBuilder::instructions()` возвращает `Vec<Instruction>` вместо `Result<...>`, `CommitmentConfig` поступает из `anchor_client` вместо `solana_sdk`, и `spl-associated-token-account` 8.0 переместил свои помощники адресов под `::address` и свой ID программы в `::program::ID`. См. [`sdk-api/rust-cpi`](/ru/sdk-api/rust-cpi#cargo-dependencies).

Два деталя системы сборки, ни один без on-chain эффекта: крейт программы объявляет функцию `localnet`, которая компилирует локальный кошелёк как `admin` из переменной окружения `CPSWAP_LOCALNET_ADMIN` (так что тесты, ограниченные администратором, могут фактически подписывать — `yarn test:local-admin` подключает это), и дублирующийся блок `[profile.release]` в `programs/cp-swap/Cargo.toml` был удалён. Cargo игнорирует `[profile]` вне корня рабочего пространства, поэтому блок корня уже был тем, который действовал — включая тот факт, что `panic = "abort"` блока уровня программы никогда не применялся.

## Что не изменилось

* **Каждый макет аккаунта.** `PoolState`, `AmmConfig`, `ObservationState`, `Permission`, `SupportMintAssociated` — те же размеры, те же смещения.
* **Коды ошибок `6000`–`6014`.**
* **Сам список разрешённых расширений.** По-прежнему те же пять расширений.
* **Ставки сборов, начисление сборов и кривая.** `CollectExcessLamports` перемещает lamports, которые никогда не были частью резервов какого-либо пула.
* **`spl_memo`.** Ограничение программы 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 реестра, с выделением удаления whitelist; подписывающая сторона `ClosePermissionPda` исправлена.
* `products/cpmm/overview` — предложение whitelist переписано.
* `products/cpmm/code-demos` — скелет Rust CPI обновлён для Anchor 1.0.
* `reference/token-2022-support` — раздел пути обхода переписан вокруг PDA реестра, с перемещённым удалённым `MINT_WHITELIST` в раздел «удалённые пути обхода».
* `reference/error-codes` — задокументирована `6015`.
* `reference/program-addresses` — новые разделы «CPMM support-mint registry authority», «CPMM fee-owner wallets» и «Excess-lamports collection wallets»; примечание `ClosePermissionPda` исправлено.
* `sdk-api/rust-cpi`, `solana-fundamentals/toolchain`, `integration-guides/cpi-integration` — пины Anchor 1.0 и примечания миграции CPI.
* `solana-fundamentals/rent-and-reclaimable-rent` — новый раздел «What the Raydium programs sweep on their own side».
