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

# CPMM 指令

> CPMM 程序上的每条指令，包括其参数、账户列表、前置和后置条件以及可能返回的错误。

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

  [查看英文版 →](/products/cpmm/instructions)
</Info>

## 指令概览

| 判别器名称                      | 谁签署                              | 功能说明                                                                                                                                                                                                                                                                                                       |
| -------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Initialize`               | 池创建者                             | 从两个代币和一个 `AmmConfig` 创建新的 CPMM 池。无需权限；任何人都可以调用。在新池上硬编码 `enable_creator_fee = false`。`pool_state` 账户可以是标准 PDA 或新的随机密钥对（见 Initialize 账户部分）。                                                                                                                                                                  |
| `InitializeWithPermission` | 付款人 + `Permission` PDA 持有者       | `Initialize` 的有权限变体。调用者（付款人）必须拥有从其自身公钥派生的 `Permission` PDA。用于需要门控池创建的平台（例如 LaunchLab 毕业）。允许调用者指定 `creator_fee_on`（`BothToken` / `OnlyToken0` / `OnlyToken1`）并强制在新池上设置 `enable_creator_fee = true`。`pool_state` 上的 `creator` 字段设置为单独传入的 `creator` 账户，而非付款人。`pool_state` 的标准 PDA 或随机密钥对灵活性与 `Initialize` 相同。 |
| `Deposit`                  | LP                               | 在两种代币中添加流动性；接收 LP 代币。                                                                                                                                                                                                                                                                                      |
| `Withdraw`                 | LP                               | 销毁 LP 代币；按比例接收两种底层代币。                                                                                                                                                                                                                                                                                      |
| `SwapBaseInput`            | 交换者                              | 精确输入交换（`amount_in` 输入，≥ `minimum_amount_out` 输出）。                                                                                                                                                                                                                                                          |
| `SwapBaseOutput`           | 交换者                              | 精确输出交换（≤ `maximum_amount_in` 输入，`amount_out` 输出）。                                                                                                                                                                                                                                                          |
| `CollectProtocolFee`       | `protocol_owner`（来自 `AmmConfig`） | 从金库扫除累积的协议费用。                                                                                                                                                                                                                                                                                              |
| `CollectFundFee`           | `fund_owner`（来自 `AmmConfig`）     | 从金库扫除累积的基金费用。                                                                                                                                                                                                                                                                                              |
| `CollectCreatorFee`        | `pool_creator`                   | 扫除累积的创建者费用（如果已启用创建者费用）。                                                                                                                                                                                                                                                                                    |
| `UpdatePoolStatus`         | `admin`                          | 通过位掩码暂停/恢复池上的特定操作。                                                                                                                                                                                                                                                                                         |
| `UpdateAmmConfig`          | `admin`                          | 更改费率或 `AmmConfig` 上的协议/基金所有者。                                                                                                                                                                                                                                                                              |
| `CreateAmmConfig`          | `admin`                          | 创建新的费用级别（新 `AmmConfig` 账户）。                                                                                                                                                                                                                                                                                |
| `CreatePermissionPda`      | `admin`                          | 铸造允许特定权限调用 `InitializeWithPermission` 的 `Permission` PDA。                                                                                                                                                                                                                                                  |
| `ClosePermissionPda`       | `admin`                          | 撤销之前颁发的 `Permission` PDA。                                                                                                                                                                                                                                                                                  |

状态位掩码：每个池的 `status` 是一个 `u8`，其中位 0 = 禁用存入，位 1 = 禁用提取，位 2 = 禁用交换（程序中为 `PoolStatusBitIndex { Deposit, Withdraw, Swap }`）。清零位表示允许操作；置位表示已暂停。`UpdatePoolStatus` 接收原始 `u8` 并覆盖现有值。

接下来的章节逐一详细说明。账户顺序遵循 CPMM IDL；SDK 和 `raydium-cp-swap/programs/cp-swap/src/instructions` 中的 Rust 客户端与此顺序一致。

## `Initialize`

创建新的 CPMM 池。

**参数**

```
init_amount_0: u64
init_amount_1: u64
open_time:     u64   // Unix 时间戳；此时间前的交换被拒绝
```

**账户**（W = 可写，S = 签署者）

| #  | 名称                         | W | S   | 说明                                                                                                                                                                                                                                                                            |
| -- | -------------------------- | - | --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1  | `creator`                  | W | S   | 支付租金；记录为 `pool_state.pool_creator`。                                                                                                                                                                                                                                           |
| 2  | `amm_config`               |   |     | 选择的费用级别。                                                                                                                                                                                                                                                                      |
| 3  | `authority`                |   |     | CPMM 全局权限 PDA。                                                                                                                                                                                                                                                                |
| 4  | `pool_state`               | W | S\* | 在此处初始化。**要么**是标准 PDA `["pool", amm_config, token_0_mint, token_1_mint]`，**要么**是新的随机密钥对——当不是标准 PDA 时，程序要求 `pool_state` 签署（`require_eq!(pool_account_info.is_signer, true)`）。随机密钥对路径让创建者规避对标准 PDA 的抢先交易尝试。下游 PDA（`lp_mint`、金库、`observation_state`）从 `pool_state.key()` 派生，无论如何。 |
| 5  | `token_0_mint`             |   |     | 已排序：`token_0_mint < token_1_mint`。                                                                                                                                                                                                                                            |
| 6  | `token_1_mint`             |   |     |                                                                                                                                                                                                                                                                               |
| 7  | `lp_mint`                  | W |     | 在此处初始化。权限设置为 `authority`。                                                                                                                                                                                                                                                     |
| 8  | `creator_token_0`          | W |     | `init_amount_0` 的源 ATA。                                                                                                                                                                                                                                                       |
| 9  | `creator_token_1`          | W |     | `init_amount_1` 的源 ATA。                                                                                                                                                                                                                                                       |
| 10 | `creator_lp_token`         | W |     | LP 的目的地（如果缺失则创建）。                                                                                                                                                                                                                                                             |
| 11 | `token_0_vault`            | W |     | 在此处初始化。由 `authority` 拥有。                                                                                                                                                                                                                                                      |
| 12 | `token_1_vault`            | W |     |                                                                                                                                                                                                                                                                               |
| 13 | `create_pool_fee`          | W |     | 创建者支付的 `create_pool_fee` 的目标 ATA。                                                                                                                                                                                                                                             |
| 14 | `observation_state`        | W |     | 在此处初始化。                                                                                                                                                                                                                                                                       |
| 15 | `token_program`            |   |     | SPL Token（用于 LP 铸造）。                                                                                                                                                                                                                                                          |
| 16 | `token_0_program`          |   |     | SPL Token 或 Token-2022。                                                                                                                                                                                                                                                       |
| 17 | `token_1_program`          |   |     | SPL Token 或 Token-2022。                                                                                                                                                                                                                                                       |
| 18 | `associated_token_program` |   |     |                                                                                                                                                                                                                                                                               |
| 19 | `system_program`           |   |     |                                                                                                                                                                                                                                                                               |
| 20 | `rent`                     |   |     |                                                                                                                                                                                                                                                                               |

`*` `pool_state` 仅在随机密钥对路径上签署；标准 PDA 路径无需 `pool_state` 签署即可运行。

**前置条件**

* 代币已排序（按字节顺序 `token_0_mint < token_1_mint`）。
* 两个代币都不使用 CPMM 允许列表之外的扩展（`TransferFeeConfig`、`MetadataPointer`、`TokenMetadata`、`InterestBearingConfig`、`ScaledUiAmount`）——见[`products/cpmm/accounts`](/zh/products/cpmm/accounts#vaults-and-token-2022)。程序内的小型每代币允许列表绕过检查以用于逐个案例的集成。
* `creator` 在各自 ATA 中至少拥有 `init_amount_0` 和 `init_amount_1`。
* `amm_config.disable_create_pool == false`。

**后置条件**

* `pool_state` 存在，`lp_supply = sqrt(init_amount_0 * init_amount_1) − LOCKED_LP`。
* LP 的初始锁定部分 `LOCKED_LP`（100 个 LP 代币的 lamports）永久锁定在池中——`pool_state.lp_supply` 记录 `liquidity − 100`，而 100 个 LP 单位保持在流通外，防止池被完全耗尽和被零除。
* `observation_state` 已初始化；`observation_index = 0` 和 `pool_id = pool_state.key()`。
* `create_pool_fee` lamports 从创建者转移到接收者并同步为原生 SOL（它是一个 wSOL ATA）。
* 池的状态位掩码是 `0`（存入/提取/交换全部启用）。
* `enable_creator_fee = false` 和 `creator_fee_on = BothToken`。`Initialize` **不**支持启用创建者费用——该路径是 `InitializeWithPermission`。
* 如果调用者传入的值 `<= block_timestamp`，`open_time` 会被提升到 `block_timestamp + 1`。交换在 `open_time` 前被拒绝；存入和提取立即工作。

**常见错误**（完整列表见[`reference/error-codes`](/zh/reference/error-codes)）

* `InvalidInput` — 代币未排序或代币相同。
* `NotSupportMint` — 被阻止的 Token-2022 扩展。
* `ExceededSlippage` — 很少发生；如果 `init_amount_0/1` 由于小数位数不匹配导致零 LP。

## `Deposit`

按池的比例在两种代币中添加流动性。

**参数**

```
lp_token_amount:   u64   // 要铸造给 LP 的 LP 代币数量
maximum_token_0:   u64
maximum_token_1:   u64
```

**账户**

| #  | 名称                   | W | S |
| -- | -------------------- | - | - |
| 1  | `owner`              |   | S |
| 2  | `authority`          |   |   |
| 3  | `pool_state`         | W |   |
| 4  | `owner_lp_token`     | W |   |
| 5  | `token_0_account`    | W |   |
| 6  | `token_1_account`    | W |   |
| 7  | `token_0_vault`      | W |   |
| 8  | `token_1_vault`      | W |   |
| 9  | `token_program`      |   |   |
| 10 | `token_program_2022` |   |   |
| 11 | `vault_0_mint`       |   |   |
| 12 | `vault_1_mint`       |   |   |
| 13 | `lp_mint`            | W |   |

**数学**

```
needed_token_0 = ceil(lp_token_amount * vault_0 / lp_supply)
needed_token_1 = ceil(lp_token_amount * vault_1 / lp_supply)
require(needed_token_0 <= maximum_token_0, "ExceededSlippage")
require(needed_token_1 <= maximum_token_1, "ExceededSlippage")
```

对 `k` 的比例性没有变化——金库和 `lp_supply` 按相同因子缩放。

**后置条件**

* `lp_supply += lp_token_amount`。
* `vault_0 += needed_token_0`（扣除任何输入上的 Token-2022 转账费用）。
* `vault_1 += needed_token_1`（扣除任何输入上的 Token-2022 转账费用）。

**常见错误** — `ExceededSlippage`、`ZeroTradingTokens`、如果存入被暂停则为 `InvalidStatus`。

## `Withdraw`

销毁 LP 代币并按比例接收两种底层代币。

**参数**

```
lp_token_amount:   u64
minimum_token_0:   u64
minimum_token_1:   u64
```

**账户**

| #  | 名称                   | W | S |
| -- | -------------------- | - | - |
| 1  | `owner`              |   | S |
| 2  | `authority`          |   |   |
| 3  | `pool_state`         | W |   |
| 4  | `owner_lp_token`     | W |   |
| 5  | `token_0_account`    | W |   |
| 6  | `token_1_account`    | W |   |
| 7  | `token_0_vault`      | W |   |
| 8  | `token_1_vault`      | W |   |
| 9  | `token_program`      |   |   |
| 10 | `token_program_2022` |   |   |
| 11 | `vault_0_mint`       |   |   |
| 12 | `vault_1_mint`       |   |   |
| 13 | `lp_mint`            | W |   |

（与 `Deposit` 相同；`lp_mint` 可写是因为 LP 代币被销毁。）

**数学**

```
out_token_0 = floor(lp_token_amount * vault_0 / lp_supply)
out_token_1 = floor(lp_token_amount * vault_1 / lp_supply)
require(out_token_0 >= minimum_token_0, "ExceededSlippage")
require(out_token_1 >= minimum_token_1, "ExceededSlippage")
```

**后置条件**

* `lp_supply -= lp_token_amount`。
* 金库发送 `out_token_0` / `out_token_1`（总额；用户收到的是扣除任何 Token-2022 转账费用后的净额）。

## `SwapBaseInput`

精确输入交换。

**参数**

```
amount_in:            u64
minimum_amount_out:   u64
```

**账户**

| #  | 名称                     | W | S |
| -- | ---------------------- | - | - |
| 1  | `payer`                |   | S |
| 2  | `authority`            |   |   |
| 3  | `amm_config`           |   |   |
| 4  | `pool_state`           | W |   |
| 5  | `input_token_account`  | W |   |
| 6  | `output_token_account` | W |   |
| 7  | `input_vault`          | W |   |
| 8  | `output_vault`         | W |   |
| 9  | `input_token_program`  |   |   |
| 10 | `output_token_program` |   |   |
| 11 | `input_token_mint`     |   |   |
| 12 | `output_token_mint`    |   |   |
| 13 | `observation_state`    | W |   |

排序**输入 → 输出**按用户的方向，不是按池的标准 `token_0 / token_1`。程序通过匹配代币来确定哪个金库是哪个。

**数学** — 见[`products/cpmm/math`](/zh/products/cpmm/math)。

**前置条件**

* `open_time <= now`。
* `pool_status` 允许交换。
* 两个代币都未对此权限暂停或冻结。
* `amount_in > 0`。

**常见错误**

* `ExceededSlippage` — `amount_out < minimum_amount_out`。
* `ZeroTradingTokens` — 交易舍入为零。
* `NotApproved` — 池通过 `UpdatePoolStatus` 被暂停用于交换。
* `InvalidInput` — 代币不匹配池的任何一个金库代币。

## `SwapBaseOutput`

精确输出交换。

**参数**

```
max_amount_in:  u64
amount_out:     u64
```

**账户** — 与 `SwapBaseInput` 相同。

**数学** — 反向曲线与上限，见[`products/cpmm/math`](/zh/products/cpmm/math)。

**常见错误** — `ExceededSlippage`（`gross_in > max_amount_in`）、`ZeroTradingTokens`、`InvalidInput`、`NotApproved`。

## `CollectProtocolFee`

从金库扫除累积的协议费用到协议目的地。

**参数** — 无。

**账户**

| #  | 名称                          | W | S |                                   |
| -- | --------------------------- | - | - | --------------------------------- |
| 1  | `owner`                     |   | S | 必须匹配 `amm_config.protocol_owner`。 |
| 2  | `authority`                 |   |   |                                   |
| 3  | `pool_state`                | W |   |                                   |
| 4  | `amm_config`                |   |   |                                   |
| 5  | `token_0_vault`             | W |   |                                   |
| 6  | `token_1_vault`             | W |   |                                   |
| 7  | `vault_0_mint`              |   |   |                                   |
| 8  | `vault_1_mint`              |   |   |                                   |
| 9  | `recipient_token_0_account` | W |   |                                   |
| 10 | `recipient_token_1_account` | W |   |                                   |
| 11 | `token_program`             |   |   |                                   |
| 12 | `token_program_2022`        |   |   |                                   |

**效果**

```
transfer pool_state.protocol_fees_token0 from vault_0 to recipient_0
transfer pool_state.protocol_fees_token1 from vault_1 to recipient_1
pool_state.protocol_fees_token0 = 0
pool_state.protocol_fees_token1 = 0
```

对曲线有效余额没有变化（累积费用已被排除）。

**常见错误** — 如果签署者不是 `protocol_owner` 则为 `NotApproved`。

## `CollectFundFee`

与 `CollectProtocolFee` 形状相同，但由 `fund_owner` 签署并将 `fund_fees_*` 计数器清零。

## `CollectCreatorFee`

同样的形状，由 `pool_state.pool_creator` 签署。仅在池以非零创建者费率初始化时才发出转账。

## `UpdatePoolStatus`

暂停或恢复池上的单个操作。`status` 字段是一个位掩码：

| 位 | 标志                  | 置位时的效果                                 |
| - | ------------------- | -------------------------------------- |
| 0 | `DEPOSIT_DISABLED`  | `Deposit` 以 `NotApproved` 拒绝。          |
| 1 | `WITHDRAW_DISABLED` | `Withdraw` 拒绝。                         |
| 2 | `SWAP_DISABLED`     | `SwapBaseInput` / `SwapBaseOutput` 拒绝。 |

**参数**

```
status: u8      // 新位掩码
```

**账户**

| # | 名称           | W | S |                      |
| - | ------------ | - | - | -------------------- |
| 1 | `authority`  |   | S | 必须匹配 CPMM 程序上的管理员密钥。 |
| 2 | `pool_state` | W |   |                      |

管理员密钥是 CPMM 程序上的升级权限——实际上是 Raydium 多签。见[`security/admin-and-multisig`](/zh/security/admin-and-multisig)。

## `CreateAmmConfig`

创建新的费用级别。

**参数**

```
index:             u16
trade_fee_rate:    u64
protocol_fee_rate: u64
fund_fee_rate:     u64
create_pool_fee:   u64
```

**账户**

| # | 名称               | W | S |         |
| - | ---------------- | - | - | ------- |
| 1 | `owner`          | W | S | 管理员。    |
| 2 | `amm_config`     | W |   | 在此处初始化。 |
| 3 | `system_program` |   |   |         |

**前置条件**

* 不存在具有相同 `index` 的 `AmmConfig`。
* `protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE`。

## `UpdateAmmConfig`

更改现有 `AmmConfig` 上的费率或所有权。接收 `param: u8`（用于更新哪个字段的判别器）和 `value: u64`。每个参数的值语义在源代码中；通常：

* `param = 0` → `trade_fee_rate`
* `param = 1` → `protocol_fee_rate`
* `param = 2` → `fund_fee_rate`
* `param = 3` → `new_protocol_owner`（以重解释形式传入 `Pubkey` 字节）
* `param = 4` → `new_fund_owner`
* `param = 5` → `create_pool_fee`
* `param = 6` → `disable_create_pool`

更改由管理员签署，在下次交换时影响**绑定到此 `AmmConfig` 的每个池**。无需迁移；池简单地读取新值。

## 状态变化矩阵

| 指令                         | `lp_supply` | 金库余额                  | 累积费用字段                                      | `observation` |
| -------------------------- | ----------- | --------------------- | ------------------------------------------- | ------------- |
| `Initialize`               | + 初始 LP     | + `init_amount_{0,1}` | 0                                           | 初始化           |
| `InitializeWithPermission` | + 初始 LP     | + `init_amount_{0,1}` | 0                                           | 初始化           |
| `Deposit`                  | +           | + 两者                  | —                                           | —             |
| `Withdraw`                 | −           | − 两者                  | —                                           | —             |
| `SwapBaseInput`            | —           | + 输入，− 输出             | + `trade_fee` 分割为协议/基金；如启用则 + `creator_fee` | + （如果间隔已过期）   |
| `SwapBaseOutput`           | —           | + 输入，− 输出             | + `trade_fee` 分割为协议/基金；如启用则 + `creator_fee` | + （如果间隔已过期）   |
| `CollectProtocolFee`       | —           | −（按协议桶）               | `protocol_*` → 0                            | —             |
| `CollectFundFee`           | —           | −（按基金桶）               | `fund_*` → 0                                | —             |
| `CollectCreatorFee`        | —           | −（按创建者桶）              | `creator_*` → 0                             | —             |
| `UpdatePoolStatus`         | —           | —                     | —                                           | —             |

## 后续步骤

* [`products/cpmm/code-demos`](/zh/products/cpmm/code-demos) — 上述内容的可运行 TypeScript 示例。
* [`reference/error-codes`](/zh/reference/error-codes) — 完整的 Anchor 错误表。
* [`products/cpmm/fees`](/zh/products/cpmm/fees) — `CollectProtocolFee` / `CollectFundFee` / `CollectCreatorFee` 清空的费用计提模型。

来源：

* [`raydium-io/raydium-cp-swap` — instructions](https://github.com/raydium-io/raydium-cp-swap/tree/master/programs/cp-swap/src/instructions)
* [Raydium SDK v2 — `@raydium-io/raydium-sdk-v2`](https://github.com/raydium-io/raydium-sdk-V2)
