> ## 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 명령어 전체 참조: 풀 생애주기, 포지션 관리, 스왑, 리워드 스트림.

<Info>
  **이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.**

  [영문판 보기 →](/products/clmm/instructions)
</Info>

<Info>
  이 페이지는 [`products/clmm/accounts`](/ko/products/clmm/accounts)(계정 구조)와 [`products/clmm/math`](/ko/products/clmm/math)(수학적 원리)를 함께 참고하세요. 인자 및 계정 순서에 대한 기준 문서이며, 구체적인 바이트 레이아웃은 IDL을 참조하세요.
</Info>

## 명령어 목록

| 그룹          | 명령어                                                              | 비고                                                                                                                                                                               |
| ----------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Admin       | `CreateAmmConfig`                                                | 새로운 수수료 티어를 정의합니다.                                                                                                                                                               |
| Admin       | `UpdateAmmConfig`                                                | 기존 티어의 요율을 변경합니다.                                                                                                                                                                |
| Admin       | `UpdatePoolStatus`                                               | 풀의 운영을 일시정지/재개합니다.                                                                                                                                                               |
| Admin       | `CreateSupportMintAssociated`                                    | Token-2022 민트 확장 설정을 CLMM 풀에서 사용할 수 있도록 허용 목록에 추가합니다.                                                                                                                            |
| Admin       | `CreateOperationAccount`                                         | 프로그램 수준의 운영 계정을 초기화합니다(최초 1회).                                                                                                                                                   |
| Admin       | `UpdateOperationAccount`                                         | 운영 계정의 화이트리스트를 수정합니다.                                                                                                                                                            |
| Admin       | `CreateDynamicFeeConfig`                                         | u16 인덱스 기반의 재사용 가능한 동적 수수료 파라미터 세트를 생성합니다.                                                                                                                                       |
| Admin       | `UpdateDynamicFeeConfig`                                         | 기존 `DynamicFeeConfig`를 수정합니다. 이미 스냅샷을 생성한 풀에는 영향이 없습니다.                                                                                                                          |
| Pool        | `CreatePool`                                                     | `AmmConfig`에 연결된 CLMM 풀을 초기화합니다. 표준 FromInput 수수료 경로. `CreateCustomizablePool`과 공존합니다.                                                                                           |
| Pool        | `CreateCustomizablePool`                                         | 신규 풀 생성 시 권장됩니다. `CreatePool`과 동일한 구조에 `collect_fee_on` 및 선택적 `enable_dynamic_fee` 플래그가 추가됩니다.                                                                                   |
| Position    | `OpenPosition` / `OpenPositionV2` / `OpenPositionWithToken22Nft` | 포지션 NFT를 발행합니다. `OpenPositionV2`는 V1을 대체하며(비트맵 확장 슬롯이 포함된 최신 계정 레이아웃), `OpenPositionWithToken22Nft`는 포지션 NFT를 SPL Token 대신 Token-2022로 발행합니다. 신규 코드는 V2 또는 Token-2022 변형을 사용하세요. |
| Position    | `IncreaseLiquidity` / `IncreaseLiquidityV2`                      | 기존 포지션에 유동성을 추가합니다.                                                                                                                                                              |
| Position    | `DecreaseLiquidity` / `DecreaseLiquidityV2`                      | 유동성을 제거하고 발생한 수수료를 수령합니다.                                                                                                                                                        |
| Position    | `ClosePosition`                                                  | NFT를 소각하고 `PersonalPositionState`를 종료합니다.                                                                                                                                        |
| Position    | `CloseProtocolPosition`                                          | 레거시 `ProtocolPositionState` PDA에 대한 관리자 전용 정리 명령어입니다. 현재 프로그램은 `ProtocolPositionState`를 생성하거나 읽지 않으며, 이 명령어는 구버전 프로그램이 생성한 계정의 렌트를 회수하기 위해서만 존재합니다.                              |
| Swap        | `Swap` / `SwapV2`                                                | 고정 유동성 스왑. 두 변형 모두 동적 수수료, 단방향 수수료 라우팅, 지정가 주문 매칭을 지원합니다. 유일한 차이점은 `SwapV2`가 Token-2022 민트를 허용한다는 것입니다(V1은 두 볼트 모두 클래식 SPL Token이어야 함).                                          |
| Swap        | `SwapRouterBaseIn`                                               | 멀티홉 스왑, 라우터에서 사용됩니다.                                                                                                                                                             |
| Limit order | `OpenLimitOrder`                                                 | 특정 틱에 매도 주문을 배치합니다. 미체결 토큰은 해당 틱에 대기하며, 가격이 지나갈 때 체결됩니다.                                                                                                                         |
| Limit order | `IncreaseLimitOrder`                                             | 기존 미체결 주문에 수량을 추가합니다.                                                                                                                                                            |
| Limit order | `DecreaseLimitOrder`                                             | 미체결 주문을 줄이거나 취소합니다. 미체결 잔량과 이미 정산된 출력 토큰을 지급합니다.                                                                                                                                 |
| Limit order | `SettleLimitOrder`                                               | 체결된 출력 토큰을 주문 소유자에게 전송합니다. 소유자 또는 운영 키퍼가 호출 가능합니다.                                                                                                                               |
| Limit order | `CloseLimitOrder`                                                | 완전히 소진된 주문 계정을 닫습니다. 렌트는 항상 주문의 `owner`에게 반환됩니다. 소유자 또는 키퍼가 호출 가능합니다.                                                                                                            |
| Fees        | `CollectProtocolFee`                                             | 프로토콜 수수료 관리자 수거.                                                                                                                                                                 |
| Fees        | `CollectFundFee`                                                 | 펀드 수수료 관리자 수거.                                                                                                                                                                   |
| Rewards     | `InitializeReward`                                               | 풀에 새로운 리워드 스트림을 연결합니다.                                                                                                                                                           |
| Rewards     | `SetRewardParams`                                                | 기존 리워드의 방출 속도/종료 시간을 변경합니다.                                                                                                                                                      |
| Rewards     | `UpdateRewardInfos`                                              | 리워드 누적을 현재 시점까지 정산합니다(스왑/포지션 변경 시 자동 호출).                                                                                                                                        |
| Rewards     | `TransferRewardOwner`                                            | 리워드 스트림의 설정 또는 충전 권한을 이전합니다.                                                                                                                                                     |
| Rewards     | `CollectRemainingRewards`                                        | 리워드 스트림의 `end_time` 이후, 미배분 토큰을 펀더에게 회수합니다.                                                                                                                                      |
| Utility     | `InitTickArray`                                                  | 틱 배열 계정을 초기화합니다(`OpenPosition`과 함께 번들링되는 경우가 많습니다).                                                                                                                              |

대부분의 관리자 전용 명령어(`CreateAmmConfig`, `UpdateAmmConfig`, `UpdatePoolStatus`, `CreateSupportMintAssociated`, `CreateOperationAccount`, `UpdateOperationAccount`, `CloseProtocolPosition`)는 프로그램에 하드코딩된 `admin` 공개 키로 제한됩니다. 리워드 스트림 관리 명령어(`TransferRewardOwner`, `CollectRemainingRewards`)는 프로그램 관리자가 아닌 리워드 펀더에 의해 제한됩니다.

V2 접미사는 "볼트/NFT에서 Token-2022 지원, 비트맵 확장 슬롯 필요"를 의미합니다. SDK는 신규 풀에 대해 기본적으로 V2를 선택합니다.

## `CreatePool`

**인자**

```
sqrt_price_x64: u128           // 초기 가격
open_time:      u64            // 이 시간 이전의 스왑은 거부됨
```

**계정 (요약)**

| #  | 이름                            | 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`, 풀 authority PDA 소유. |
| 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`는 0으로 초기화됩니다(동적 수수료 비활성화).

## `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`에서 초기화됩니다(5개의 보정 파라미터가 복사되고 상태 필드는 0으로 초기화).
* 그렇지 않은 경우: `pool_state.dynamic_fee_info`는 0으로 초기화됩니다(해당 풀에서 영구적으로 동적 수수료 비활성화).

`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 |             | NFT에 대한 소유자의 ATA.                   |
| 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`](/ko/products/clmm/math)를 참조하세요. `base_flag`에 따라 프로그램은 `liquidity` 또는 `(amount_0_max, amount_1_max)`를 실제 `L`과 실제 소비된 토큰 수량으로 변환합니다.

**사전 조건**

* `tick_lower < tick_upper`, 둘 다 `pool.tick_spacing`의 배수이어야 하며 `[MIN_TICK, MAX_TICK]` 범위 내에 있어야 합니다.
* 필요한 틱 배열이 전달되고 초기화되어 있어야 합니다(또는 트랜잭션 내에서 `InitTickArray` CPI로 생성).
* 사용자의 소스 ATA에 `amount_0_max` 및 `amount_1_max` 이상의 잔액이 있어야 합니다.

**사후 조건**

* `personal_position`이 존재하고, `liquidity`가 설정되며, `fee_growth_inside_last`가 스냅샷됩니다.
* `tick_lower` 및 `tick_upper`의 틱 배열 항목이 업데이트됩니다(`liquidity_gross += L`, `liquidity_net ± L`, 수수료 성장 스냅샷 유지).
* 포지션이 범위 내인 경우(`tick_lower ≤ tick_current < tick_upper`) `pool_state.liquidity += L`.

**일반적인 오류** — `InvalidTickIndex`, `NotApproved`, `ZeroAmountSpecified`, `TransactionTooLarge` (틱 배열이 너무 많은 경우).

## `IncreaseLiquidityV2`

이미 열린 포지션에 유동성을 추가합니다.

**인자**

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

**계정** — `OpenPosition`과 유사하되 NFT 민트 제외(포지션이 이미 존재하며 NFT는 1개의 토큰을 보유한 소유자의 ATA로 전달됨).

**효과**

* 사용자 → 볼트로 `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`와 동일한 구조.

**효과**

* 현재 `sqrt_price_x64`를 기준으로 제거된 `L`에 대한 `(amount_0, amount_1)`을 계산합니다.
* `IncreaseLiquidity`와 동일하게 마지막 조작 이후 발생한 수수료/리워드를 정산합니다.
* 볼트에서 사용자에게 `amount_0 + fees_owed_0` 및 `amount_1 + fees_owed_1`을 전송합니다.
* 유동성 카운터를 감소시키며, 새로운 `personal_position.liquidity == 0`이면 `ClosePosition`이 가능해집니다.

**슬리피지** — `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`.

(즉, 모든 것을 수령하고 유동성을 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 |   | 스왑이 확장 영역으로 이동하는 경우.       |
| 14+ | `tick_array` (나머지)                      | W |   | 예상 스왑 범위를 커버할 만큼의 배열.      |

호출자는 예상되는 스왑 범위를 커버하는 틱 배열의 우선순위 목록을 전달하며, 프로그램은 필요한 만큼 사용합니다. SDK는 `PoolUtils.computeAmountOutFormat` 또는 API의 쿼트 엔드포인트를 통해 이 목록을 계산합니다.

**사전 조건**

* `pool_state.status`가 스왑을 허용해야 합니다.
* `now >= open_time`.
* `sqrt_price_limit_x64`가 방향에 맞게 `sqrt_price_x64`의 올바른 쪽에 있어야 합니다.

**일반적인 오류** — `ExceededSlippage`, `SqrtPriceLimitOverflow`, `TickArrayNotFound`, `LiquidityInsufficient`.

**호출자가 알아야 할 `SwapV2` 내부 동작** (2025년 이후 릴리즈):

1. **동적 수수료 할증** — `pool.dynamic_fee_info`가 0이 아닌 경우, 프로그램은 마지막 스왑 이후 이동한 틱 거리를 기반으로 변동성 누적기를 업데이트하고([`products/clmm/fees`](/ko/products/clmm/fees)의 필터/감쇠 규칙 적용), `AmmConfig.trade_fee_rate`에 `dynamic_fee_component`를 추가합니다. 총 수수료는 10%로 상한이 설정됩니다(`MAX_FEE_RATE_NUMERATOR / 1_000_000`).
2. **지정가 주문 매칭** — 가격 이동이 미체결 지정가 주문이 있는 틱을 통과할 때, 프로그램은 먼저 해당 틱의 지정가 주문 유동성을 `order_phase` 순서로 FIFO 방식으로 체결한 후 LP 유동성 커브를 따라 진행합니다. 체결된 수량은 나중에 정산할 수 있도록 `tick.unfilled_ratio_x64` 및 `tick.part_filled_orders_remaining`을 업데이트하며, 주문은 소유자가 `SettleLimitOrder`를 호출할 때까지 미정산 상태로 유지됩니다.
3. **단방향 수수료 라우팅** — `pool.fee_on = Token0Only` 또는 `Token1Only`인 경우, 스왑 단계는 동일한 입출력 거래를 계산하지만 수수료는 설정된 방향으로 라우팅됩니다. 설정된 수수료 방향이 출력 쪽인 경우, 수수료는 스왑 출력에서 차감됩니다(사용자는 `out − fee`를 받음). 입력 쪽인 경우의 동작은 `FromInput`과 동일합니다. `PoolState`의 `is_fee_on_input(zero_for_one)` 및 `is_fee_on_token0(zero_for_one)`을 참조하세요.

`Swap` (V1)은 `SwapV2`와 동일하게 동적 수수료, 단방향 수수료 라우팅, 지정가 주문 매칭을 구현합니다. 유일한 차이점은 Token-2022 지원이 없다는 것으로, 두 볼트 모두 클래식 SPL Token이어야 합니다. Token-2022 민트가 포함된 풀은 `SwapV2`를 통해 스왑해야 합니다. 어그리게이터와 SDK는 이미 모든 CLMM 레그에 V2를 우선 사용하므로 호출자가 민트 유형에 따라 분기할 필요가 없습니다.

## `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` (0이거나 풀의 최솟값 미만), `InvalidTickIndex` (`[MIN_TICK, MAX_TICK]` 범위를 벗어나거나 선택한 방향에 맞게 `tick_current`의 잘못된 쪽에 있음), `TickAndSpacingNotMatch` (`tick_index % pool.tick_spacing != 0`), `OrderPhaseSaturated`.

## `IncreaseLimitOrder`

기존 미체결 주문에 수량을 추가합니다. 주문의 `owner`만 호출 가능합니다.

**인자**

```
amount: u64    // 추가 입력 토큰 수량
```

**계정** — `OpenLimitOrder`와 유사하되 nonce 계정 제외; `limit_order` PDA가 직접 전달됩니다.

**사전 조건**

* `limit_order.owner == signer`.
* 주문이 동일한 코호트에 있어야 합니다(`tick.order_phase == limit_order.order_phase`). 코호트가 이미 체결을 시작한 경우 주문은 부분 정산 상태이므로, 먼저 `DecreaseLimitOrder` 또는 `SettleLimitOrder`를 호출하여 롤 포워드해야 합니다.

**효과**

* 소유자 ATA에서 `input_vault`로 `amount`를 전송합니다.
* `limit_order.total_amount += amount`; `tick.orders_amount += amount`.

## `DecreaseLimitOrder`

미체결 주문을 줄이거나 완전히 취소합니다. 소유자에게 미체결 잔량을 환불하고, 이전 부분 체결로 이미 정산된 출력 토큰도 지급합니다.

**인자**

```
amount:     u64    // 출금할 입력 토큰 수량 (최대 = 미체결 잔량)
amount_min: u64    // 입력 측 출금에 대한 슬리피지 하한
```

**계정** — 입력 및 출력 토큰 양쪽 모두:

| #  | 이름                                      | 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`를 업데이트합니다. 새로운 미체결 잔량이 0이 되면, 프로그램은 계정을 종료하고 `owner`에게 렌트를 환급합니다.

## `SettleLimitOrder`

주문의 미체결 잔량을 변경하지 않고 체결된 출력 토큰을 소유자에게 전송합니다. `auto_withdraw` 키퍼가 장기 실행되는 부분 체결을 드립 방식으로 지급할 때 유용합니다.

**호출자** — 주문의 `owner` 또는 프로그램의 `limit_order_admin`(자동화된 키퍼 루프를 실행하는 오프체인 운영 핫 월렛). 키퍼는 다른 권한이 없으며, 체결된 출력을 주문의 `owner` ATA로 전송하는 것 외에는 사용자 자금을 이동할 수 없습니다.

**계정**

| # | 이름                     | 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`.

**사전 조건**

* 주문의 미체결 잔량이 0이어야 합니다(전액 체결 및 정산되었거나, 소유자가 이전에 주문을 0으로 감소시키고 종료하지 않은 경우).

**효과**

* `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 | 하드코딩된 admin 공개 키. |
| 2 | `dynamic_fee_config` | W |   | PDA, 여기서 `init`.  |
| 3 | `system_program`     |   |   |                   |

**일반적인 오류** — `decay_period <= filter_period`이거나 0이어야 할 필드가 범위를 벗어난 경우 `InvalidDynamicFeeConfigParams`.

## `UpdateDynamicFeeConfig` (admin)

기존 `DynamicFeeConfig`를 수정합니다. 생성 시 이미 설정을 스냅샷한 풀은 **소급 업데이트되지 않으며**, 이 설정을 참조하는 새로 생성되는 풀만 새 값을 적용합니다.

**인자** — `CreateDynamicFeeConfig`와 동일한 5개의 보정 필드(`filter_period`, `decay_period`, `reduction_factor`, `dynamic_fee_control`, `max_volatility_accumulator`). `index`는 생성 시 고정되며 여기서 다시 전달하지 않습니다.

## `CollectProtocolFee` / `CollectFundFee`

CPMM의 `CollectProtocolFee` / `CollectFundFee`와 동일한 형태입니다. 서명자는 `AmmConfig.owner` / `AmmConfig.fund_owner`와 일치해야 합니다. 풀의 볼트에서 발생한 프로토콜/펀드 수수료를 수신자에게 이전하고, 해당 `PoolState.protocol_fees_*` / `fund_fees_*` 필드를 0으로 초기화합니다.

## `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`        |   |   | 리워드 생성을 제어하는 CLMM 운영 상태 PDA. |
| 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`

순수 장부 관리 명령어로, `emissions_per_second × Δt / liquidity`를 곱해 `reward_growth_global_x64`를 현재 시간까지 정산합니다. 유동성에 관련된 모든 명령어가 내부적으로 호출합니다. 외부 액터(UI, 크랭크)가 이를 직접 트리거하고 싶을 때를 위해 독립 명령어로도 제공됩니다.

## `CollectReward`

포지션 소유자가 발생한 리워드 토큰을 청구합니다.

**계정**

| # | 이름                        | W | S |                        |
| - | ------------------------- | - | - | ---------------------- |
| 1 | `nft_owner`               |   | S |                        |
| 2 | `nft_account`             |   |   | 포지션 NFT를 보유한 소유자의 ATA. |
| 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]`를 0으로 초기화합니다.

## 상태 변경 매트릭스

| 명령어                      | `pool.liquidity` | `pool.fee_growth_global` | `pool.reward_growth_global` | `personal_position.liquidity` | 틱 배열                            |
| ------------------------ | ---------------- | ------------------------ | --------------------------- | ----------------------------- | ------------------------------- |
| `CreatePool`             | 0                | 0                        | —                           | —                             | —                               |
| `OpenPosition`           | 범위 내이면 +         | —                        | —                           | 신규                            | liquidity\_gross/net 추가         |
| `IncreaseLiquidity`      | 범위 내이면 +         | 발생분 정산                   | 발생분 정산                      | +                             | 조정                              |
| `DecreaseLiquidity`      | 범위 내이면 −         | 발생분 정산                   | 발생분 정산                      | −                             | 조정                              |
| `ClosePosition`          | —                | —                        | —                           | 소멸                            | —                               |
| `SwapV2`                 | 크로싱 시 ±          | +                        | —                           | —                             | 크로스 & 외부 플립; 지정가 주문 코호트 매칭      |
| `OpenLimitOrder`         | —                | —                        | —                           | —                             | 대상 틱에 `orders_amount += amount` |
| `IncreaseLimitOrder`     | —                | —                        | —                           | —                             | `orders_amount += amount`       |
| `DecreaseLimitOrder`     | —                | —                        | —                           | —                             | `orders_amount -=`, 코호트 종료 가능   |
| `SettleLimitOrder`       | —                | —                        | —                           | —                             | — (틱 읽기 전용)                     |
| `CloseLimitOrder`        | —                | —                        | —                           | —                             | —                               |
| `CreateCustomizablePool` | 0                | 0                        | —                           | —                             | —                               |
| `UpdateRewardInfos`      | —                | —                        | +                           | —                             | —                               |
| `CollectReward`          | —                | —                        | 발생분 정산                      | —                             | —                               |

## 다음 단계

* [`products/clmm/code-demos`](/ko/products/clmm/code-demos) — 실행 가능한 TypeScript 샘플.
* [`products/clmm/fees`](/ko/products/clmm/fees) — 수수료 및 리워드 발생에 대한 세부 정보.
* [`reference/error-codes`](/ko/reference/error-codes) — 전체 CLMM Anchor 오류 표.

출처:

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