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

<Info>
  本頁是權威的指令參考。如需實際組成這些指令的程式碼，請參閱 [`products/cpmm/code-demos`](/zh-Hant/products/cpmm/code-demos)。錯誤代碼的含義請見 [`reference/error-codes`](/zh-Hant/reference/error-codes)。
</Info>

## 指令總結

| 判別器名稱                      | 簽署者                              | 作用                                                                                                                                                                                                                                                                                                           |
| -------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Initialize`               | 池創建者                             | 從兩個 mint 和一個 `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` 帳戶，而非支付者。與 `Initialize` 相同的規範 PDA 或隨機金鑰對靈活性適用於 `pool_state`。 |
| `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`、`vaults`、`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 mint）。                                                                                                                                                                                                                                                           |
| 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` 簽署的情況下執行。

**前置條件**

* Mint 已排序（按位元組順序 `token_0_mint < token_1_mint`）。
* 沒有任何 mint 使用 CPMM 允許清單外的擴展（`TransferFeeConfig`、`MetadataPointer`、`TokenMetadata`、`InterestBearingConfig`、`ScaledUiAmount`）——參見 [`products/cpmm/accounts`](/zh-Hant/products/cpmm/accounts#vaults-and-token-2022)。程式內的小型每 mint 允許清單可為逐案上線繞過檢查。
* `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`。
* `LOCKED_LP`（100 lamport LP 代幣）的 LP 啟動者被永久鎖定在池中——`pool_state.lp_supply` 記錄 `liquidity − 100`，而 100 LP 單位仍在流通外，防止池被完全耗盡並除以零。
* `observation_state` 已初始化；`observation_index = 0` 且 `pool_id = pool_state.key()`。
* `create_pool_fee` lamport 從創建者轉移至接收者並同步為原生 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-Hant/reference/error-codes)）

* `InvalidInput` — mint 未排序，或相同的 mint。
* `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`。程式透過匹配 mint 確定哪個保險庫是哪個。

**數學** — 參見 [`products/cpmm/math`](/zh-Hant/products/cpmm/math)。

**前置條件**

* `open_time <= now`。
* `pool_status` 允許交換。
* 對此權限既無 mint 暫停也無凍結。
* `amount_in > 0`。

**常見錯誤**

* `ExceededSlippage` — `amount_out < minimum_amount_out`。
* `ZeroTradingTokens` — 交易四捨五入為零。
* `NotApproved` — 池透過 `UpdatePoolStatus` 暫停交換。
* `InvalidInput` — mint 不匹配池的任何保險庫 mint。

## `SwapBaseOutput`

精確輸出交換。

**引數**

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

**帳戶** — 與 `SwapBaseInput` 相同。

**數學** — 反向曲線加上上限，參見 [`products/cpmm/math`](/zh-Hant/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
```

曲線有效餘額無變化（累計費用已被排除）。

**常見錯誤** — `NotApproved`（如果簽署者不是 `protocol_owner`）。

## `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-Hant/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` |   |   |        |

**前置條件**

* 沒有現存 `AmmConfig` 具有相同的 `index`。
* `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`               | + init LP   | + `init_amount_{0,1}` | 0                                            | init          |
| `InitializeWithPermission` | + init LP   | + `init_amount_{0,1}` | 0                                            | init          |
| `Deposit`                  | +           | + 兩者                  | —                                            | —             |
| `Withdraw`                 | −           | − 兩者                  | —                                            | —             |
| `SwapBaseInput`            | —           | + in, − out           | + `trade_fee` 分割為協議/基金；如果啟用則 + `creator_fee` | + (如果間隔已過)    |
| `SwapBaseOutput`           | —           | + in, − out           | + `trade_fee` 分割為協議/基金；如果啟用則 + `creator_fee` | + (如果間隔已過)    |
| `CollectProtocolFee`       | —           | − (由協議儲存庫)            | `protocol_*` → 0                             | —             |
| `CollectFundFee`           | —           | − (由基金儲存庫)            | `fund_*` → 0                                 | —             |
| `CollectCreatorFee`        | —           | − (由創建者儲存庫)           | `creator_*` → 0                              | —             |
| `UpdatePoolStatus`         | —           | —                     | —                                            | —             |

## 後續步驟

* [`products/cpmm/code-demos`](/zh-Hant/products/cpmm/code-demos) — 上述內容的可執行 TypeScript 範例。
* [`reference/error-codes`](/zh-Hant/reference/error-codes) — 完整的 Anchor 錯誤表。
* [`products/cpmm/fees`](/zh-Hant/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)
