> ## 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.

# Инструкции CLMM

> Полный справочник инструкций CLMM: жизненный цикл пула, управление позициями, swap и потоки вознаграждений.

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

  [Открыть английскую версию →](/products/clmm/instructions)
</Info>

<Info>
  Эта страница дополняет [`products/clmm/accounts`](/ru/products/clmm/accounts) (описание аккаунтов) и [`products/clmm/math`](/ru/products/clmm/math) (описание математики). Здесь приведены авторитетные сведения об аргументах и порядке аккаунтов; конкретные байтовые раскладки берите из IDL.
</Info>

## Список инструкций

| Группа      | Инструкция                                                       | Примечания                                                                                                                                                                                                                                                                               |
| ----------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Admin       | `CreateAmmConfig`                                                | Создать новый уровень комиссий.                                                                                                                                                                                                                                                          |
| Admin       | `UpdateAmmConfig`                                                | Изменить ставки на существующем уровне.                                                                                                                                                                                                                                                  |
| Admin       | `UpdatePoolStatus`                                               | Приостановить/возобновить операции в пуле.                                                                                                                                                                                                                                               |
| Admin       | `CreateSupportMintAssociated`                                    | Добавить конфигурацию расширения Token-2022 в список допустимых для CLMM-пулов.                                                                                                                                                                                                          |
| Admin       | `CreateOperationAccount`                                         | Инициализировать аккаунт операций на уровне программы (однократно).                                                                                                                                                                                                                      |
| Admin       | `UpdateOperationAccount`                                         | Изменить белый список аккаунта операций.                                                                                                                                                                                                                                                 |
| Admin       | `CreateDynamicFeeConfig`                                         | Создать переиспользуемый набор параметров динамической комиссии с индексом u16.                                                                                                                                                                                                          |
| Admin       | `UpdateDynamicFeeConfig`                                         | Изменить существующий `DynamicFeeConfig`. Пулы, уже снявшие снимок конфига при создании, не затрагиваются.                                                                                                                                                                               |
| Pool        | `CreatePool`                                                     | Инициализировать CLMM-пул, привязанный к `AmmConfig`. Стандартный путь с комиссией FromInput. Сосуществует с `CreateCustomizablePool`.                                                                                                                                                   |
| Pool        | `CreateCustomizablePool`                                         | Рекомендуется для новых пулов. Аналог `CreatePool` с добавлением `collect_fee_on` и флага `enable_dynamic_fee`.                                                                                                                                                                          |
| Position    | `OpenPosition` / `OpenPositionV2` / `OpenPositionWithToken22Nft` | Минтинг NFT позиции. `OpenPositionV2` заменяет V1 (новая раскладка аккаунтов со слотом bitmap-extension); `OpenPositionWithToken22Nft` выпускает NFT позиции как Token-2022 вместо SPL Token. В новом коде следует использовать V2 или вариант Token-2022.                               |
| Position    | `IncreaseLiquidity` / `IncreaseLiquidityV2`                      | Добавить ликвидность в существующую позицию.                                                                                                                                                                                                                                             |
| Position    | `DecreaseLiquidity` / `DecreaseLiquidityV2`                      | Снять ликвидность; собирает накопленные комиссии.                                                                                                                                                                                                                                        |
| Position    | `ClosePosition`                                                  | Сжечь NFT и закрыть `PersonalPositionState`.                                                                                                                                                                                                                                             |
| Position    | `CloseProtocolPosition`                                          | Только для admin: очистка устаревших PDA `ProtocolPositionState`. Текущая программа больше не создаёт и не читает `ProtocolPositionState` — инструкция существует исключительно для возврата ренты с аккаунтов, созданных старыми версиями программы.                                    |
| Swap        | `Swap` / `SwapV2`                                                | Swap с постоянной ликвидностью. Оба варианта поддерживают динамическую комиссию, маршрутизацию комиссий на одну сторону и исполнение лимитных ордеров; единственное отличие — `SwapV2` принимает минты Token-2022 (вариант V1 требует, чтобы оба хранилища были классическим SPL Token). |
| Swap        | `SwapRouterBaseIn`                                               | Многошаговый swap, используется роутером.                                                                                                                                                                                                                                                |
| Limit order | `OpenLimitOrder`                                                 | Разместить ордер на продажу на указанном тике. Неисполненные токены хранятся на тике; движок исполняет их по мере прохождения цены.                                                                                                                                                      |
| Limit order | `IncreaseLimitOrder`                                             | Увеличить существующий открытый ордер.                                                                                                                                                                                                                                                   |
| Limit order | `DecreaseLimitOrder`                                             | Уменьшить или отменить открытый ордер; возвращает неисполненный остаток и уже зачисленный вывод.                                                                                                                                                                                         |
| Limit order | `SettleLimitOrder`                                               | Передать исполненные выходные токены владельцу ордера. Может вызвать владелец или операционный keeper.                                                                                                                                                                                   |
| Limit order | `CloseLimitOrder`                                                | Закрыть полностью исполненный аккаунт ордера. Рента всегда возвращается `owner` ордера. Может вызвать владелец или keeper.                                                                                                                                                               |
| Fees        | `CollectProtocolFee`                                             | Admin-сбор протокольных комиссий.                                                                                                                                                                                                                                                        |
| Fees        | `CollectFundFee`                                                 | Admin-сбор фондовых комиссий.                                                                                                                                                                                                                                                            |
| Rewards     | `InitializeReward`                                               | Подключить новый поток вознаграждений к пулу.                                                                                                                                                                                                                                            |
| Rewards     | `SetRewardParams`                                                | Изменить скорость эмиссии или время окончания вознаграждения.                                                                                                                                                                                                                            |
| Rewards     | `UpdateRewardInfos`                                              | Начислить рост вознаграждений до текущего момента (вызывается любым swap или изменением позиции).                                                                                                                                                                                        |
| Rewards     | `TransferRewardOwner`                                            | Передать права, позволяющие устанавливать поток вознаграждений или пополнять его.                                                                                                                                                                                                        |
| Rewards     | `CollectRemainingRewards`                                        | После наступления `end_time` потока вознаграждений вернуть нераспределённые токены фандеру.                                                                                                                                                                                              |
| Utility     | `InitTickArray`                                                  | Инициализировать аккаунт массива тиков (обычно объединяется с `OpenPosition`).                                                                                                                                                                                                           |

Большинство инструкций только для admin (`CreateAmmConfig`, `UpdateAmmConfig`, `UpdatePoolStatus`, `CreateSupportMintAssociated`, `CreateOperationAccount`, `UpdateOperationAccount`, `CloseProtocolPosition`) защищены захардкоженным pubkey `admin` программы. Инструкции admin потока вознаграждений (`TransferRewardOwner`, `CollectRemainingRewards`) защищены фандером вознаграждения, а не admin программы.

Суффикс V2 означает «поддержка Token-2022 на хранилищах/NFT, требуется слот bitmap-extension». SDK по умолчанию использует V2 для новых пулов.

## `CreatePool`

**Аргументы**

```
sqrt_price_x64: u128           // начальная цена
open_time:      u64            // swap-операции отклоняются до этого времени
```

**Аккаунты (сокращённо)**

| #  | Название                      | W | S | Примечания                                    |
| -- | ----------------------------- | - | - | --------------------------------------------- |
| 1  | `pool_creator`                | W | S |                                               |
| 2  | `amm_config`                  |   |   | Выбранный уровень комиссий.                   |
| 3  | `pool_state`                  | W |   | `init` здесь.                                 |
| 4  | `token_mint_0`                |   |   | Отсортировано.                                |
| 5  | `token_mint_1`                |   |   |                                               |
| 6  | `token_vault_0`               | W |   | `init` здесь, принадлежит PDA authority пула. |
| 7  | `token_vault_1`               | W |   |                                               |
| 8  | `observation_state`           | W |   | `init` здесь.                                 |
| 9  | `tick_array_bitmap_extension` | W |   | `init` здесь (V2).                            |
| 10 | `token_program`               |   |   |                                               |
| 11 | `token_program_2022`          |   |   |                                               |
| 12 | `system_program`, `rent`      |   |   |                                               |

**Предусловия**

* `token_mint_0 < token_mint_1` по порядку байт.
* `amm_config.disable_create_pool == false`.
* Минты не отклонены белым списком расширений Token-2022.

**Постусловия**

* `pool_state.sqrt_price_x64 = sqrt_price_x64`, `tick_current = floor(log_{1.0001}(price))`.
* `pool_state.liquidity = 0` (позиций ещё нет).
* `pool_state.fee_on = FromInput` (устаревшее значение по умолчанию).
* `pool_state.dynamic_fee_info` обнулён (динамическая комиссия отключена).

## `CreateCustomizablePool`

Рекомендуется для новых пулов. Работает так же, как `CreatePool`, добавляя режим сбора комиссий на уровне пула и опциональное включение динамической комиссии.

**Аргументы**

```rust theme={null}
pub struct CreateCustomizableParams {
    pub sqrt_price_x64:    u128,
    pub collect_fee_on:    CollectFeeOn,   // FromInput | Token0Only | Token1Only
    pub enable_dynamic_fee: bool,
}
```

**Аккаунты (сокращённо)** — те же, что у `CreatePool`, плюс при `enable_dynamic_fee = true`:

| # | Название             | W | S | Примечания                                               |
| - | -------------------- | - | - | -------------------------------------------------------- |
| N | `dynamic_fee_config` |   |   | Общий конфиг для снятия снимка. Должен уже существовать. |

**Предусловия** — те же, что у `CreatePool`. Если `enable_dynamic_fee = false`, `dynamic_fee_config` игнорируется.

**Постусловия**

* `pool_state.fee_on` устанавливается в выбранный вариант `CollectFeeOn`.
* Если динамическая комиссия включена: `pool_state.dynamic_fee_info` инициализируется из переданного `DynamicFeeConfig` (копируются пять калибровочных параметров; поля состояния обнуляются).
* В противном случае: `pool_state.dynamic_fee_info` обнулён (динамическая комиссия навсегда неактивна для этого пула).

`fee_on` и бит включения динамической комиссии устанавливаются **только** при создании пула. Обновление на месте невозможно — пулы, созданные через устаревший `CreatePool`, не могут получить динамическую комиссию или одностороннюю комиссию задним числом. Для новых развёртываний следует использовать эту инструкцию.

## `OpenPositionV2` / `OpenPositionWithToken22Nft`

Создать новую позицию в существующем пуле.

**Аргументы**

```
tick_lower_index: i32
tick_upper_index: i32
tick_array_lower_start_index: i32
tick_array_upper_start_index: i32
liquidity:  u128              // желаемое L (или 0 — использовать суммы ниже)
amount_0_max: u64
amount_1_max: u64
with_metadata: bool           // записать метаданные NFT (Metaplex)
base_flag: Option<bool>       // true = подогнать под amount0; false = подогнать под amount1
```

**Аккаунты (сокращённо)**

| #  | Название                                  | W | S           |                                               |
| -- | ----------------------------------------- | - | ----------- | --------------------------------------------- |
| 1  | `payer`                                   | W | S           |                                               |
| 2  | `position_nft_owner`                      |   |             |                                               |
| 3  | `position_nft_mint`                       | W | S (keypair) |                                               |
| 4  | `position_nft_account`                    | W |             | ATA владельца для NFT.                        |
| 5  | `metadata_account`                        | W |             | Metaplex (опционально, если `with_metadata`). |
| 6  | `pool_state`                              | W |             |                                               |
| 7  | `protocol_position`                       |   |             |                                               |
| 8  | `tick_array_lower`                        | W |             | Создаётся, если не инициализирован.           |
| 9  | `tick_array_upper`                        | W |             | Аналогично.                                   |
| 10 | `personal_position`                       | W |             | Создаётся здесь.                              |
| 11 | `token_account_0`, `token_account_1`      | W |             | Исходные ATA пользователя.                    |
| 12 | `token_vault_0`, `token_vault_1`          | W |             |                                               |
| 13 | `rent`, `system_program`, `token_program` |   |             |                                               |
| 14 | `associated_token_program`                |   |             |                                               |
| 15 | `metadata_program`                        |   |             | Опционально.                                  |
| 16 | `token_program_2022`                      |   |             | V2.                                           |
| 17 | `vault_0_mint`, `vault_1_mint`            |   |             | V2.                                           |
| 18 | `tick_array_bitmap_extension`             | W |             | V2 (если затрагивается).                      |

**Математика** — см. [`products/clmm/math`](/ru/products/clmm/math). По значению `base_flag` программа приводит либо `liquidity`, либо `(amount_0_max, amount_1_max)` к фактическому `L` и фактически потреблённым суммам токенов.

**Предусловия**

* `tick_lower < tick_upper`, оба кратны `pool.tick_spacing`, в диапазоне `[MIN_TICK, MAX_TICK]`.
* Требуемые массивы тиков переданы и инициализированы (или созданы здесь через CPI `InitTickArray` в транзакции).
* У пользователя не менее `amount_0_max` и `amount_1_max` в исходных ATA.

**Постусловия**

* `personal_position` существует, `liquidity` установлено, `fee_growth_inside_last` зафиксировано.
* Записи массива тиков на `tick_lower` и `tick_upper` обновлены (`liquidity_gross += L`, `liquidity_net ± L`, снимки роста комиссий сохранены).
* `pool_state.liquidity += L`, если позиция в диапазоне (`tick_lower ≤ tick_current < tick_upper`).

**Частые ошибки** — `InvalidTickIndex`, `NotApproved`, `ZeroAmountSpecified`, `TransactionTooLarge` (при слишком большом количестве массивов тиков).

## `IncreaseLiquidityV2`

Добавить ликвидность в уже открытую позицию.

**Аргументы**

```
liquidity: u128
amount_0_max: u64
amount_1_max: u64
base_flag: Option<bool>
```

**Аккаунты** — как у `OpenPosition`, за исключением минта NFT (позиция уже существует; NFT передаётся как ATA владельца, содержащая 1 токен).

**Эффект**

* Переводит `amount_0_actual` / `amount_1_actual` от пользователя в хранилища.
* Увеличивает `personal_position.liquidity` и `pool_state.liquidity` (если в диапазоне), а также `liquidity_gross` / `liquidity_net` граничных тиков.
* **Собирает комиссии и вознаграждения, накопленные с последнего обращения**, и зачисляет их в `tokens_fees_owed_{0,1}` / `reward_amount_owed`. Выплата происходит только при вызове `DecreaseLiquidity` или `CollectReward`, но не при увеличении позиции.

## `DecreaseLiquidityV2`

Снять ликвидность из позиции.

**Аргументы**

```
liquidity: u128
amount_0_min: u64
amount_1_min: u64
```

**Аккаунты** — такая же структура, как у `IncreaseLiquidity`.

**Эффект**

* Вычисляет `(amount_0, amount_1)` для удалённого `L` при текущем `sqrt_price_x64`.
* Начисляет комиссии и вознаграждения, накопленные с последнего обращения, — аналогично `IncreaseLiquidity`.
* Переводит `amount_0 + fees_owed_0` и `amount_1 + fees_owed_1` из хранилищ пользователю.
* Уменьшает счётчики ликвидности; если новое `personal_position.liquidity == 0`, позицию можно закрыть через `ClosePosition`.

**Slippage** — `amount_0_min` и `amount_1_min` — минимумы, которые пользователь принимает с учётом комиссий за перевод Token-2022 на стороне вывода.

## `ClosePosition`

Сжечь NFT позиции и закрыть `PersonalPositionState`.

**Предусловия**

* `personal_position.liquidity == 0`.
* `tokens_fees_owed_{0,1} == 0`.
* Все счётчики вознаграждений `reward_amount_owed == 0`.

(То есть сначала необходимо всё собрать и уменьшить позицию до нуля.)

**Эффект**

* Сжигает NFT.
* Закрывает аккаунт минта NFT и аккаунт `personal_position`, возвращая ренту `payer`.

## `SwapV2`

Обход кривой ликвидности; точный ввод *или* точный вывод в зависимости от `is_base_input`.

**Аргументы**

```
amount: u64                  // ввод при is_base_input=true, вывод иначе
other_amount_threshold: u64  // минимум вывода или максимум ввода
sqrt_price_limit_x64: u128   // жёсткая граница; 0 ⇒ без ограничений
is_base_input: bool
```

**Аккаунты (сокращённо)**

| #   | Название                                    | W | S | Примечания                                                              |
| --- | ------------------------------------------- | - | - | ----------------------------------------------------------------------- |
| 1   | `payer`                                     |   | S |                                                                         |
| 2   | `amm_config`                                |   |   |                                                                         |
| 3   | `pool_state`                                | W |   |                                                                         |
| 4   | `input_token_account`                       | W |   |                                                                         |
| 5   | `output_token_account`                      | W |   |                                                                         |
| 6   | `input_vault`                               | W |   |                                                                         |
| 7   | `output_vault`                              | W |   |                                                                         |
| 8   | `observation_state`                         | W |   |                                                                         |
| 9   | `token_program`                             |   |   |                                                                         |
| 10  | `token_program_2022`                        |   |   | V2.                                                                     |
| 11  | `memo_program`                              |   |   | V2 (требуется для некоторых путей Token-2022).                          |
| 12  | `input_vault_mint`, `output_vault_mint`     |   |   | V2.                                                                     |
| 13  | `tick_array_bitmap_extension` (опционально) | W |   | Если swap уходит в расширение.                                          |
| 14+ | `tick_array` (remaining)                    | W |   | Достаточное количество массивов для охвата ожидаемого диапазона обхода. |

Вызывающий передаёт ранжированный список массивов тиков, охватывающих ожидаемый обход swap; программа использует столько, сколько нужно. SDK вычисляет этот список через `PoolUtils.computeAmountOutFormat` или конечную точку котировок API.

**Предусловия**

* `pool_state.status` разрешает swap.
* `now >= open_time`.
* `sqrt_price_limit_x64` находится на корректной стороне от `sqrt_price_x64` для выбранного направления.

**Частые ошибки** — `ExceededSlippage`, `SqrtPriceLimitOverflow`, `TickArrayNotFound`, `LiquidityInsufficient`.

**Что `SwapV2` делает внутри и что важно знать вызывающему** (релиз после 2025 года):

1. **Надбавка динамической комиссии** — если `pool.dynamic_fee_info` ненулевой, программа обновляет аккумулятор волатильности, используя расстояние по тикам, пройденное с момента последнего swap (с правилами фильтра/затухания из [`products/clmm/fees`](/ru/products/clmm/fees)), и добавляет `dynamic_fee_component` поверх `AmmConfig.trade_fee_rate`. Суммарная комиссия ограничена 10% (`MAX_FEE_RATE_NUMERATOR / 1_000_000`).
2. **Исполнение лимитных ордеров** — когда обход цены пересекает тик с открытыми лимитными ордерами, программа сначала исполняет доступную ликвидность лимитных ордеров на этом тике (FIFO по `order_phase`), затем продолжает по кривой ликвидности LP. Исполненные суммы обновляют `tick.unfilled_ratio_x64` и `tick.part_filled_orders_remaining` для последующего расчёта; сами ордера остаются незавершёнными до тех пор, пока владелец не вызовет `SettleLimitOrder`.
3. **Маршрутизация комиссий на одну сторону** — при `pool.fee_on = Token0Only` или `Token1Only` шаг swap по-прежнему вычисляет то же соотношение ввода и вывода; комиссия затем направляется на настроенную сторону. Для направлений, где настроенная сторона комиссии является выводом, комиссия вычитается из вывода swap (пользователь получает `out − fee`); для направлений, где это ввод, поведение совпадает с `FromInput`. См. `is_fee_on_input(zero_for_one)` и `is_fee_on_token0(zero_for_one)` на `PoolState`.

`Swap` (V1) реализует те же динамическую комиссию, маршрутизацию комиссий на одну сторону и исполнение лимитных ордеров, что и `SwapV2`; единственная недостающая возможность — поддержка Token-2022: оба хранилища должны быть классическим SPL Token. Пулы с любым минтом Token-2022 должны использовать `SwapV2` для swap-операций. Агрегатор и SDK уже предпочитают V2 для каждого плеча CLMM, поэтому вызывающим не нужно ветвиться по типу минта.

## `OpenLimitOrder`

Разместить ордер на продажу на конкретном тике. Ордер находится в FIFO-когорте на тике и исполняется по мере прохождения цены.

**Аргументы**

```
nonce_index:    u8       // выбранный пользователем индекс nonce-аккаунта (0..255 на кошелёк)
zero_for_one:   bool     // true: продать token0 за token1; false: продать token1 за token0
tick_index:     i32      // должен быть кратен pool.tick_spacing
amount:         u64      // количество входного токена
```

**Аккаунты (сокращённо)**

| #  | Название                 | W | S | Примечания                                                                             |
| -- | ------------------------ | - | - | -------------------------------------------------------------------------------------- |
| 1  | `payer`                  | W | S | Владелец ордера; платит ренту.                                                         |
| 2  | `pool_state`             | W |   |                                                                                        |
| 3  | `tick_array`             | W |   | Массив тиков, содержащий `tick_index`.                                                 |
| 4  | `limit_order_nonce`      | W |   | PDA. `init_if_needed` — создаётся при первом ордере пользователя с этим `nonce_index`. |
| 5  | `limit_order`            | W |   | PDA. `init` здесь.                                                                     |
| 6  | `input_token_account`    | W |   | ATA входного токена пользователя.                                                      |
| 7  | `input_vault`            | W |   | Хранилище входного токена пула.                                                        |
| 8  | `input_vault_mint`       |   |   | Обработка комиссий Token-2022.                                                         |
| 9  | `input_token_program`    |   |   | SPL или Token-2022.                                                                    |
| 10 | `system_program`, `rent` |   |   |                                                                                        |

**Предусловия**

* `tick_index % pool.tick_spacing == 0` и в диапазоне `[MIN_TICK, MAX_TICK]`.
* `tick_index` находится **на правильной стороне от `pool.tick_current`** для выбранного направления (продажа token0 → тик должен быть выше текущего, и наоборот). Продажа на уже пройденном тике будет немедленно исполнена и отклонена.
* `pool_state.status` разрешает операцию с лимитным ордером (бит 5).

**Постусловия**

* `limit_order` существует, зафиксированы `tick.order_phase` и `tick.unfilled_ratio_x64` на момент открытия.
* `tick.orders_amount += amount` (в текущей когорте).
* `limit_order_nonce.order_nonce += 1`.
* Эмитировано `OpenLimitOrderEvent`.

**Частые ошибки** — `InvalidLimitOrderAmount` (ноль или ниже минимума пула), `InvalidTickIndex` (за пределами `[MIN_TICK, MAX_TICK]` или не на той стороне от `tick_current` для выбранного направления), `TickAndSpacingNotMatch` (`tick_index % pool.tick_spacing != 0`), `OrderPhaseSaturated`.

## `IncreaseLimitOrder`

Увеличить существующий открытый ордер. Может вызвать только `owner` ордера.

**Аргументы**

```
amount: u64    // дополнительное количество входного токена
```

**Аккаунты** — как у `OpenLimitOrder`, без nonce-аккаунта; PDA `limit_order` передаётся напрямую.

**Предусловия**

* `limit_order.owner == signer`.
* Ордер всё ещё находится в той же когорте (`tick.order_phase == limit_order.order_phase`). Если когорта уже начала исполняться, ордер частично завершён — вызывающему следует сначала вызвать `DecreaseLimitOrder` или `SettleLimitOrder` для продвижения вперёд.

**Эффект**

* Переводит `amount` из ATA владельца в `input_vault`.
* `limit_order.total_amount += amount`; `tick.orders_amount += amount`.

## `DecreaseLimitOrder`

Уменьшить или полностью отменить открытый ордер. Возвращает владельцу неисполненный остаток плюс любой вывод, уже зачисленный предыдущими частичными исполнениями.

**Аргументы**

```
amount:     u64    // количество входного токена для вывода (максимум = неисполненный остаток)
amount_min: u64    // нижняя граница slippage для вывода входной стороны
```

**Аккаунты** — обе стороны: входной и выходной токены:

| #  | Название                                | W | S |
| -- | --------------------------------------- | - | - |
| 1  | `owner`                                 |   | S |
| 2  | `pool_state`                            | W |   |
| 3  | `tick_array`                            | W |   |
| 4  | `limit_order`                           | W |   |
| 5  | `input_token_account`                   | W |   |
| 6  | `output_token_account`                  | W |   |
| 7  | `input_vault`                           | W |   |
| 8  | `output_vault`                          | W |   |
| 9  | `input_vault_mint`, `output_vault_mint` |   |   |
| 10 | `token_program`, `token_program_2022`   |   |   |

**Эффект**

* Пересчитывает исполненную сумму ордера по `unfilled_ratio_x64` когорты с момента открытия.
* Отправляет исполненный вывод на `output_token_account`.
* Возвращает `amount` неисполненного ввода на `input_token_account`.
* Соответственно обновляет `limit_order`. Если новый неисполненный остаток равен нулю, программа закрывает аккаунт и возвращает ренту `owner`.

## `SettleLimitOrder`

Передать исполненные выходные токены владельцу, не изменяя неисполненный остаток ордера. Полезно, когда keeper-ы с `auto_withdraw` хотят постепенно выплачивать долгосрочные частичные исполнения.

**Вызывающий** — либо `owner` ордера, либо `limit_order_admin` программы (офчейновый операционный горячий кошелёк, выполняющий автоматический keeper-цикл). У keeper-а нет других полномочий — он не может перемещать средства пользователей за пределами передачи исполненного вывода на ATA `owner` ордера.

**Аккаунты**

| # | Название               | W | S |                                 |
| - | ---------------------- | - | - | ------------------------------- |
| 1 | `signer`               |   | S | owner *или* `limit_order_admin` |
| 2 | `pool_state`           |   |   |                                 |
| 3 | `tick_array`           |   |   |                                 |
| 4 | `limit_order`          | W |   |                                 |
| 5 | `output_token_account` | W |   | ATA вывода владельца.           |
| 6 | `output_vault`         | W |   | Хранилище вывода пула.          |
| 7 | `output_vault_mint`    |   |   |                                 |
| 8 | `output_token_program` |   |   |                                 |

**Эффект**

* Вычисляет накопленный вывод по `(limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64)`.
* Переводит дельту на `output_token_account`.
* Обновляет `limit_order.settled_output`.
* **Не закрывает** ордер; он остаётся открытым против любого оставшегося ввода.

## `CloseLimitOrder`

Закрыть полностью исполненный аккаунт ордера. Рента всегда возвращается `limit_order.owner` независимо от того, кто подписывает.

**Вызывающий** — либо `owner`, либо `limit_order_admin`.

**Предусловия**

* Неисполненный остаток ордера равен нулю (либо `amount == total_amount` было исполнено и рассчитано, либо владелец ранее уменьшил ордер до нуля и забыл закрыть).

**Эффект**

* Закрывает `limit_order`; рента отправляется `limit_order.owner`.

## `CreateDynamicFeeConfig` (admin)

Создать переиспользуемый набор параметров с индексом u16.

**Аргументы**

```
index:                       u16
filter_period:               u16   // секунды; например 30
decay_period:                u16   // секунды; например 600. Должен быть > filter_period
reduction_factor:            u16   // 1..10_000; например 5_000 = удержание 50% за окно затухания
dynamic_fee_control:         u32   // 1..100_000; усиление на кривой волатильность→комиссия
max_volatility_accumulator:  u32   // верхняя граница
```

**Аккаунты**

| # | Название             | W | S | Примечания                   |
| - | -------------------- | - | - | ---------------------------- |
| 1 | `owner`              | W | S | Захардкоженный pubkey admin. |
| 2 | `dynamic_fee_config` | W |   | PDA, `init` здесь.           |
| 3 | `system_program`     |   |   |                              |

**Частые ошибки** — `InvalidDynamicFeeConfigParams`, если `decay_period <= filter_period` или любое поле с нулевым значением выходит за допустимые пределы.

## `UpdateDynamicFeeConfig` (admin)

Изменить существующий `DynamicFeeConfig`. Пулы, уже снявшие снимок конфига при создании, **не обновляются** задним числом; новые значения подхватят только пулы, созданные после этого изменения и ссылающиеся на данный конфиг.

**Аргументы** — те же пять калибровочных полей, что у `CreateDynamicFeeConfig` (`filter_period`, `decay_period`, `reduction_factor`, `dynamic_fee_control`, `max_volatility_accumulator`); `index` фиксируется при создании и здесь не передаётся повторно.

## `CollectProtocolFee` / `CollectFundFee`

Идентичны по форме аналогичным инструкциям CPMM. Подписант должен совпадать с `AmmConfig.owner` / `AmmConfig.fund_owner`. Очищает накопленные протокольные/фондовые комиссии из хранилищ пула в адрес получателя, обнуляя соответствующие поля `PoolState.protocol_fees_*` / `fund_fees_*`.

## `InitializeReward`

Подключить новый поток вознаграждений к пулу. Одновременно может быть активно не более 3 потоков.

**Аргументы**

```
open_time:     u64
end_time:      u64
emissions_per_second_x64: u128   // Q64.64
```

**Аккаунты**

| # | Название                 | W | S |                                                            |
| - | ------------------------ | - | - | ---------------------------------------------------------- |
| 1 | `reward_funder`          | W | S |                                                            |
| 2 | `funder_token_account`   | W |   |                                                            |
| 3 | `amm_config`             |   |   |                                                            |
| 4 | `pool_state`             | W |   |                                                            |
| 5 | `operation_state`        |   |   | PDA операций CLMM, контролирующий создание вознаграждений. |
| 6 | `reward_token_mint`      |   |   |                                                            |
| 7 | `reward_token_vault`     | W |   | `init` здесь.                                              |
| 8 | `reward_token_program`   |   |   |                                                            |
| 9 | `system_program`, `rent` |   |   |                                                            |

**Предусловия**

* На пуле активно менее 3 потоков.
* Фандер вносит `total_emission = emissions_per_second × (end_time − open_time)` токенов вознаграждения в хранилище в рамках этой инструкции.
* Минт вознаграждения входит в белый список `operation_state`.

## `SetRewardParams`

Продлить, пополнить или изменить скорость эмиссии существующего потока вознаграждений. Обычно вызывается создателем пула или мультисигом Raydium. Ограничения хранятся ончейн: как правило, можно увеличить `end_time` или эмиссию, но нельзя уменьшить их задним числом. Проверьте список владельцев `operation_state`.

## `UpdateRewardInfos`

Чисто бухгалтерская операция — начисляет `reward_growth_global_x64` до текущего момента путём умножения `emissions_per_second × Δt / liquidity`. Вызывается внутри каждой инструкции, затрагивающей ликвидность. Доступна как самостоятельная инструкция, поскольку внешние участники (UI, кранки) иногда хотят запустить её явно.

## `CollectReward`

Владелец позиции забирает накопленные токены вознаграждения.

**Аккаунты**

| # | Название                  | W | S |                              |
| - | ------------------------- | - | - | ---------------------------- |
| 1 | `nft_owner`               |   | S |                              |
| 2 | `nft_account`             |   |   | ATA владельца с NFT позиции. |
| 3 | `personal_position`       | W |   |                              |
| 4 | `pool_state`              | W |   |                              |
| 5 | `protocol_position`       |   |   |                              |
| 6 | `reward_token_vault`      | W |   |                              |
| 7 | `recipient_token_account` | W |   |                              |
| 8 | `token_program`           |   |   |                              |
| 9 | `token_program_2022`      |   |   |                              |

**Эффект**

* Начисляет рост вознаграждений (по той же схеме, что и комиссии).
* Переводит причитающуюся сумму на ATA получателя, обнуляет `reward_amount_owed[i]`.

## Матрица изменения состояния

| Инструкция               | `pool.liquidity`   | `pool.fee_growth_global` | `pool.reward_growth_global` | `personal_position.liquidity` | Массив тиков                                                       |
| ------------------------ | ------------------ | ------------------------ | --------------------------- | ----------------------------- | ------------------------------------------------------------------ |
| `CreatePool`             | 0                  | 0                        | —                           | —                             | —                                                                  |
| `OpenPosition`           | + если в диапазоне | —                        | —                           | новая                         | добавить liquidity\_gross/net                                      |
| `IncreaseLiquidity`      | + если в диапазоне | начислить                | начислить                   | +                             | скорректировать                                                    |
| `DecreaseLiquidity`      | − если в диапазоне | начислить                | начислить                   | −                             | скорректировать                                                    |
| `ClosePosition`          | —                  | —                        | —                           | уничтожена                    | —                                                                  |
| `SwapV2`                 | ± при пересечениях | +                        | —                           | —                             | пересечь и перевернуть outside; исполнить когорты лимитных ордеров |
| `OpenLimitOrder`         | —                  | —                        | —                           | —                             | `orders_amount += amount` на целевом тике                          |
| `IncreaseLimitOrder`     | —                  | —                        | —                           | —                             | `orders_amount += amount`                                          |
| `DecreaseLimitOrder`     | —                  | —                        | —                           | —                             | `orders_amount -=`, может закрыть когорту                          |
| `SettleLimitOrder`       | —                  | —                        | —                           | —                             | — (тик только для чтения)                                          |
| `CloseLimitOrder`        | —                  | —                        | —                           | —                             | —                                                                  |
| `CreateCustomizablePool` | 0                  | 0                        | —                           | —                             | —                                                                  |
| `UpdateRewardInfos`      | —                  | —                        | +                           | —                             | —                                                                  |
| `CollectReward`          | —                  | —                        | начислить                   | —                             | —                                                                  |

## Что дальше

* [`products/clmm/code-demos`](/ru/products/clmm/code-demos) — запускаемые примеры на TypeScript.
* [`products/clmm/fees`](/ru/products/clmm/fees) — подробности о начислении комиссий и вознаграждений.
* [`reference/error-codes`](/ru/reference/error-codes) — полная таблица Anchor-ошибок CLMM.

Источники:

* [`raydium-io/raydium-clmm` — `programs/amm/src/instructions`](https://github.com/raydium-io/raydium-clmm)
* Raydium SDK v2 — `@raydium-io/raydium-sdk-v2`
