> ## 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`의 퍼미션 제어 변형입니다. 호출자(`payer`)는 자신의 공개키에서 파생된 `Permission` PDA를 소유해야 합니다. 풀 생성을 제한해야 하는 플랫폼에서 사용됩니다(예: LaunchLab 졸업). 호출자가 `creator_fee_on`(`BothToken` / `OnlyToken0` / `OnlyToken1`)을 지정할 수 있으며, 새 풀에서 `enable_creator_fee = true`로 강제합니다. `pool_state`의 `creator` 필드는 지불자가 아닌 별도로 전달된 `creator` 계정으로 설정됩니다. `pool_state`에 대해 `Initialize`와 동일한 정규 PDA 또는 무작위 키페어 유연성이 있습니다. |
| `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\* | 여기서 `init`됨. **정규 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`, `vault`, `observation_state`)는 어느 경우든 `pool_state.key()`에서 파생됩니다. |
| 5  | `token_0_mint`             |   |     | 정렬됨: `token_0_mint < token_1_mint`.                                                                                                                                                                                                                                                                                                     |
| 6  | `token_1_mint`             |   |     |                                                                                                                                                                                                                                                                                                                                         |
| 7  | `lp_mint`                  | W |     | 여기서 `init`됨. 권한이 `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 |     | 여기서 `init`됨. `authority`가 소유.                                                                                                                                                                                                                                                                                                           |
| 12 | `token_1_vault`            | W |     |                                                                                                                                                                                                                                                                                                                                         |
| 13 | `create_pool_fee`          | W |     | 생성자가 지불하는 `create_pool_fee`에 대한 목적지 ATA.                                                                                                                                                                                                                                                                                                |
| 14 | `observation_state`        | W |     | 여기서 `init`됨.                                                                                                                                                                                                                                                                                                                            |
| 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`](/ko/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`로 존재합니다.
* `LOCKED_LP`(LP 토큰 100 라마포)의 LP 스타터는 풀에서 영구적으로 잠깁니다 — `pool_state.lp_supply`는 `liquidity − 100`을 기록하는 동안 `100` LP 단위는 순환 외부에 남아있어 풀이 완전히 비워지는 것과 0으로 나누는 것을 방지합니다.
* `observation_state`가 초기화됩니다; `observation_index = 0`이고 `pool_id = pool_state.key()`.
* `create_pool_fee` 라마포는 생성자에서 수신자로 전송되고 네이티브 SOL로 동기화됩니다(wSOL ATA입니다).
* 풀의 상태 비트마스크는 `0`입니다(입금 / 출금 / 스왑 모두 활성화).
* `enable_creator_fee = false`이고 `creator_fee_on = BothToken`. `Initialize`는 생성자 수수료 활성화를 지원하지 **않습니다** — 그 경로는 `InitializeWithPermission`입니다.
* `open_time`은 호출자가 `<= block_timestamp` 값을 전달한 경우 `block_timestamp + 1`로 범프됩니다. 스왑은 `open_time` 전에 거부됩니다; 입금 및 출금은 즉시 작동합니다.

**일반적인 오류** (전체 목록은 [`reference/error-codes`](/ko/reference/error-codes)에서)

* `InvalidInput` — 민트가 정렬되지 않았거나 동일한 민트.
* `NotSupportMint` — 차단된 Token-2022 확장.
* `ExceededSlippage` — 드문 경우; `init_amount_0/1`이 소수점 자릿수 불일치로 인해 0 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`](/ko/products/cpmm/math) 참고.

**전제 조건**

* `open_time <= now`.
* `pool_status`가 스왑을 허용함.
* 이 권한에 대해 두 민트 모두 일시 중지되거나 동결되지 않음.
* `amount_in > 0`.

**일반적인 오류**

* `ExceededSlippage` — `amount_out < minimum_amount_out`.
* `ZeroTradingTokens` — 거래가 0으로 반올림됨.
* `NotApproved` — 풀이 `UpdatePoolStatus`를 통해 스왑에 대해 일시 중지됨.
* `InvalidInput` — 민트가 풀의 금고 민트 중 하나와도 일치하지 않음.

## `SwapBaseOutput`

정확한 출력 스왑.

**인수**

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

**계정** — `SwapBaseInput`과 동일합니다.

**수학** — 역 곡선과 함께 천정, [`products/cpmm/math`](/ko/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_*` 카운터를 0으로 설정합니다.

## `CollectCreatorFee`

마찬가지로 동일한 형태이며 `pool_state.pool_creator`가 서명합니다. 풀이 0이 아닌 생성자 수수료율로 초기화된 경우에만 이전을 내보냅니다.

## `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`](/ko/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 |   | 여기서 `init`됨. |
| 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`               | + 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`](/ko/products/cpmm/code-demos) — 위의 실행 가능한 TypeScript 샘플.
* [`reference/error-codes`](/ko/reference/error-codes) — 완전한 Anchor 오류 테이블.
* [`products/cpmm/fees`](/ko/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)
