> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meteora.ag/llms.txt
> Use this file to discover all available pages before exploring further.

# DLMM Pro Program Instructions

> All DLMM Pro instructions grouped by area, with signers, purpose and the matching TypeScript SDK builder.

The DLMM Pro IDL (`DlmmProIDL` in `@meteora-ag/dlmm-pro-sdk`) defines 39 callable instructions. It also lists `for_idl_type_generation_do_not_call`, which exists only for IDL type generation and is not in the deployed program. Build user transactions with the [TypeScript SDK](https://docs.meteora.ag/developer-guides/dlmm-pro/typescript-sdk/getting-started.md), or call the program by CPI using the account lists in the IDL. The SDK builder for each user instruction is named in the Use column.

Instructions that emit events through event CPI include the `event_authority` and `program` accounts. See [Events](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events.md).

## Pool Creation

All three create the pool, its two reserve vaults and its oracle. The bitmap extension is created too when you pass it. The pool creator is recorded as `creator` and does not sign.

| Instruction | Signer(s) | Use |
| - | - | - |
| `initialize_pool_with_static_config` | Payer, plus the config's pool creator authority when the config is not public | Creates a pool from a `StaticConfig`, which fixes fees, tick spacing, collect fee mode, activation type and extensions. `client.pool.initializePoolWithStaticConfig`. |
| `initialize_pool_with_dynamic_config` | Payer, pool creator authority | Creates a pool with caller-chosen fees, tick spacing, activation and extensions, under a `DynamicConfig`. `client.pool.initializePoolWithDynamicConfig`. |
| `initialize_launch_pool` | Payer | Creates a launch pool keyed by its mint pair, with no config. The payer proves it holds both tokens through `user_token_x` and `user_token_y` (non-zero balances, nothing transferred). `client.pool.initializeLaunchPool`. |

A mint that needs a token badge is checked against the access registry during creation. `CollectFeeMode.OnlyY` also needs a badge for token Y unless it is wrapped SOL or USDC. See [Pool Creation and Activation](https://docs.meteora.ag/core-products/dlmm-pro/pool-creation-and-activation.md).

## Swap

| Instruction | Signer(s) | Use |
| - | - | - |
| `swap` | User | Exact-in swap. The direction comes from the mint of `user_token_out`. `client.pool.swap`, with `client.pool.quoteExactIn` to pick the tick arrays. |

> [!WARNING]
>
> `swap` is exact-in only. The program reverts with `NotConsumingFullAmountIn` unless the swap consumes all of `input_amount`. This happens when the tick arrays you pass run out of liquidity. Pass the tick arrays of a quote whose `amountLeft` is zero, in swap direction order (descending index for `swap_for_y`, ascending otherwise).

`input_amount` is the exact input before the input mint transfer fee. `minimum_output_amount` is the least you accept after the output mint transfer fee. The optional `referral` token account receives the host fee and must hold the fee token.

## Tick Arrays and Oracle

| Instruction | Signer(s) | Use |
| - | - | - |
| `initialize_tick_array` | Funder | Creates the tick array account for one index. Does nothing if it exists. `client.pool.initializeTickArray`. |
| `initialize_tick_bitmap_extension` | Funder | Creates the bitmap extension for tick array indexes outside -512 to 511. `client.pool.initializeTickBitmapExtension`. |
| `increase_oracle_length` | Payer | Grows the oracle by `length_to_add` observations, up to 500 in total. `client.pool.increaseOracleLength`. |

## Positions

| Instruction | Signer(s) | Use |
| - | - | - |
| `open_position` | Position NFT mint (new keypair), payer | Mints the position NFT to `owner` and creates the position array with one slot per range in `tick_ranges`, up to 45. Creates missing tick arrays and ticks. `client.position.openPosition`. |
| `expand_position` | Position owner, or a delegate with UpdatePositionRange, payer | Adds range slots to a position. Raises `layout_version`. `client.position.expandPosition`. |
| `remove_position` | Position owner, or a delegate with UpdatePositionRange | Removes empty range slots selected by `bitmap`. Raises `layout_version`. Cannot select every slot. A delegate must name the owner as `rent_receiver`, or the call fails with `InvalidPermission`. `client.position.removePosition`. |
| `close_position` | Position owner | Closes an empty position. Burns the NFT, closes its token account and mint, collects tick array rent and sends rent to `rent_receiver`. `client.position.closePosition`. |
| `update_position_delegate_permission` | Position owner | Sets the permission bitmask for the NFT delegate. `client.position.updatePositionDelegatePermission`. |

Instructions that act on range slots take a `u64` bitmap in which bit `i` selects slot `i`. `add_liquidity`, `add_liquidity_by_weight`, `add_liquidity_imbalance`, `remove_liquidity`, `remove_liquidity_by_bps`, `remove_position`, `lock_permanent_position` and `lock_vesting_position` also take `expected_layout_version` (`Option<u16>`) and fail with `InvalidLayoutVersion` when it differs from the position array. Pass `None` (`null` in the SDK) to skip the check. See [Positions](https://docs.meteora.ag/core-products/dlmm-pro/positions.md).

## Liquidity

Each instruction needs the position NFT token account (`nft_account`) and the tick arrays of the selected slots.

| Instruction | Signer(s) | Use |
| - | - | - |
| `add_liquidity` | Position owner, or a delegate with AddLiquidity | Deposits `liquidities[k]` into each selected slot, capped by `max_amount_x` and `max_amount_y`. `client.position.addLiquidity`. |
| `add_liquidity_by_weight` | Position owner, or a delegate with AddLiquidity | Like `add_liquidity`, with each selected slot's liquidity given as `multiplier × weight` (one `u8` weight per slot in `liquidities`). `client.position.addLiquidityByWeight`. |
| `add_liquidity_imbalance` | Position owner, or a delegate with AddLiquidity | Deposits one slot with optional per-token caps and a price or minimum liquidity slippage check. `client.position.addLiquidityImbalance`. |
| `remove_liquidity` | Position owner, or a delegate with RemoveLiquidity | Withdraws `liquidities[k]` from each selected slot, with `min_amount_x` and `min_amount_y` as slippage bounds. `client.position.removeLiquidity`. |
| `remove_liquidity_by_bps` | Position owner, or a delegate with RemoveLiquidity | Withdraws `bps` of each selected slot's unlocked liquidity, after releasing vested liquidity (all slots when `bitmap` is `None`). `client.position.removeLiquidityByBps`. |

A delegate that withdraws tokens can only pay into the owner associated token accounts, or the program fails with `IncorrectATA`.

## Fees and Locks

| Instruction | Signer(s) | Use |
| - | - | - |
| `refresh_fees_and_rewards` | Position owner, or any delegate | Accrues fees and rewards into the selected slots without moving tokens. `client.position.refreshFeesAndRewards`. |
| `claim_fee` | Position owner, or a delegate with ClaimFee | Pays out the pending fees of the position, with `min_amount_x` and `min_amount_y` as slippage bounds. `client.position.claimFee`. |
| `lock_permanent_position` | Position owner | Locks `bps` of each slot's unlocked liquidity for good. The locked liquidity cannot be removed. `client.position.lockPermanentPosition`. |
| `lock_vesting_position` | Position owner | Moves liquidity into a vesting schedule (cliff, then periodic releases). One schedule per position. `client.position.lockVestingPosition`. |

Fees and rewards accrue to a slot when it is refreshed. Claim after refreshing every slot that holds liquidity.

## Limit Orders

| Instruction | Signer(s) | Use |
| - | - | - |
| `open_limit_order` | Limit order NFT mint (new keypair), payer, owner | Mints the limit order NFT and deposits one side into up to 25 ticks. `client.limitOrder.openLimitOrder`. |
| `cancel_limit_order` | Order owner, or a delegate with CancelLimitOrder | Cancels the listed ticks and pays out the unfilled amount, the filled proceeds and the owner share of the fee. `client.limitOrder.cancelLimitOrder`. |
| `close_limit_order` | Order owner | Closes a limit order whose ticks are all canceled. Burns the NFT, closes its token account and mint, and sends rent to `rent_receiver`. `client.limitOrder.closeLimitOrder`. |
| `update_limit_order_delegate_permission` | Order owner | Sets the permission bitmask for the NFT delegate. `client.limitOrder.updateLimitOrderDelegatePermission`. |

See [Limit Orders](https://docs.meteora.ag/core-products/dlmm-pro/limit-orders.md).

## Rewards

Rewards apply to pools with the LiquidityMining extension. A pool has 2 reward slots. See [Liquidity Mining](https://docs.meteora.ag/core-products/dlmm-pro/liquidity-mining.md).

| Instruction | Signer(s) | Use |
| - | - | - |
| `initialize_reward` | Payer, plus an operator with InitializeReward or the pool creator (slot 0 only) | Creates the reward vault and sets the reward mint and authority of a slot. `client.reward.initializeReward`. |
| `update_reward_authority` | Pool creator (slot 0), or an operator with UpdateRewardAuthority | Changes the authority of a reward slot. `client.reward.updateRewardAuthority`. |
| `set_reward_emission` | Funder, reward authority | Funds the reward vault and sets the emission window and rate. `client.reward.setRewardEmission`. |
| `claim_reward` | Position owner, or a delegate with ClaimReward | Pays out the pending amount of one reward index, summed over every range slot of the position. `client.reward.claimReward`. |
| `withdraw_ineligible_rewards` | Reward authority | Withdraws rewards emitted while the pool had no liquidity, once the emission has ended. `client.reward.withdrawIneligibleRewards`. |

## Partner and Protocol Fees

| Instruction | Signer(s) | Use |
| - | - | - |
| `claim_partner_fee` | Pool partner | Pays out the accrued partner fee, capped by `max_amount_x` and `max_amount_y`. `client.pool.claimPartnerFee`. |
| `claim_protocol_fee2` | Protocol fee authority | Pays out the accrued protocol fee of one token to the protocol. Not callable by integrators. |

## Operator and Admin

The SDK does not wrap these. Build them with `client.program.methods`, where Anchor exposes each instruction in camel case (for example `client.program.methods.createStaticConfig(...)`).

| Instruction | Signer(s) | Use |
| - | - | - |
| `create_operator_account` | Admin, payer | Creates an `Operator` account with a permission bitmask for an address. |
| `close_operator_account` | Admin | Closes an `Operator` account. |
| `create_static_config` | Operator with CreateConfigKey, payer | Creates a `StaticConfig`. |
| `create_dynamic_config` | Operator with CreateConfigKey, payer | Creates a `DynamicConfig`. |
| `close_config` | Operator with RemoveConfigKey | Closes a static or dynamic config. |
| `set_pool_status` | Operator with SetPoolStatus | Disables or enables swaps and adding liquidity on a pool. Disabling adding liquidity also blocks opening positions, expanding positions and opening limit orders. |
| `update_partner_fee` | Operator with UpdatePartnerFee | Sets `partner_fee_bps` on a pool. Only pools with a partner (dynamic-config pools). |

## Remaining Accounts

Instructions that transfer tokens take a `RemainingAccountsInfo` argument. Its `slices` list `{ accounts_type, length }` entries, and the program consumes that many remaining accounts for each slice in order from the start. `accounts_type` is one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. Each type can appear once, and it must be valid for the instruction. Pass the extra accounts a Token 2022 transfer hook program needs for that leg. Use an empty list for mints without a hook.

Tick arrays follow the transfer hook accounts. They must be writable in every instruction except `refresh_fees_and_rewards`, and in `swap` every remaining account after the hook slices must be a tick array account:

| Instruction | Tick array order |
| - | - |
| `swap` | Swap direction: descending index for `swap_for_y`, ascending otherwise. |
| `add_liquidity`, `add_liquidity_by_weight`, `add_liquidity_imbalance`, `remove_liquidity`, `remove_liquidity_by_bps`, `refresh_fees_and_rewards`, `cancel_limit_order` | Any order. |
| `open_position`, `expand_position`, `remove_position`, `close_position`, `close_limit_order` | Ascending index. |
| `open_limit_order` | Ascending index. With `relative_tick`, any order, including the tick arrays of the slippage range. |

The SDK builders resolve transfer hook accounts, and `quoteExactIn` returns swap tick arrays in traversal order. See the [TypeScript SDK reference](https://docs.meteora.ag/developer-guides/dlmm-pro/typescript-sdk/reference.md) for each builder and [Rust library](https://docs.meteora.ag/developer-guides/dlmm-pro/rust-integration/library.md) for account helpers.

## Delegates

The owner of a position or limit order NFT can approve a delegate on the NFT token account (a Token 2022 `approve` of amount 0, since a non-zero delegated amount fails with `DelegatedAmountNonZero`) and set its permissions with `update_position_delegate_permission` or `update_limit_order_delegate_permission`.

| Account | Permission bits |
| - | - |
| Position | 0 AddLiquidity, 1 RemoveLiquidity, 2 ClaimFee, 3 ClaimReward, 4 UpdatePositionRange |
| Limit order | 0 CancelLimitOrder |

## Instruction Reference

This section lists every callable instruction in the order of the tables above. Each entry gives the arguments, the accounts in IDL order, the remaining accounts, what the program checks and changes, the events, the errors a caller can plausibly hit and the SDK builder.

Conventions used in every entry:

* Token amounts are in atoms, the smallest unit of the mint. Prices are square roots in Q64.64, meaning a `u128` that holds the value times 2^64, and a price is token Y atoms per token X atom. Shares are in basis points, 10000 being 100%. Liquidity is an unscaled integer.
* A slot or timestamp means the unit chosen by the pool `activation_type`: 0 is slots, 1 is unix seconds. Rewards and the dynamic fee always use unix seconds.
* A Token 2022 transfer fee is charged by the token program on every transfer. Amounts that leave a user account, such as `input_amount` and the `max_amount` caps, include the fee, and the program grosses up deposits so the reserve receives exactly the amount it needs. Amounts that a receiver gets, such as `min_amount` bounds and `minimum_output_amount`, are checked after the fee. A reserve or vault pays the full amount and the receiver is credited that amount minus the fee.
* An optional account that you do not need is passed as the program ID `dPro1D5wiqnGMH8vMDG23jh35btTHoWdyqXjqkqxe8n`, which is how Anchor encodes an omitted optional account.
* Account constraints that Anchor checks before the program logic, such as a reserve or mint that does not match the pool, a token account with the wrong mint or authority, or an account owned by the wrong program, fail with Anchor constraint errors, not with the program errors listed. The Errors tables list only program errors.
* `event_authority` and `program` appear on every instruction that emits through event CPI, see [Events](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events.md). `memo_program` is the Memo program, which the program calls only when a receiving Token 2022 account requires incoming transfer memos.
* Delegates are described under [Delegates](#delegates). A delegate that pays out tokens can only pay into the associated token account of the NFT owner, and fails with `IncorrectATA` otherwise.
* Instructions that transfer tokens take a `RemainingAccountsInfo` argument, described under [Remaining Accounts](#remaining-accounts). The errors for it are `MissingRemainingAccountForTransferHook`, `NoTransferHookProgram`, `InvalidRemainingAccountSlice`, `DuplicatedRemainingAccountTypes` and `InsufficientRemainingAccounts`.

The `data` field of `BaseFeeConfigParameters` depends on `base_fee_mode`. Offsets count inside the 31 bytes of `data`, integers are little-endian and unused bytes must be zero. Fee numerators use the denominator 1000000000, so 100000 is 0.01% and 990000000 is 99%. In the formulas, the current point is the current slot or timestamp and `p` is the number of periods passed.

| `base_fee_mode` | Layout of `data` | Rules and fee |
| - | - | - |
| 0 Fixed | `cliff_fee_numerator: u64` at 0 | The numerator is at least 100000 and at most 990000000. The fee is constant. |
| 1 TimeSchedulerLinear | `cliff_fee_numerator: u64` at 0, `period_frequency: u64` at 8, `reduction_factor: u64` at 16, `number_of_period: u16` at 24 | `period_frequency`, `reduction_factor` and `number_of_period` are above 0. `p` is the smaller of `number_of_period` and the whole periods from the activation point, `(current point - activation point) / period_frequency`, and it is `number_of_period` before the activation point. The fee numerator is `cliff_fee_numerator - reduction_factor * p`. It must not go below 0, and at `number_of_period` it must be at least 100000, while `cliff_fee_numerator` is at most 990000000. |
| 2 TimeSchedulerExponential | Same as mode 1 | Same rules as mode 1, with the fee numerator `cliff_fee_numerator * (1 - reduction_factor / 10000)^p`, rounded down. `reduction_factor` is in basis points. 10000 or more fails with MathOverflow, and so does a schedule whose decayed factor rounds down to zero. |
| 3 MarketCapSchedulerLinear | `cliff_fee_numerator: u64` at 0, `reduction_factor: u64` at 8, `sqrt_price_step_bps: u32` at 16, `scheduler_expiration_duration: u32` at 20, `number_of_period: u16` at 24 | `reduction_factor`, `sqrt_price_step_bps`, `scheduler_expiration_duration` and `number_of_period` are above 0. `p` is 0 when the current square root price is at or below the pool initial one. Otherwise it is the smaller of `number_of_period` and `(sqrt_price - init_sqrt_price) * 10000 / init_sqrt_price / sqrt_price_step_bps`, whole numbers. `p` is `number_of_period` before the activation point and after `activation point + scheduler_expiration_duration`, in slots or seconds. The fee and its limits are as in mode 1. |
| 4 MarketCapSchedulerExponential | Same as mode 3 | Same rules as mode 3, with the fee as in mode 2. |

The total swap fee numerator is the base fee plus the variable fee of the dynamic fee, capped at 990000000.

The `data` field of `PoolActivationInfoParameters` depends on `activation_mode`. Offsets count inside the 15 bytes of `data` and integers are little-endian. A pool with two activation slots allows an action only when both slots allow it, except for the whitelisted wallet of that action.

| `activation_mode` | Layout of `data` | Rules |
| - | - | - |
| 0 Open | 15 zero bytes | Allows swaps and liquidity changes at all times. |
| 1 BondingCurve | `is_reach_target: u8` at 0, 6 zero bytes, `target_increase_bps: u64` at 7 | `is_reach_target` is 0 and `target_increase_bps` is above 10000. Swaps are always allowed. Adding and removing liquidity is allowed only after a swap leaves the pool square root price at or above `init_sqrt_price * target_increase_bps / 10000` (the basis points apply to the square root price, so 20000 means four times the initial price), which sets `is_reach_target` to 1 for good. The target price must not exceed the price of the largest tick id that is a multiple of the tick spacing, and `whitelisted_add_liquidity` must be set. |
| 2 TimeBased | `swap_point`, `add_liquidity_point` and `remove_liquidity_point` as 5-byte integers at 0, 5 and 10 | Each action is allowed from its point, in slots or seconds. No point is before the current point, and none is more than 30 days after it. `swap_point` must equal the pool activation point. |

### initialize\_pool\_with\_static\_config

Creates a pool from a `StaticConfig`: the pool account, its two reserve vaults, its oracle and, optionally, its bitmap extension. Anyone can pay for it. The config fixes the fees, tick spacing, collect fee mode, activation type and extensions, and the config pool creator authority must sign unless the config is public.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `initial_sqrt_price` | `u128` | Square root of the initial price, Q64.64, where the price is token Y atoms per token X atom. Between 4295048016 and 79226673515401279992447579055 inclusive, and its tick id must be between -443636 and 443636 inclusive. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | New pool account paid by `payer`. PDA with seeds `"pool"`, `config`, the larger and then the smaller of the two mint addresses by byte order, so the order of the mints does not change the address. Its size follows the config extensions. |
| `token_x_mint` | No | No | Token X mint, owned by `token_x_program`. Must differ from the token Y mint. The Token 2022 native mint is rejected. |
| `token_y_mint` | No | No | Token Y mint, owned by `token_y_program`. Same rules as the token X mint. |
| `config` | No | No | `StaticConfig` the pool is created from. Its `pool_creator_authority` must equal the `pool_creator_authority` account. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Pass it to create the bitmap extension together with the pool. It is required when the tick array index of the initial tick is outside -512 to 511, and optional otherwise. When omitted, pass the program ID as placeholder. PDA with seeds `"bitmap"`, `pool`. |
| `oracle` | Yes | No | New oracle account with one observation, paid by `payer`. PDA with seeds `"oracle"`, `pool`. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `reserve_x` | Yes | No | New token account for token X, owned by the pool authority, created in `token_x_program` and paid by `payer`. PDA with seeds `"reserve"`, `token_x_mint`, `pool`. |
| `reserve_y` | Yes | No | New token account for token Y, owned by the pool authority, created in `token_y_program` and paid by `payer`. PDA with seeds `"reserve"`, `token_y_mint`, `pool`. |
| `token_badge_x` (optional) | No | No | Access registry `TokenBadge` account for the token X mint. Needed when the mint is not supported without a badge (see Checks and Effects). When omitted, pass the program ID as placeholder. |
| `token_badge_y` (optional) | No | No | Access registry `TokenBadge` account for the token Y mint. Needed when the mint is not supported without a badge, and for an `OnlyY` pool whose token Y is not wrapped SOL or USDC. When omitted, pass the program ID as placeholder. |
| `creator` | No | No | Recorded as the pool `creator`. It does not sign and can be any address. On a pool with LiquidityMining it can initialize reward slot 0 and change its authority. |
| `payer` | Yes | Yes | Pays the rent of the pool, oracle, reserves and bitmap extension. |
| `pool_creator_authority` | No | No | Pool creator authority of the config. It must sign unless the config has the default key (all zeros) as its authority, which marks a public config. Pass the default key for a public config. |
| `token_x_program` | No | No | Token program of the token X mint, Token or Token 2022. |
| `token_y_program` | No | No | Token program of the token Y mint, Token or Token 2022. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* Each mint is validated. The Token 2022 native mint always fails. If a token badge is passed for the mint, its `token_mint` must equal the mint and nothing else is checked. Without a badge, wrapped SOL and USDC pass, a mint owned by the Token program passes (a freeze authority is allowed), and a Token 2022 mint passes only when its extensions are limited to transfer fee, metadata pointer, token metadata and a transfer hook that has neither a program nor an authority set.
* The config must name the same `pool_creator_authority` as the account. If it is not the default key, that account must sign, or the call fails.
* The collect fee mode comes from the config. If it is `OnlyY` and token Y is not wrapped SOL or USDC, `token_badge_y` must be passed and its `token_mint` must equal the token Y mint.
* The initial price must be within the sqrt price bounds and have a tick id within the tick bounds.
* Creates the pool, the two reserves and the oracle (one empty observation, which the first swap fills). The pool starts with liquidity 0, current tick from the initial price, token flags 0 for Token and 1 for Token 2022 recorded per mint, and the activation point set as described below. If `tick_array_bitmap_extension` is passed it is created, marked as initialized on the pool and an `EvtInitializeBitmapExtension` log is written.
* The pool copies the fee schedule, tick spacing, collect fee mode, activation type and extensions from the config, and has pool type 0 (Static). The activation point is the current slot or unix timestamp, by the config activation type. Static configs cannot have the ActivationAccess extension, so the pool has no activation rules and no partner. With LiquidityMining the pool has two uninitialized reward slots.
* Rent for all new accounts is charged to `payer`. The config account is only read.

#### Events

[`EvtInitializePool`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializepool) is emitted once the pool is set up. [`EvtInitializeBitmapExtension`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializebitmapextension) is written to the log when `tick_array_bitmap_extension` is passed.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPoolCreatorAuthority` | The config `pool_creator_authority` differs from the account passed, or it is not the default key and the account did not sign. |
| `InvalidParameters` | The initial price is outside the square root price bounds, or its tick id is outside the tick bounds. |
| `UnsupportNativeMintToken2022` | A mint is the Token 2022 native mint. |
| `UnsupportedMint` | A mint is not supported without a badge and no badge was passed (see Checks and Effects). |
| `InvalidTokenBadge` | A passed badge belongs to another mint, or an `OnlyY` pool has a token Y that needs a badge and `token_badge_y` was not passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | The tick array of the initial tick has an index outside -512 to 511 and `tick_array_bitmap_extension` was not passed. |

#### SDK

`client.pool.initializePoolWithStaticConfig`. The builder marks the config pool creator authority as a signer when it is not the default key.

### initialize\_pool\_with\_dynamic\_config

Creates a pool from a `DynamicConfig` with fees, tick spacing, price, activation and extensions chosen by the caller. The config pool creator authority must sign. It becomes the partner of the pool and earns the config partner fee share.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `InitializePoolWithDynamicParameters` | Pool settings chosen by the creator. The fields follow. |
| `parameters.pool_fees` | `PoolFeeParameters` | Fee schedule of the pool. |
| `parameters.pool_fees.base_fee_parameter` | `BaseFeeConfigParameters` | Base fee, 32 bytes in two fields. |
| `parameters.pool_fees.base_fee_parameter.base_fee_mode` | `u8` | Base fee schedule. 0 Fixed, 1 TimeSchedulerLinear, 2 TimeSchedulerExponential, 3 MarketCapSchedulerLinear, 4 MarketCapSchedulerExponential. |
| `parameters.pool_fees.base_fee_parameter.data` | `[u8;31]` | Mode-specific parameters, encoded and validated as in the base fee data table above. Unused bytes must be zero. |
| `parameters.pool_fees.dynamic_fee_parameter` | `Option<DynamicFeeParameters>` | `None` turns the dynamic fee off. `Some` turns it on and the fields below apply. |
| `parameters.pool_fees.dynamic_fee_parameter.max_volatility_accumulator` | `u32` | Cap on the volatility accumulator. At most 16777215. One unit is 1 over 10000 of a tick of price movement from the reference price. |
| `parameters.pool_fees.dynamic_fee_parameter.variable_fee_control` | `u32` | Scale of the variable fee. At most 16777215. The variable fee numerator is the ceiling of `variable_fee_control * volatility_accumulator^2 / 100000000000`, in units of 1 over 1000000000. At the cap it must not exceed 990000000. |
| `parameters.pool_fees.dynamic_fee_parameter.filter_period` | `u16` | Seconds. Must be above 0 and below `decay_period`. Swaps closer than this to the last reference update or significant swap keep the volatility reference unchanged. |
| `parameters.pool_fees.dynamic_fee_parameter.decay_period` | `u16` | Seconds. Must be above `filter_period` and at most 3600. After this long the volatility reference resets to 0. The reference also resets once it is more than 3600 seconds old, even when significant swaps keep arriving. |
| `parameters.pool_fees.dynamic_fee_parameter.reduction_factor` | `u16` | Basis points, 1 to 10000. Between the filter and decay periods the volatility reference becomes the accumulator times this value over 10000. |
| `parameters.pool_fees.dynamic_fee_parameter.min_delta_tick_for_significant_swap` | `u16` | Must be above 0. A swap counts as significant when its price movement, measured in ticks, is at least this value. |
| `parameters.tick_spacing` | `u16` | Distance between usable tick ids. 1 to 256 inclusive. |
| `parameters.collect_fee_mode` | `u8` | 0 OutputToken, the swap fee comes out of the token the trader receives. 1 OnlyY, the swap fee is always in token Y. Any other value fails to convert. |
| `parameters.initial_sqrt_price` | `u128` | Square root of the initial price, Q64.64, where the price is token Y atoms per token X atom. Between 4295048016 and 79226673515401279992447579055 inclusive. |
| `parameters.activation_type` | `u8` | Unit of `activation_point`, scheduler periods, vesting and activation rules. 0 Slot, 1 Timestamp (unix seconds). |
| `parameters.activation_point` | `Option<u64>` | Slot or timestamp at which the pool opens. `None` uses the current slot or timestamp. Must be `None` unless `extensions` has the ActivationAccess bit. |
| `parameters.extensions` | `u8` | Bitmask of pool extensions. Bit 0 LiquidityMining, bit 1 ActivationAccess. Must be 0 to 3. |
| `parameters.pool_activation` | `Option<PoolActivationParameters>` | Activation rules. Must be `Some` when `extensions` has the ActivationAccess bit and `None` otherwise. |
| `parameters.pool_activation.whitelisted_swap` | `Pubkey` | Wallet that is exempt from the activation rules when it signs `swap`. The default key (all zeros) means no wallet. |
| `parameters.pool_activation.whitelisted_add_liquidity` | `Pubkey` | Wallet that is exempt from the activation rules for adding liquidity, matched against the owner of the position or limit order. The default key means no wallet. Must not be the default key when an activation slot uses BondingCurve. |
| `parameters.pool_activation.whitelisted_remove_liquidity` | `Pubkey` | Wallet that is exempt from the activation rules for removing liquidity, matched against the owner of the position or limit order. The default key means no wallet. |
| `parameters.pool_activation.activations` | `[PoolActivationInfoParameters;2]` | Two activation slots. Both must allow an action for it to be allowed. Allowed mode pairs, slot 0 then slot 1: Open and Open, Open and BondingCurve, Open and TimeBased, BondingCurve and TimeBased. |
| `parameters.pool_activation.activations[].activation_mode` | `u8` | 0 Open, 1 BondingCurve, 2 TimeBased. Any other value fails with InvalidActivationAccess. |
| `parameters.pool_activation.activations[].data` | `[u8;15]` | Mode-specific parameters, encoded and validated as in the activation data table above. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | New pool account paid by `payer`. PDA with seeds `"pool"`, `config`, the larger and then the smaller of the two mint addresses by byte order. Its size follows `parameters.extensions`. |
| `token_x_mint` | No | No | Token X mint, owned by `token_x_program`. Must differ from the token Y mint. The Token 2022 native mint is rejected. |
| `token_y_mint` | No | No | Token Y mint, owned by `token_y_program`. Same rules as the token X mint. |
| `config` | No | No | `DynamicConfig` the pool is created from. Its `pool_creator_authority` must equal the `pool_creator_authority` account. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Pass it to create the bitmap extension together with the pool. It is required when the tick array index of the initial tick is outside -512 to 511, and optional otherwise. When omitted, pass the program ID as placeholder. PDA with seeds `"bitmap"`, `pool`. |
| `oracle` | Yes | No | New oracle account with one observation, paid by `payer`. PDA with seeds `"oracle"`, `pool`. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `reserve_x` | Yes | No | New token account for token X, owned by the pool authority, created in `token_x_program` and paid by `payer`. PDA with seeds `"reserve"`, `token_x_mint`, `pool`. |
| `reserve_y` | Yes | No | New token account for token Y, owned by the pool authority, created in `token_y_program` and paid by `payer`. PDA with seeds `"reserve"`, `token_y_mint`, `pool`. |
| `token_badge_x` (optional) | No | No | Access registry `TokenBadge` account for the token X mint. Needed when the mint is not supported without a badge (see Checks and Effects). When omitted, pass the program ID as placeholder. |
| `token_badge_y` (optional) | No | No | Access registry `TokenBadge` account for the token Y mint. Needed when the mint is not supported without a badge, and for an `OnlyY` pool whose token Y is not wrapped SOL or USDC. When omitted, pass the program ID as placeholder. |
| `creator` | No | No | Recorded as the pool `creator`. It does not sign and can be any address. On a pool with LiquidityMining it can initialize reward slot 0 and change its authority. |
| `payer` | Yes | Yes | Pays the rent of the pool, oracle, reserves and bitmap extension. |
| `pool_creator_authority` | No | Yes | Pool creator authority of the config. Signs the transaction and becomes the pool partner. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* Pool fees are validated. The base fee mode must be 0 to 4 and its `data` must pass the checks in the base fee data table. If the dynamic fee is set, its fields must pass the ranges in the argument table, including the check that the variable fee at the cap is at most 990000000.
* `tick_spacing` is 1 to 256, `collect_fee_mode` is 0 or 1, and the initial square root price is within the price bounds.
* `extensions` is at most 3. Without the ActivationAccess bit, `activation_point` and `pool_activation` must be `None`. With it, `pool_activation` must be `Some`, `activation_point` of `None` means the current point, and each slot is validated by its mode as in the activation data table. The slot modes must form an allowed pair. Unless a slot is TimeBased, `activation_point` must be the current point, so pass `None`.
* TimeBased slots must not set any of the three points before the current slot or timestamp, nor more than 2592000 seconds (10368000 slots) after it, and the swap point must equal the activation point. BondingCurve slots need `whitelisted_add_liquidity` to be set, a target above 10000 bps, and a target price at or below the price of the largest spacing-aligned tick id.
* When the collect fee mode is `OnlyY` and token Y is not wrapped SOL or USDC, `token_badge_y` must be passed and its `token_mint` must equal the token Y mint.
* Each mint is validated. The Token 2022 native mint always fails. If a token badge is passed for the mint, its `token_mint` must equal the mint and nothing else is checked. Without a badge, wrapped SOL and USDC pass, a mint owned by the Token program passes (a freeze authority is allowed), and a Token 2022 mint passes only when its extensions are limited to transfer fee, metadata pointer, token metadata and a transfer hook that has neither a program nor an authority set. When the config permission bitmask has bit 0 (CreatePoolWithoutMintValidation), only the native mint rejection remains and badges are not checked for these mints.
* Creates the pool, the two reserves and the oracle (one empty observation, which the first swap fills). The pool starts with liquidity 0, current tick from the initial price, token flags 0 for Token and 1 for Token 2022 recorded per mint, and the activation point set as described below. If `tick_array_bitmap_extension` is passed it is created, marked as initialized on the pool and an `EvtInitializeBitmapExtension` log is written.
* The pool has pool type 1 (Dynamic). The partner is set to `pool_creator_authority` and `partner_fee_bps` is copied from the config, even when it is 0, since an operator can raise it later with `update_partner_fee`. The activation point is `parameters.activation_point`, or the current point when `None`. With ActivationAccess the activation rules are written to the pool tail. With LiquidityMining the pool has two uninitialized reward slots.
* Rent for all new accounts is charged to `payer`. The config account is only read.

#### Events

[`EvtInitializePool`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializepool) is emitted once the pool is set up, with `pool_activation` as passed. [`EvtInitializeBitmapExtension`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializebitmapextension) is written to the log when `tick_array_bitmap_extension` is passed.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPoolCreatorAuthority` | The config `pool_creator_authority` differs from the account passed. |
| `InvalidParameters` | A parameter is out of range, for example the tick spacing, the initial price, a fee parameter, `extensions` above 3, `activation_point` or `pool_activation` set without the ActivationAccess bit, or a missing `pool_activation` with it. |
| `MathOverflow` | A linear fee schedule whose `cliff_fee_numerator` is below `reduction_factor * number_of_period`, or an exponential schedule with a `reduction_factor` of 10000 or more. |
| `InvalidBaseFeeMode` | `base_fee_mode` is not 0 to 4. |
| `TypeCastFailed` | `collect_fee_mode` is not 0 or 1. |
| `InvalidActivationType` | `activation_type` is not 0 or 1. |
| `InvalidActivationAccess` | An `activation_mode` of a slot is not 0 to 2. |
| `UnsupportNativeMintToken2022` | A mint is the Token 2022 native mint. |
| `UnsupportedMint` | A mint is not supported without a badge and no badge was passed (see Checks and Effects). |
| `InvalidTokenBadge` | A passed badge belongs to another mint, or an `OnlyY` pool has a token Y that needs a badge and `token_badge_y` was not passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | The tick array of the initial tick has an index outside -512 to 511 and `tick_array_bitmap_extension` was not passed. |

#### SDK

`client.pool.initializePoolWithDynamicConfig`.

### initialize\_launch\_pool

Creates a launch pool, keyed by its mint pair alone with no config. Anyone can create it by proving with `user_token_x` and `user_token_y` that the payer holds both tokens. Nothing is transferred. The pool has no partner and a 20% protocol share of the market maker fee.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `InitializePoolWithDynamicParameters` | Pool settings chosen by the creator. The fields follow. |
| `parameters.pool_fees` | `PoolFeeParameters` | Fee schedule of the pool. |
| `parameters.pool_fees.base_fee_parameter` | `BaseFeeConfigParameters` | Base fee, 32 bytes in two fields. |
| `parameters.pool_fees.base_fee_parameter.base_fee_mode` | `u8` | Base fee schedule. 0 Fixed, 1 TimeSchedulerLinear, 2 TimeSchedulerExponential, 3 MarketCapSchedulerLinear, 4 MarketCapSchedulerExponential. |
| `parameters.pool_fees.base_fee_parameter.data` | `[u8;31]` | Mode-specific parameters, encoded and validated as in the base fee data table above. Unused bytes must be zero. |
| `parameters.pool_fees.dynamic_fee_parameter` | `Option<DynamicFeeParameters>` | `None` turns the dynamic fee off. `Some` turns it on and the fields below apply. |
| `parameters.pool_fees.dynamic_fee_parameter.max_volatility_accumulator` | `u32` | Cap on the volatility accumulator. At most 16777215. One unit is 1 over 10000 of a tick of price movement from the reference price. |
| `parameters.pool_fees.dynamic_fee_parameter.variable_fee_control` | `u32` | Scale of the variable fee. At most 16777215. The variable fee numerator is the ceiling of `variable_fee_control * volatility_accumulator^2 / 100000000000`, in units of 1 over 1000000000. At the cap it must not exceed 990000000. |
| `parameters.pool_fees.dynamic_fee_parameter.filter_period` | `u16` | Seconds. Must be above 0 and below `decay_period`. Swaps closer than this to the last reference update or significant swap keep the volatility reference unchanged. |
| `parameters.pool_fees.dynamic_fee_parameter.decay_period` | `u16` | Seconds. Must be above `filter_period` and at most 3600. After this long the volatility reference resets to 0. The reference also resets once it is more than 3600 seconds old, even when significant swaps keep arriving. |
| `parameters.pool_fees.dynamic_fee_parameter.reduction_factor` | `u16` | Basis points, 1 to 10000. Between the filter and decay periods the volatility reference becomes the accumulator times this value over 10000. |
| `parameters.pool_fees.dynamic_fee_parameter.min_delta_tick_for_significant_swap` | `u16` | Must be above 0. A swap counts as significant when its price movement, measured in ticks, is at least this value. |
| `parameters.tick_spacing` | `u16` | Distance between usable tick ids. 1 to 256 inclusive. |
| `parameters.collect_fee_mode` | `u8` | 0 OutputToken, the swap fee comes out of the token the trader receives. 1 OnlyY, the swap fee is always in token Y. Any other value fails to convert. |
| `parameters.initial_sqrt_price` | `u128` | Square root of the initial price, Q64.64, where the price is token Y atoms per token X atom. Between 4295048016 and 79226673515401279992447579055 inclusive. |
| `parameters.activation_type` | `u8` | Unit of `activation_point`, scheduler periods, vesting and activation rules. 0 Slot, 1 Timestamp (unix seconds). |
| `parameters.activation_point` | `Option<u64>` | Slot or timestamp at which the pool opens. `None` uses the current slot or timestamp. Must be `None` unless `extensions` has the ActivationAccess bit. |
| `parameters.extensions` | `u8` | Bitmask of pool extensions. Bit 0 LiquidityMining, bit 1 ActivationAccess. Must be 0 to 3. |
| `parameters.pool_activation` | `Option<PoolActivationParameters>` | Activation rules. Must be `Some` when `extensions` has the ActivationAccess bit and `None` otherwise. |
| `parameters.pool_activation.whitelisted_swap` | `Pubkey` | Wallet that is exempt from the activation rules when it signs `swap`. The default key (all zeros) means no wallet. |
| `parameters.pool_activation.whitelisted_add_liquidity` | `Pubkey` | Wallet that is exempt from the activation rules for adding liquidity, matched against the owner of the position or limit order. The default key means no wallet. Must not be the default key when an activation slot uses BondingCurve. |
| `parameters.pool_activation.whitelisted_remove_liquidity` | `Pubkey` | Wallet that is exempt from the activation rules for removing liquidity, matched against the owner of the position or limit order. The default key means no wallet. |
| `parameters.pool_activation.activations` | `[PoolActivationInfoParameters;2]` | Two activation slots. Both must allow an action for it to be allowed. Allowed mode pairs, slot 0 then slot 1: Open and Open, Open and BondingCurve, Open and TimeBased, BondingCurve and TimeBased. |
| `parameters.pool_activation.activations[].activation_mode` | `u8` | 0 Open, 1 BondingCurve, 2 TimeBased. Any other value fails with InvalidActivationAccess. |
| `parameters.pool_activation.activations[].data` | `[u8;15]` | Mode-specific parameters, encoded and validated as in the activation data table above. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | New pool account paid by `payer`. PDA with seeds `"l_pool"`, the larger and then the smaller of the two mint addresses by byte order, so there is one launch pool per pair. Its size follows `parameters.extensions`. |
| `token_x_mint` | No | No | Token X mint, owned by `token_x_program`. Must differ from the token Y mint. The Token 2022 native mint is rejected. |
| `token_y_mint` | No | No | Token Y mint, owned by `token_y_program`. Same rules as the token X mint. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Pass it to create the bitmap extension together with the pool. It is required when the tick array index of the initial tick is outside -512 to 511, and optional otherwise. When omitted, pass the program ID as placeholder. PDA with seeds `"bitmap"`, `pool`. |
| `oracle` | Yes | No | New oracle account with one observation, paid by `payer`. PDA with seeds `"oracle"`, `pool`. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `reserve_x` | Yes | No | New token account for token X, owned by the pool authority, created in `token_x_program` and paid by `payer`. PDA with seeds `"reserve"`, `token_x_mint`, `pool`. |
| `reserve_y` | Yes | No | New token account for token Y, owned by the pool authority, created in `token_y_program` and paid by `payer`. PDA with seeds `"reserve"`, `token_y_mint`, `pool`. |
| `token_badge_x` (optional) | No | No | Access registry `TokenBadge` account for the token X mint. Needed when the mint is not supported without a badge (see Checks and Effects). When omitted, pass the program ID as placeholder. |
| `token_badge_y` (optional) | No | No | Access registry `TokenBadge` account for the token Y mint. Needed when the mint is not supported without a badge, and for an `OnlyY` pool whose token Y is not wrapped SOL or USDC. When omitted, pass the program ID as placeholder. |
| `creator` | No | No | Recorded as the pool `creator`. It does not sign and can be any address. On a pool with LiquidityMining it can initialize reward slot 0 and change its authority. |
| `payer` | Yes | Yes | Pays the rent of the pool, oracle, reserves and bitmap extension. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `user_token_x` | No | No | Token account of the payer for token X. Its authority must be `payer` and its mint the token X mint. The balance must be above 0. Only read. |
| `user_token_y` | No | No | Token account of the payer for token Y. Same rules as `user_token_x`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* Both `user_token_x` and `user_token_y` must have a balance above 0.
* Pool fees are validated. The base fee mode must be 0 to 4 and its `data` must pass the checks in the base fee data table. If the dynamic fee is set, its fields must pass the ranges in the argument table, including the check that the variable fee at the cap is at most 990000000.
* `tick_spacing` is 1 to 256, `collect_fee_mode` is 0 or 1, and the initial square root price is within the price bounds.
* `extensions` is at most 3. Without the ActivationAccess bit, `activation_point` and `pool_activation` must be `None`. With it, `pool_activation` must be `Some`, `activation_point` of `None` means the current point, and each slot is validated by its mode as in the activation data table. The slot modes must form an allowed pair. Unless a slot is TimeBased, `activation_point` must be the current point, so pass `None`.
* TimeBased slots must not set any of the three points before the current slot or timestamp, nor more than 2592000 seconds (10368000 slots) after it, and the swap point must equal the activation point. BondingCurve slots need `whitelisted_add_liquidity` to be set, a target above 10000 bps, and a target price at or below the price of the largest spacing-aligned tick id.
* When the collect fee mode is `OnlyY` and token Y is not wrapped SOL or USDC, `token_badge_y` must be passed and its `token_mint` must equal the token Y mint.
* Each mint is validated. The Token 2022 native mint always fails. If a token badge is passed for the mint, its `token_mint` must equal the mint and nothing else is checked. Without a badge, wrapped SOL and USDC pass, a mint owned by the Token program passes (a freeze authority is allowed), and a Token 2022 mint passes only when its extensions are limited to transfer fee, metadata pointer, token metadata and a transfer hook that has neither a program nor an authority set. No wallet or config can skip this validation.
* Creates the pool, the two reserves and the oracle (one empty observation, which the first swap fills). The pool starts with liquidity 0, current tick from the initial price, token flags 0 for Token and 1 for Token 2022 recorded per mint, and the activation point set as described below. If `tick_array_bitmap_extension` is passed it is created, marked as initialized on the pool and an `EvtInitializeBitmapExtension` log is written.
* The pool has pool type 2 (LaunchPool). It has no partner, and the protocol takes 20% of the market maker fee instead of 10%. The activation point is `parameters.activation_point`, or the current point when `None`. \[Open, Open] is accepted. LiquidityMining and ActivationAccess are both available.
* Rent for all new accounts is charged to `payer`.

#### Events

[`EvtInitializePool`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializepool) is emitted once the pool is set up. [`EvtInitializeBitmapExtension`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializebitmapextension) is written to the log when `tick_array_bitmap_extension` is passed.

#### Errors

| Error | Cause |
| - | - |
| `InvalidTokenOwnerProof` | `user_token_x` or `user_token_y` has a balance of 0. |
| `InvalidParameters` | A parameter is out of range, for example the tick spacing, the initial price, a fee parameter, `extensions` above 3, `activation_point` or `pool_activation` set without the ActivationAccess bit, or a missing `pool_activation` with it. |
| `MathOverflow` | A linear fee schedule whose `cliff_fee_numerator` is below `reduction_factor * number_of_period`, or an exponential schedule with a `reduction_factor` of 10000 or more. |
| `InvalidBaseFeeMode` | `base_fee_mode` is not 0 to 4. |
| `TypeCastFailed` | `collect_fee_mode` is not 0 or 1. |
| `InvalidActivationType` | `activation_type` is not 0 or 1. |
| `InvalidActivationAccess` | An `activation_mode` of a slot is not 0 to 2. |
| `UnsupportNativeMintToken2022` | A mint is the Token 2022 native mint. |
| `UnsupportedMint` | A mint is not supported without a badge and no badge was passed (see Checks and Effects). |
| `InvalidTokenBadge` | A passed badge belongs to another mint, or an `OnlyY` pool has a token Y that needs a badge and `token_badge_y` was not passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | The tick array of the initial tick has an index outside -512 to 511 and `tick_array_bitmap_extension` was not passed. |

#### SDK

`client.pool.initializeLaunchPool`.

### swap

Exact-in swap. The caller pays exactly `input_amount` of one token and receives the other, walking the tick arrays passed in swap direction. Anyone can call it, unless the pool activation rules limit swaps to a whitelisted wallet.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `SwapParameters` | Swap amounts. The fields follow. |
| `parameters.input_amount` | `u64` | Exact amount taken from `user_token_in`, in atoms, before any Token 2022 transfer fee of the input mint. Must be above 0. The pool receives this amount minus the input transfer fee, and the trading fee comes out of that when the fee is on the input. |
| `parameters.minimum_output_amount` | `u64` | Least amount the user must receive, in atoms, after the Token 2022 transfer fee of the output mint. 0 turns the check off. |
| `remaining_accounts_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX`, `TransferHookY` and `TransferHookReferral`. |
| `remaining_accounts_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_accounts_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX`, `TransferHookY` and `TransferHookReferral`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_accounts_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Its price, current tick, liquidity, fee growth, protocol fee, partner fee and dynamic fee state change. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when the walk crosses tick arrays outside indexes -512 to 511, or when the current tick array is outside them. When omitted, pass the program ID as placeholder. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `user_token_in` | Yes | No | Token account of the user for the input token. The signer must be its authority or delegate. The direction of the swap is not read from it. |
| `user_token_out` | Yes | No | Token account of the user for the output token. Its mint decides the direction: token Y gives `swap_for_y` (token X in), token X gives the opposite. |
| `referral` (optional) | Yes | No | Token account that receives the host fee. It can be any token account, including the user own. It must hold the fee token (token Y for `OnlyY`, otherwise the output token of the swap). When omitted, pass the program ID as placeholder and no host fee is paid. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `oracle` | Yes | No | Oracle of the pool. A new observation is written or the latest is updated. |
| `user` | No | Yes | Signs the swap and is the authority of `user_token_in`. It is also the wallet checked against `whitelisted_swap`. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

First the transfer hook slices from `remaining_accounts_info`: `TransferHookX`, `TransferHookY` and `TransferHookReferral` are accepted. The hook of the input mint is used for the transfer into the reserve, the hook of the output mint for the payment to the user, and the referral slice for the host fee payment.

Then the tick arrays, all writable, in swap direction: descending tick array index when swapping token X for token Y (`swap_for_y`), ascending otherwise. Every remaining account after the hook slices must be a tick array account. The program starts at the tick array that holds the current tick or the next one with liquidity and skips passed accounts that are not the next array with liquidity in direction. Pass the arrays of a quote whose `amountLeft` is 0.

#### Checks and Effects

* `input_amount` must be above 0.
* The pool must have swaps enabled in `pool_status`, and when the pool has ActivationAccess every activation slot must allow swaps at the current slot or timestamp, unless the signer is `whitelisted_swap`. Open allows always, BondingCurve allows always, TimeBased allows from its swap point.
* The input transfer fee is taken off `input_amount` first. If the fee is on the input (collect fee mode `OnlyY` and token Y in, see below), the trading fee is charged step by step and rounded up in each step: a step that ends at a tick with input left grosses the fee up from the amount it consumed, and the last step takes the fee from the input that remains. The walk consumes the input tick by tick. At each tick it fills the market maker liquidity of the range first and then, with the input left, the limit orders of that tick at the tick price, processed orders before open orders. Amounts out are rounded down, and amounts in are rounded up.
* The fee token follows the collect fee mode. With `OutputToken`, the fee is taken from the output side, so token Y when swapping X for Y and token X otherwise. With `OnlyY`, token Y is the fee token: it is taken from the output when swapping X for Y and from the input when swapping Y for X. When the fee is on the output it is rounded up and taken from the output of each step before the output transfer fee.
* The trading fee numerator is the base fee at the current slot or timestamp and price, plus the variable fee of the dynamic fee state, capped at 990000000, over 1000000000. The dynamic fee volatility state is updated before the walk and again after it.
* The fee is split between the market maker side and the limit order side by the share of the fill each one provided. The protocol takes 10% of the market maker part (20% on a launch pool) and 50% of the limit order part. Two edge cases: when the limit order fill of a step rounds down to zero output, the protocol takes the whole limit order part of that step, and when a step fills nothing at all, the protocol takes the whole fee of that step. If a referral account is passed, the host fee is 20% of the protocol fee, where the limit order part of the protocol fee counts at no more than the market maker protocol rate. The host fee is paid from the reserve to `referral`. If the pool has a partner and `partner_fee_bps` is above 0, the partner takes that share of the protocol fee left after the host fee. The protocol fee left accrues in `protocol_fee_x` or `protocol_fee_y` and the partner fee in the pending partner fee of the fee token. The market maker part left after the protocol fee accrues to liquidity providers through the fee growth of the fee token, and the limit order part left accrues to the filled limit orders of the tick.
* The walk must consume the whole input after the transfer fee and the trading fee. If the tick arrays run out first, the call fails with NotConsumingFullAmountIn. If the pool has no tick array with liquidity in the swap direction, it fails with LiquidityIsZero.
* The output transfer fee is taken off the output. `minimum_output_amount` is checked against the amount after that fee. The pool sends the full output to the user, the user receives it minus the transfer fee, and the host fee is paid from the reserve to `referral` before it.
* The price, current tick id and liquidity of the pool are updated, ticks crossed update their outside fee growth and reward growth, tick arrays that become empty or non-empty flip their bits in the pool bitmap (or extension), rewards are accrued up to now on LiquidityMining pools, and BondingCurve activation slots mark their target as reached once the price has risen to the target.
* The oracle is updated with the tick before the swap. The first swap starts it. A new observation is written when at least 15 seconds have passed since the last one was created, otherwise the latest observation is updated.

#### Events

[`EvtSwap`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtswap) is emitted with the amounts in and out, transfer fees and the fee split. `amount_in` is `input_amount` and `amount_out` is after the output transfer fee.

#### Errors

| Error | Cause |
| - | - |
| `AmountIsZero` | `input_amount` is 0. |
| `InvalidActivationAccess` | Swaps are disabled in `pool_status`, or the activation rules do not allow swaps yet for this signer. |
| `LiquidityIsZero` | The pool has no tick array with liquidity in the swap direction. |
| `NotConsumingFullAmountIn` | The tick arrays passed ran out of liquidity before `input_amount` was consumed, or the arrays passed are not in direction order. |
| `ExceededSlippage` | The output after the output transfer fee is below `minimum_output_amount`. |
| `BitmapExtensionAccountIsNotProvided` | The pool has an initialized bitmap extension, the search leaves the inline bitmap and the extension was not passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 changes between empty and non-empty and the extension was not passed. |
| `InvalidTickArray` | The tick array account that the walk expects next belongs to another pool. |
| `MathOverflow` | An amount overflows during the calculation, for example a very large input at an extreme price. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

`client.pool.swap`, with `client.pool.quoteExactIn` to choose the tick arrays.

### initialize\_tick\_array

Creates the tick array account of one tick array index with no ticks. Anyone can call it. It does nothing when the account already exists.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `index` | `i32` | Tick array index. The array covers tick ids from `index * 128 * tick_spacing` through `(index + 1) * 128 * tick_spacing - 1`. At least one spacing-aligned tick id of the array must be between -443636 and 443636. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool the tick array belongs to. Only read, it supplies the tick spacing and the extensions. |
| `tick_array` | Yes | No | Tick array account to create. PDA with seeds `"tick_array"`, `pool`, `index` (i32 little-endian). |
| `funder` | Yes | Yes | Pays the rent of the new tick array. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* At least one usable tick id of the array lies within the tick bounds.
* If the account does not exist, creates it with the fixed header only (pool and index, 64 bytes including the discriminator) and charges the minimum rent to `funder`. The size of a tick, which is larger on a LiquidityMining pool, only matters when ticks are added later. If it exists, nothing changes and no event is emitted.
* Ticks are added later by `open_position`, `expand_position` and `open_limit_order`, which also create the tick array when it is missing, so this instruction is optional.

#### Events

[`EvtInitializeTickArray`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializetickarray) is emitted only when the account is created.

#### Errors

| Error | Cause |
| - | - |
| `InvalidParameters` | The array has no usable tick id within the tick bounds. |
| `MathOverflow` | `index` is so large that its tick ids do not fit in an `i32`. |

#### SDK

`client.pool.initializeTickArray`.

### initialize\_tick\_bitmap\_extension

Creates the bitmap extension of a pool, which tracks tick arrays outside indexes -512 to 511. Anyone can call it. It does nothing when the pool already has one.

#### Arguments

This instruction takes no arguments.

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Its extension flag is set. |
| `tick_array_bitmap_extension` | Yes | No | Bitmap extension account to create. PDA with seeds `"bitmap"`, `pool`. |
| `funder` | Yes | Yes | Pays the rent of the bitmap extension. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |

#### Checks and Effects

* If the pool has no extension yet, creates the account, marks the pool as having one and writes an `EvtInitializeBitmapExtension` log. Otherwise nothing changes.
* Instructions that touch tick arrays outside -512 to 511 need this account. Pool creation can create it at the same time when the initial tick is outside the inline range.

#### Events

[`EvtInitializeBitmapExtension`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializebitmapextension) is written to the log only when the account is created. This instruction has no event authority account.

#### Errors

This instruction checks no arguments, so it returns no program error from the IDL. Anchor account validation errors can still occur, for example when `tick_array_bitmap_extension` is not the address derived for the pool.

#### SDK

`client.pool.initializeTickBitmapExtension`.

### increase\_oracle\_length

Grows the oracle ring buffer of a pool by `length_to_add` observations. Anyone can call it and the payer funds the extra rent.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `length_to_add` | `u16` | Number of observations to add. Must be above 0, and the new total must be at most 500. A new oracle holds 1 observation. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `oracle` | Yes | No | Oracle to grow. It is reallocated and topped up to the new rent-exempt minimum. |
| `payer` | Yes | Yes | Pays the extra rent. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* `length_to_add` is above 0 and the new length is at most 500.
* When the ring buffer has wrapped, the observations are rotated so that the oldest is first and the newest last, and the index moves to the newest, so history keeps its order. New empty observations are appended after it.
* The account grows by 16 bytes per observation and `payer` transfers the difference to reach the rent-exempt minimum of the new size.

#### Events

[`EvtIncreaseOracleLength`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtincreaseoraclelength) is emitted with the old and new lengths.

#### Errors

| Error | Cause |
| - | - |
| `InvalidParameters` | `length_to_add` is 0, or the new total length is above 500. |

#### SDK

`client.pool.increaseOracleLength`.

### open\_position

Mints a position NFT to `owner` and creates the position array with one empty range slot per entry of `tick_ranges`. Anyone can call it: the payer and the new NFT mint sign, and the owner does not need to sign. No liquidity is added.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `OpenPositionParameters` | Ranges of the new position. The fields follow. |
| `parameters.tick_ranges` | `Vec<TickRange>` | Range slots to create, 1 to 45 entries. Ranges may overlap, so one position can hold several shapes. |
| `parameters.tick_ranges[].tick_lower_id` | `i32` | Lower tick id of the range slot. Must be a multiple of the pool tick spacing, between -443636 and 443636 inclusive, and below `tick_upper_id`. |
| `parameters.tick_ranges[].tick_upper_id` | `i32` | Upper tick id of the range slot. Same rules as `tick_lower_id`. Liquidity covers ticks from `tick_lower_id` up to but excluding `tick_upper_id`. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read. It must allow adding liquidity for `owner`. |
| `pool_authority` | No | No | Mint authority and close authority of the NFT mint. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `nft_mint` | Yes | Yes | New Token 2022 mint of the position NFT, a fresh keypair that signs. Created with 0 decimals, the pool authority as mint authority, the pool as freeze authority, and its token metadata stored in the mint. |
| `nft_account` | Yes | No | Token account of `owner` for the NFT, created by this instruction and paid by `payer`. Associated token account of `owner` for `nft_mint` under Token 2022. |
| `position` | Yes | No | New position array account paid by `payer`. It holds one slot per range, in the reward variant when the pool has LiquidityMining. PDA with seeds `"position"`, `nft_mint`. |
| `owner` | No | No | Receives the NFT and owns the position. Does not sign. |
| `payer` | Yes | Yes | Pays the rent of the NFT mint, the NFT token account, the position array, and the tick arrays and ticks it needs. |
| `token_program` | No | No | Token 2022 program. Fixed address `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `associated_token_program` | No | No | Associated token account program. Fixed address `ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Tick arrays, all writable, one per distinct tick array index that holds a lower or upper tick id of the new ranges, in ascending index order with no duplicates and no other accounts in between. A missing array is created at its derived address, so pass the address even when the account does not exist yet. An existing array must belong to the pool and carry the expected index.

#### Checks and Effects

* The pool must have adding liquidity enabled in `pool_status`, and with ActivationAccess every activation slot must allow adding liquidity at the current point, unless `owner` is `whitelisted_add_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its add liquidity point.
* Each range needs lower below upper, both multiples of the pool tick spacing and within -443636 to 443636. There are 1 to 45 ranges. Overlapping and repeated ranges are allowed.
* Creates the position array with slots in the order given, each with zero liquidity, `layout_version` 0 and `delegate_permission` 0. Mints exactly 1 of the NFT to `owner`.
* `payer` pays the rent of one tick entry per reference, which is every lower and upper tick id of every range, even when ranges share a tick. Missing tick arrays are created and tick arrays grow to hold new ticks. Each tick keeps a reference count that goes up by one per use. The same rent returns to the `rent_receiver` of `remove_position` or `close_position`. `payer` also pays the rent-exempt minimum of each tick array this call creates. Tick arrays are never closed, so that part is not refunded.
* No tokens move, the pool state does not change, and no `EvtInitializeTickArray` is emitted for tick arrays created here.

#### Events

[`EvtOpenPosition`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtopenposition) is emitted with the ranges.

#### Errors

| Error | Cause |
| - | - |
| `InvalidParameters` | No range or more than 45, a lower tick id not below the upper, a tick id that is not a multiple of the tick spacing or is outside -443636 to 443636. |
| `InvalidActivationAccess` | Adding liquidity is disabled in `pool_status`, or the activation rules do not allow it yet for the owner. |
| `InvalidTickArray` | A tick array is missing from the remaining accounts, is not at its derived address, or belongs to another pool or index. |
| `ReallocExceedMaxLengthPerInstruction` | New ticks would grow one tick array by more than 10240 bytes in one instruction. |

#### SDK

`client.position.openPosition`. The `nftMint` keypair must co-sign the transaction.

### expand\_position

Appends empty range slots to a position. The NFT owner can call it, or a delegate with the UpdatePositionRange permission. The payer funds the extra rent and does not need to be the owner.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `OpenPositionParameters` | Ranges to append. The fields follow. |
| `parameters.tick_ranges` | `Vec<TickRange>` | Range slots to append, 1 to 45 entries, and at most 45 slots in the position after the call. Ranges may overlap. |
| `parameters.tick_ranges[].tick_lower_id` | `i32` | Lower tick id of the range slot. Must be a multiple of the pool tick spacing, between -443636 and 443636 inclusive, and below `tick_upper_id`. |
| `parameters.tick_ranges[].tick_upper_id` | `i32` | Upper tick id of the range slot. Same rules as `tick_lower_id`. Liquidity covers ticks from `tick_lower_id` up to but excluding `tick_upper_id`. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read. It must allow adding liquidity for the NFT owner. |
| `position` | Yes | No | Position array to grow. It is reallocated to the new slot count. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the NFT mint stored in `position`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with UpdatePositionRange. |
| `payer` | Yes | Yes | Pays the rent for the larger position array and for tick arrays and ticks the new ranges need. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Tick arrays, all writable, one per distinct tick array index that holds a lower or upper tick id of the appended ranges, in ascending index order with no duplicates and no other accounts in between. A missing array is created at its derived address, so pass the address even when the account does not exist yet. An existing array must belong to the pool and carry the expected index.

#### Checks and Effects

* The signer must be the NFT owner, or the delegate of the NFT token account with a zero delegated amount and the UpdatePositionRange permission bit.
* The pool must have adding liquidity enabled in `pool_status`, and with ActivationAccess every activation slot must allow adding liquidity at the current point, unless the NFT owner is `whitelisted_add_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its add liquidity point.
* The new ranges follow the same rules as in `open_position`, and the slot count after the call must not exceed 45.
* New slots are added after the existing ones, so existing slot indexes do not change. `layout_version` goes up by 1.
* The position array grows and `payer` tops it up to the rent-exempt minimum of the new size. `payer` pays the rent of one tick entry per reference, which is every lower and upper tick id of every range, even when ranges share a tick. Missing tick arrays are created and tick arrays grow to hold new ticks. Each tick keeps a reference count that goes up by one per use. The same rent returns to the `rent_receiver` of `remove_position` or `close_position`. `payer` also pays the rent-exempt minimum of each tick array this call creates. Tick arrays are never closed, so that part is not refunded.

#### Events

[`EvtExpandPosition`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtexpandposition) is emitted with the appended ranges.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `InvalidParameters` | No range or more than 45, more than 45 slots in the position after the call, a lower tick id not below the upper, a tick id that is not a multiple of the tick spacing or is outside -443636 to 443636. |
| `InvalidActivationAccess` | Adding liquidity is disabled in `pool_status`, or the activation rules do not allow it yet for the owner. |
| `InvalidTickArray` | A tick array is missing from the remaining accounts, is not at its derived address, or belongs to another pool or index. |
| `ReallocExceedMaxLengthPerInstruction` | New ticks would grow one tick array by more than 10240 bytes in one instruction. |

#### SDK

`client.position.expandPosition`.

### remove\_position

Removes empty range slots selected by a bitmap and refunds their rent. The NFT owner can call it, or a delegate with the UpdatePositionRange permission. At least one slot must remain.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `RemovePositionParameters` | Slots to remove. The fields follow. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |
| `parameters.bitmap` | `u64` | Bit i selects slot i for removal. At least one bit must be set, no bit may be at or above the slot count, and the set bits must be fewer than the slot count. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read. |
| `position` | Yes | No | Position array to shrink. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the NFT mint stored in `position`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with UpdatePositionRange. |
| `rent_receiver` | Yes | No | Receives the refunded rent of the removed slots and of their tick references. A delegate must name the owner of the NFT token account here. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Tick arrays, all writable, one per distinct tick array index that holds a lower or upper tick id of the removed ranges, in ascending index order with no duplicates and no other accounts in between.

#### Checks and Effects

* The signer must be the NFT owner, or the delegate with a zero delegated amount and the UpdatePositionRange permission. A delegate must set `rent_receiver` to the owner of the NFT token account.
* Removing liquidity cannot be disabled in `pool_status`. With ActivationAccess every activation slot must allow removing at the current point unless the NFT owner is `whitelisted_remove_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its remove liquidity point.
* `expected_layout_version`, when set, must match. The bitmap must be valid as described in the argument table.
* Every selected slot must be empty: no unlocked, permanently locked or vesting liquidity, no pending fees and no pending rewards.
* The remaining slots keep their relative order and move down to fill the gaps, so slot indexes change. `layout_version` goes up by 1.
* The position array shrinks and the lamports above the new rent-exempt minimum go to `rent_receiver`. The reference of each removed tick is dropped, ticks without references leave their tick arrays, and the matching tick rent also goes to `rent_receiver`.

#### Events

[`EvtRemovePosition`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtremoveposition) is emitted with the bitmap and the removed ranges.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position permission bits do not include UpdatePositionRange, or the signer is a delegate and `rent_receiver` is not the owner of the NFT token account. |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `InvalidParameters` | The bitmap is empty, selects a slot beyond the slot count, or selects every slot. |
| `PositionIsNotEmpty` | A selected slot still has liquidity, pending fees or pending rewards. |
| `InvalidActivationAccess` | The activation rules do not allow removing liquidity yet for the owner. |
| `InvalidTickArray` | A tick array is missing, has the wrong index or belongs to another pool. |

#### SDK

`client.position.removePosition`. The builder rejects a delegate that does not name the owner as `rentReceiver`.

### close\_position

Closes a position whose slots are all empty. Only the NFT owner can call it. It burns the NFT, closes the NFT token account, the NFT mint and the position array, and sends all freed rent to `rent_receiver`.

#### Arguments

This instruction takes no arguments.

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `nft_mint` | Yes | No | Mint of the position NFT. Must equal `position.nft_mint`. It is closed. |
| `nft_account` | Yes | No | Token account of the owner that holds the NFT. It is burned from and closed. |
| `pool` | No | No | The pool. Only read. |
| `position` | Yes | No | Position array to close. It is closed and its lamports go to `rent_receiver`. |
| `pool_authority` | No | No | Pool authority, the close authority of the NFT mint. It signs the closing of the mint and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `rent_receiver` | Yes | No | Receives the rent of the position array, the NFT token account, the NFT mint and the tick references. |
| `owner` | No | Yes | Signs. Must be the authority of `nft_account`. |
| `token_program` | No | No | Token 2022 program. Fixed address `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Tick arrays, all writable, one per distinct tick array index that holds a lower or upper tick id of any slot of the position, in ascending index order with no duplicates and no other accounts in between.

#### Checks and Effects

* Every slot must be empty: no liquidity of any kind, no pending fees and no pending rewards. Claim and remove first.
* Pause and activation rules do not apply: an owner can always close.
* Burns the 1 NFT, closes the NFT token account and the NFT mint (the pool authority signs for the mint), and closes the position array. The rent of all three goes to `rent_receiver`.
* Drops the reference of every tick of the position. Ticks without references leave their tick arrays, the arrays shrink, and the rent paid for those ticks goes to `rent_receiver`.

#### Events

[`EvtClosePosition`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtcloseposition) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `PositionIsNotEmpty` | A slot still has liquidity, pending fees or pending rewards. |
| `InvalidTickArray` | A tick array is missing, has the wrong index or belongs to another pool. |

#### SDK

`client.position.closePosition`.

### update\_position\_delegate\_permission

Sets the permission bitmask that the NFT delegate has on a position. Only the NFT owner can call it.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `permission` | `u32` | Bitmask, 0 to 31. Bit 0 AddLiquidity, 1 RemoveLiquidity, 2 ClaimFee, 3 ClaimReward, 4 UpdatePositionRange. 0 removes all permissions. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `position` | Yes | No | Position array that stores the bitmask. |
| `nft_account` | No | No | Token account that holds the NFT. Its authority must be `owner`. |
| `owner` | No | Yes | Signs. Must be the authority of `nft_account`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* `permission` is at most 31.
* Stores the bitmask on the position array. It does not approve a delegate: the owner does that with a Token 2022 `approve` of amount 0 on the NFT token account. A delegate with a non-zero delegated amount fails every delegated call.
* The bitmask stays on the position when the NFT moves, so a new owner and the delegate they approve inherit it until it is changed.

#### Events

[`EvtUpdatePositionDelegatePermission`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtupdatepositiondelegatepermission) is emitted with the permission and the current delegate of the NFT token account, if any.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPermission` | `permission` is above 31. |

#### SDK

`client.position.updatePositionDelegatePermission`.

### add\_liquidity

Deposits chosen liquidity amounts into selected range slots of a position, paying both tokens as needed. The NFT owner can call it, or a delegate with the AddLiquidity permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `AddLiquidityParameters` | Deposit request. The fields follow. |
| `parameters.max_amount_x` | `u64` | Most token X to take from `user_token_x`, in atoms, including the Token 2022 transfer fee of mint X. Set it above the quote to leave headroom for price movement. |
| `parameters.max_amount_y` | `u64` | Most token Y to take from `user_token_y`, in atoms, including the Token 2022 transfer fee of mint Y. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |
| `parameters.bitmap` | `u64` | Bit i selects position slot i. The number of set bits must equal the number of entries in `liquidities`, and no bit may be at or above the slot count. |
| `parameters.liquidities` | `Vec<u128>` | Liquidity to add per selected slot, as unscaled integers, in ascending slot order. Each must be above 0 and at most 170141183460469231731687303715884105727. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Its liquidity changes when a selected range contains the current tick, and rewards are accrued. |
| `position` | Yes | No | Position array to modify. Its `pool` field must equal `pool`. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when a tick array outside indexes -512 to 511 changes between empty and non-empty. When omitted, pass the program ID as placeholder. |
| `user_token_x` | Yes | No | Token account that pays token X, for the token X mint. The `signer` must be its authority. |
| `user_token_y` | Yes | No | Token account that pays token Y, for the token Y mint. The `signer` must be its authority. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with AddLiquidity. It pays the tokens, so it must also be the authority of `user_token_x` and `user_token_y`. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_account_info` argument, then tick arrays. `TransferHookX` and `TransferHookY` are accepted. The tick arrays are all writable, in any order, and every account after the hook slices must be a tick array of the pool. Pass the arrays that hold the lower and upper tick id of every selected slot.

#### Checks and Effects

* The position must exist for the NFT: `nft_account` holds 1 of the position NFT. The signer must be the NFT owner, or a delegate of the token account with a zero delegated amount and the AddLiquidity permission.
* The pool must have adding liquidity enabled in `pool_status`, and with ActivationAccess every activation slot must allow adding liquidity at the current point, unless the NFT owner is `whitelisted_add_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its add liquidity point.
* `expected_layout_version`, when set, must match the position layout version.
* For each selected slot the position and its ticks are brought up to date first: released vesting liquidity becomes unlocked, and fees and rewards are accrued to the position. Then the liquidity is added to the slot unlocked liquidity and to the gross liquidity of its two ticks. The net liquidity of the lower tick goes up by the same amount and the net liquidity of the upper tick goes down by it. A tick cannot hold more gross liquidity than the largest `u128` divided by the number of ticks of the pool.
* Pool liquidity increases only by the liquidity of slots whose range contains the current tick, meaning lower tick id at or below it and upper tick id above it.
* Token amounts follow the current price: only token X when the price is below the range, only token Y when above, both when inside. Each amount is rounded up and summed over the slots. The program then adds the Token 2022 transfer fee of each mint, so that the reserve receives exactly the required amount. The fee-included total must not exceed the matching `max_amount`. Nothing is paid for a token whose total is 0.
* Tick arrays that change between holding no liquidity and holding some flip their bit in the pool bitmap, or in the extension for indexes outside -512 to 511.

#### Events

[`EvtAddLiquidity`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtaddliquidity) is emitted with the amounts paid, which include the transfer fee, and the pool price at execution.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `InvalidParameters` | `bitmap` and `liquidities` do not match: empty list, a count different from the set bits, or a bit at or above the slot count. |
| `LiquidityIsZero` | A selected liquidity is 0. |
| `LiquidityIsTooHigh` | A liquidity is above the largest signed 128-bit value, or a tick would exceed the gross liquidity limit. |
| `ExceededSlippage` | The transfer-fee-included amount of token X or Y is above `max_amount_x` or `max_amount_y`. |
| `InvalidActivationAccess` | Adding liquidity is disabled in `pool_status`, or the activation rules do not allow it yet for the NFT owner. |
| `InvalidTickArray` | A remaining account after the hook slices belongs to another pool. |
| `CannotFindTickFromId` | A tick of a selected slot is not in any tick array passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 flips and `tick_array_bitmap_extension` was not passed. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |
| `TypeCastFailed` | The token X or Y amount for a selected liquidity does not fit in a `u64`. |

#### SDK

`client.position.addLiquidity`.

### add\_liquidity\_by\_weight

Like `add_liquidity`, but each slot liquidity is given as a weight times a shared multiplier. The NFT owner can call it, or a delegate with the AddLiquidity permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `AddLiquidityByWeightParameters` | Deposit request. The fields follow. |
| `parameters.max_amount_x` | `u64` | Most token X to take from `user_token_x`, in atoms, including the Token 2022 transfer fee of mint X. |
| `parameters.max_amount_y` | `u64` | Most token Y to take from `user_token_y`, in atoms, including the Token 2022 transfer fee of mint Y. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |
| `parameters.bitmap` | `u64` | Bit i selects position slot i. The number of set bits must equal the number of entries in `liquidities`, and no bit may be at or above the slot count. |
| `parameters.multiplier` | `u128` | Liquidity per unit of weight. The liquidity of a slot is `multiplier * weight`, which fails when it overflows `u128`. |
| `parameters.liquidities` | `bytes` | One `u8` weight per selected slot, in ascending slot order. A weight of 0 gives liquidity 0 and fails. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Its liquidity changes when a selected range contains the current tick, and rewards are accrued. |
| `position` | Yes | No | Position array to modify. Its `pool` field must equal `pool`. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when a tick array outside indexes -512 to 511 changes between empty and non-empty. When omitted, pass the program ID as placeholder. |
| `user_token_x` | Yes | No | Token account that pays token X, for the token X mint. The `signer` must be its authority. |
| `user_token_y` | Yes | No | Token account that pays token Y, for the token Y mint. The `signer` must be its authority. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with AddLiquidity. It pays the tokens, so it must also be the authority of `user_token_x` and `user_token_y`. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_account_info` argument, then tick arrays. `TransferHookX` and `TransferHookY` are accepted. The tick arrays are all writable, in any order, and every account after the hook slices must be a tick array of the pool. Pass the arrays that hold the lower and upper tick id of every selected slot.

#### Checks and Effects

* Each liquidity is `multiplier * weight`, then the call behaves exactly as `add_liquidity` with those liquidities.
* The position must exist for the NFT: `nft_account` holds 1 of the position NFT. The signer must be the NFT owner, or a delegate of the token account with a zero delegated amount and the AddLiquidity permission.
* The pool must have adding liquidity enabled in `pool_status`, and with ActivationAccess every activation slot must allow adding liquidity at the current point, unless the NFT owner is `whitelisted_add_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its add liquidity point.
* `expected_layout_version`, when set, must match the position layout version.
* For each selected slot the position and its ticks are brought up to date first: released vesting liquidity becomes unlocked, and fees and rewards are accrued to the position. Then the liquidity is added to the slot unlocked liquidity and to the gross liquidity of its two ticks. The net liquidity of the lower tick goes up by the same amount and the net liquidity of the upper tick goes down by it. A tick cannot hold more gross liquidity than the largest `u128` divided by the number of ticks of the pool.
* Pool liquidity increases only by the liquidity of slots whose range contains the current tick, meaning lower tick id at or below it and upper tick id above it.
* Token amounts follow the current price: only token X when the price is below the range, only token Y when above, both when inside. Each amount is rounded up and summed over the slots. The program then adds the Token 2022 transfer fee of each mint, so that the reserve receives exactly the required amount. The fee-included total must not exceed the matching `max_amount`. Nothing is paid for a token whose total is 0.
* Tick arrays that change between holding no liquidity and holding some flip their bit in the pool bitmap, or in the extension for indexes outside -512 to 511.

#### Events

[`EvtAddLiquidity`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtaddliquidity) is emitted with the amounts paid and the resulting liquidities, as for `add_liquidity`.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `InvalidParameters` | `bitmap` and `liquidities` do not match: empty list, a count different from the set bits, or a bit at or above the slot count. |
| `LiquidityIsZero` | A selected liquidity is 0. |
| `LiquidityIsTooHigh` | A liquidity is above the largest signed 128-bit value, or a tick would exceed the gross liquidity limit. |
| `ExceededSlippage` | The transfer-fee-included amount of token X or Y is above `max_amount_x` or `max_amount_y`. |
| `InvalidActivationAccess` | Adding liquidity is disabled in `pool_status`, or the activation rules do not allow it yet for the NFT owner. |
| `InvalidTickArray` | A remaining account after the hook slices belongs to another pool. |
| `CannotFindTickFromId` | A tick of a selected slot is not in any tick array passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 flips and `tick_array_bitmap_extension` was not passed. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |
| `MathOverflow` | `multiplier * weight` overflows `u128`. |
| `TypeCastFailed` | The token X or Y amount for a selected liquidity does not fit in a `u64`. |

#### SDK

`client.position.addLiquidityByWeight`.

### add\_liquidity\_imbalance

Deposits into one range slot of a position, using up to the given maximum of each token and minting the liquidity that the smaller side allows. The NFT owner can call it, or a delegate with the AddLiquidity permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `AddLiquidityImbalanceParameters` | Deposit request. The fields follow. |
| `parameters.max_amount_x` | `Option<u64>` | Most token X to use, in atoms, including the Token 2022 transfer fee. `None` deposits no token X. When set it must be above 0. The amount used is the smaller of this value and the balance of `user_token_x`. |
| `parameters.max_amount_y` | `Option<u64>` | Most token Y to use, in atoms, including the Token 2022 transfer fee. `None` deposits no token Y. When set it must be above 0. The amount used is the smaller of this value and the balance of `user_token_y`. At least one of the two maximums must be `Some`. |
| `parameters.slippage` | `AddLiquidityImbalanceSlippage` | Bounds on the execution price and on the liquidity minted. |
| `parameters.slippage.sqrt_price_slippage` | `Option<SqrtPriceSlippage>` | `None` skips the price check. `Some` requires the current pool price to be inside the bounds below. |
| `parameters.slippage.sqrt_price_slippage.min_sqrt_price` | `u128` | Lowest accepted pool square root price, Q64.64. At least 4295048016 and at most `max_sqrt_price`. |
| `parameters.slippage.sqrt_price_slippage.max_sqrt_price` | `u128` | Highest accepted pool square root price, Q64.64. At most 79226673515401279992447579055. |
| `parameters.slippage.min_liquidity` | `Option<u128>` | `None` skips the check. `Some` requires the liquidity minted to be at least this value, which guards against a deposit that ends up almost empty. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |
| `parameters.index` | `u8` | Index of the position slot to deposit into. Must be below the slot count. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Its liquidity changes when a selected range contains the current tick, and rewards are accrued. |
| `position` | Yes | No | Position array to modify. Its `pool` field must equal `pool`. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when a tick array outside indexes -512 to 511 changes between empty and non-empty. When omitted, pass the program ID as placeholder. |
| `user_token_x` | Yes | No | Token account that pays token X, for the token X mint. The `signer` must be its authority. |
| `user_token_y` | Yes | No | Token account that pays token Y, for the token Y mint. The `signer` must be its authority. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with AddLiquidity. It pays the tokens, so it must also be the authority of `user_token_x` and `user_token_y`. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_account_info` argument, then tick arrays. `TransferHookX` and `TransferHookY` are accepted. The tick arrays are all writable, in any order, and every account after the hook slices must be a tick array of the pool. Pass the arrays that hold the lower and upper tick id of the slot.

#### Checks and Effects

* Parameters are validated: at least one maximum is set and above 0, `index` is a valid slot, the layout version matches, and when `sqrt_price_slippage` is set its bounds are inside the price limits, ordered, and contain the current price.
* For each side with a maximum, the amount used is the smaller of the maximum and the token account balance. The Token 2022 transfer fee is removed from it, and the liquidity that this amount buys in the slot range is computed. A side that the range cannot take at the current price gives no liquidity and is ignored. When both sides give a value, the smaller liquidity is minted, so one side may be only partly used.
* The maximum passed on to the deposit is the given maximum for a side, and 0 for a side that is `None`. The call then runs as `add_liquidity` for that single slot with that liquidity, so the amounts actually paid are rounded up from the liquidity and checked against the maximums.
* A side that is `None` has a maximum of 0. If the range needs that token at the current price, which is the case whenever the current tick is inside the range, the call fails with `ExceededSlippage`. Use a one-sided deposit only for a range that is entirely above the current tick (token X only) or that ends at or below it (token Y only).
* The position must exist for the NFT: `nft_account` holds 1 of the position NFT. The signer must be the NFT owner, or a delegate of the token account with a zero delegated amount and the AddLiquidity permission.
* The pool must have adding liquidity enabled in `pool_status`, and with ActivationAccess every activation slot must allow adding liquidity at the current point, unless the NFT owner is `whitelisted_add_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its add liquidity point.
* `expected_layout_version`, when set, must match the position layout version.
* For each selected slot the position and its ticks are brought up to date first: released vesting liquidity becomes unlocked, and fees and rewards are accrued to the position. Then the liquidity is added to the slot unlocked liquidity and to the gross liquidity of its two ticks. The net liquidity of the lower tick goes up by the same amount and the net liquidity of the upper tick goes down by it. A tick cannot hold more gross liquidity than the largest `u128` divided by the number of ticks of the pool.
* Pool liquidity increases only by the liquidity of slots whose range contains the current tick, meaning lower tick id at or below it and upper tick id above it.
* Token amounts follow the current price: only token X when the price is below the range, only token Y when above, both when inside. Each amount is rounded up and summed over the slots. The program then adds the Token 2022 transfer fee of each mint, so that the reserve receives exactly the required amount. The fee-included total must not exceed the matching `max_amount`. Nothing is paid for a token whose total is 0.
* Tick arrays that change between holding no liquidity and holding some flip their bit in the pool bitmap, or in the extension for indexes outside -512 to 511.

#### Events

[`EvtAddLiquidity`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtaddliquidity) is emitted with a bitmap of the single slot and the liquidity minted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `LiquidityIsTooHigh` | A liquidity is above the largest signed 128-bit value, or a tick would exceed the gross liquidity limit. |
| `InvalidActivationAccess` | Adding liquidity is disabled in `pool_status`, or the activation rules do not allow it yet for the NFT owner. |
| `InvalidTickArray` | A remaining account after the hook slices belongs to another pool. |
| `CannotFindTickFromId` | A tick of a selected slot is not in any tick array passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 flips and `tick_array_bitmap_extension` was not passed. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |
| `InvalidParameters` | Both maximums are `None`, `index` is not below the slot count, or the price bounds are outside the price limits or reversed. |
| `AmountIsZero` | A maximum is 0, or no side can take liquidity at the current price. |
| `LiquidityIsZero` | The liquidity computed is 0. |
| `ExceededSlippage` | The pool price is outside the `sqrt_price_slippage` bounds, the liquidity is below `min_liquidity`, the transfer-fee-included amount is above a maximum, or the range needs a token whose maximum is `None`. |

#### SDK

`client.position.addLiquidityImbalance`.

### remove\_liquidity

Withdraws chosen liquidity amounts from selected range slots of a position and pays out the tokens. The NFT owner can call it, or a delegate with the RemoveLiquidity permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `RemoveLiquidityParameters` | Withdrawal request. The fields follow. |
| `parameters.min_amount_x` | `u64` | Least token X the receiver must get, in atoms, after the Token 2022 transfer fee of mint X. 0 skips the check. |
| `parameters.min_amount_y` | `u64` | Least token Y the receiver must get, in atoms, after the Token 2022 transfer fee of mint Y. 0 skips the check. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |
| `parameters.bitmap` | `u64` | Bit i selects position slot i. The number of set bits must equal the number of entries in `liquidities`, and no bit may be at or above the slot count. |
| `parameters.liquidities` | `Vec<u128>` | Liquidity to remove per selected slot, as unscaled integers, in ascending slot order. Each must be above 0, at most the unlocked liquidity of the slot, and at most 170141183460469231731687303715884105727. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Its liquidity changes when a selected range contains the current tick, and rewards are accrued. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `position` | Yes | No | Position array to modify. Its `pool` field must equal `pool`. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when a tick array outside indexes -512 to 511 changes between empty and non-empty. When omitted, pass the program ID as placeholder. |
| `user_token_x` | Yes | No | Token account that receives token X. Only used when the withdrawal includes token X, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `user_token_y` | Yes | No | Token account that receives token Y. Only used when the withdrawal includes token Y, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with RemoveLiquidity. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_account_info` argument, then tick arrays. `TransferHookX` and `TransferHookY` are accepted. The tick arrays are all writable, in any order, and every account after the hook slices must be a tick array of the pool. Pass the arrays that hold the lower and upper tick id of every slot that is withdrawn from.

#### Checks and Effects

* The signer must be the NFT owner, or a delegate of the token account with a zero delegated amount and the RemoveLiquidity permission.
* Removing liquidity cannot be disabled in `pool_status`. With ActivationAccess every activation slot must allow removing at the current point unless the NFT owner is `whitelisted_remove_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its remove liquidity point.
* `expected_layout_version`, when set, must match the position layout version.
* For each selected slot the position is brought up to date first: released vesting liquidity becomes unlocked, and fees and rewards are accrued to the position. Liquidity is then taken from the slot unlocked liquidity only, so permanently locked and still vesting liquidity cannot leave. The gross liquidity of the two ticks drops by the same amount. The net liquidity of the lower tick drops by it and the net liquidity of the upper tick rises by it. Tick references are only dropped when the slot is removed or the position is closed.
* Pool liquidity decreases only by the liquidity of slots whose range contains the current tick.
* Token amounts follow the current price and are rounded down, summed over the slots. The amounts are taken out of the reserves in full, and the receiver gets them minus the Token 2022 transfer fee of each mint. `min_amount_x` and `min_amount_y` are checked against the amounts after that fee, and a minimum of 0 skips the check.
* Fees and rewards that the slots earned are not paid out here. They stay pending on the position until `claim_fee` and `claim_reward`.
* A delegate can only pay into the associated token account of the NFT owner for each mint and token program. The NFT owner can pay anywhere. If the receiver is a Token 2022 account that requires incoming transfer memos, a memo is written first.
* Tick arrays that change between holding no liquidity and holding some flip their bit in the pool bitmap, or in the extension for indexes outside -512 to 511.

#### Events

[`EvtRemoveLiquidity`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtremoveliquidity) is emitted with the amounts taken from the reserves, before the transfer fee, and the pool price at execution.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `MathOverflow` | A liquidity to remove is larger than the unlocked liquidity of the slot or the liquidity of a tick. |
| `LiquidityIsTooHigh` | A liquidity is above the largest signed 128-bit value. |
| `TypeCastFailed` | The token X or Y amount for a selected liquidity does not fit in a `u64`. |
| `ExceededSlippage` | The amount of token X or Y after the transfer fee is below `min_amount_x` or `min_amount_y`. |
| `IncorrectATA` | A delegate signed and the receiving account is not the associated token account of the NFT owner for that mint. |
| `InvalidActivationAccess` | The activation rules do not allow removing liquidity yet for the NFT owner. |
| `InvalidTickArray` | A remaining account after the hook slices belongs to another pool. |
| `CannotFindTickFromId` | A tick of a selected slot is not in any tick array passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 flips and `tick_array_bitmap_extension` was not passed. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |
| `InvalidParameters` | `bitmap` and `liquidities` do not match: empty list, a count different from the set bits, or a bit at or above the slot count. |
| `LiquidityIsZero` | A selected liquidity is 0. |

#### SDK

`client.position.removeLiquidity`.

### remove\_liquidity\_by\_bps

Withdraws a share of the unlocked liquidity of selected range slots, after releasing vested liquidity. The NFT owner can call it, or a delegate with the RemoveLiquidity permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `RemoveLiquidityByBpsParameters` | Withdrawal request. The fields follow. |
| `parameters.min_amount_x` | `u64` | Least token X the receiver must get, in atoms, after the Token 2022 transfer fee of mint X. 0 skips the check. |
| `parameters.min_amount_y` | `u64` | Least token Y the receiver must get, in atoms, after the Token 2022 transfer fee of mint Y. 0 skips the check. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |
| `parameters.bps` | `u16` | Share of the unlocked liquidity of each selected slot to remove, in basis points, 1 to 10000 inclusive. 10000 removes everything that is unlocked. |
| `parameters.bitmap` | `Option<u64>` | `None` selects every slot. `Some` selects slot i with bit i, with at least one bit set and no bit at or above the slot count. Slots whose share rounds down to 0 are skipped. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Its liquidity changes when a selected range contains the current tick, and rewards are accrued. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `position` | Yes | No | Position array to modify. Its `pool` field must equal `pool`. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when a tick array outside indexes -512 to 511 changes between empty and non-empty. When omitted, pass the program ID as placeholder. |
| `user_token_x` | Yes | No | Token account that receives token X. Only used when the withdrawal includes token X, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `user_token_y` | Yes | No | Token account that receives token Y. Only used when the withdrawal includes token Y, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with RemoveLiquidity. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_account_info` argument, then tick arrays. `TransferHookX` and `TransferHookY` are accepted. The tick arrays are all writable, in any order, and every account after the hook slices must be a tick array of the pool. Pass the arrays that hold the lower and upper tick id of every slot that is withdrawn from.

#### Checks and Effects

* Released vesting liquidity of the position is unlocked first, so the share applies to the liquidity that is unlocked now.
* For each selected slot the liquidity removed is `unlocked liquidity * bps / 10000`, rounded down. Slots that give 0 are left out. If every slot gives 0 the call fails.
* The rest follows `remove_liquidity` with those liquidities and bitmap.
* The signer must be the NFT owner, or a delegate of the token account with a zero delegated amount and the RemoveLiquidity permission.
* Removing liquidity cannot be disabled in `pool_status`. With ActivationAccess every activation slot must allow removing at the current point unless the NFT owner is `whitelisted_remove_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its remove liquidity point.
* `expected_layout_version`, when set, must match the position layout version.
* For each selected slot the position is brought up to date first: released vesting liquidity becomes unlocked, and fees and rewards are accrued to the position. Liquidity is then taken from the slot unlocked liquidity only, so permanently locked and still vesting liquidity cannot leave. The gross liquidity of the two ticks drops by the same amount. The net liquidity of the lower tick drops by it and the net liquidity of the upper tick rises by it. Tick references are only dropped when the slot is removed or the position is closed.
* Pool liquidity decreases only by the liquidity of slots whose range contains the current tick.
* Token amounts follow the current price and are rounded down, summed over the slots. The amounts are taken out of the reserves in full, and the receiver gets them minus the Token 2022 transfer fee of each mint. `min_amount_x` and `min_amount_y` are checked against the amounts after that fee, and a minimum of 0 skips the check.
* Fees and rewards that the slots earned are not paid out here. They stay pending on the position until `claim_fee` and `claim_reward`.
* A delegate can only pay into the associated token account of the NFT owner for each mint and token program. The NFT owner can pay anywhere. If the receiver is a Token 2022 account that requires incoming transfer memos, a memo is written first.
* Tick arrays that change between holding no liquidity and holding some flip their bit in the pool bitmap, or in the extension for indexes outside -512 to 511.

#### Events

[`EvtRemoveLiquidity`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtremoveliquidity) is emitted with the bitmap of the slots withdrawn from and the liquidities removed.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `ExceededSlippage` | The amount of token X or Y after the transfer fee is below `min_amount_x` or `min_amount_y`. |
| `IncorrectATA` | A delegate signed and the receiving account is not the associated token account of the NFT owner for that mint. |
| `InvalidActivationAccess` | The activation rules do not allow removing liquidity yet for the NFT owner. |
| `InvalidTickArray` | A remaining account after the hook slices belongs to another pool. |
| `CannotFindTickFromId` | A tick of a selected slot is not in any tick array passed. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 flips and `tick_array_bitmap_extension` was not passed. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |
| `InvalidParameters` | `bps` is 0 or above 10000, `bitmap` is `Some` and empty or selects a slot beyond the slot count, or no selected slot has a share above 0 after rounding. |

#### SDK

`client.position.removeLiquidityByBps`.

### refresh\_fees\_and\_rewards

Accrues fees and rewards into the selected range slots of a position without moving tokens. The NFT owner can call it, or any delegate of the NFT token account, whatever its permissions.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `bitmap` | `u64` | Bit i selects position slot i. At least one bit must be set and no bit may be at or above the slot count. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Pool-wide rewards are accrued up to now. |
| `position` | Yes | No | Position array to update. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate. No permission bit is needed. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Tick arrays that hold the lower and upper tick id of every selected slot that has liquidity, in any order. The program only reads them, so they can be read-only.

#### Checks and Effects

* The signer must be the NFT owner or the delegate of the token account with a zero delegated amount.
* The bitmap must select at least one existing slot.
* For each selected slot with liquidity, the fees earned since its checkpoint are added to its pending fees, and on LiquidityMining pools the rewards earned are added to its pending rewards. Released vesting liquidity becomes unlocked. Slots with no liquidity are skipped. Accrual uses the fee growth and reward growth inside the range, which need both ticks of the range.
* Pool reward state is updated to the current time on LiquidityMining pools. No tokens move.
* Claim instructions pay only what has been accrued, so refresh every slot that holds liquidity before `claim_fee` or `claim_reward`.

#### Events

No event is emitted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidParameters` | The bitmap is empty or selects a slot beyond the slot count. |
| `InvalidAuthority` | The signer is not the NFT owner and not the delegate of the NFT token account. |
| `DelegatedAmountNonZero` | The signer is the delegate but the delegated amount is not 0. |
| `InvalidTickArray` | A remaining account belongs to another pool. |
| `CannotFindTickFromId` | A tick of a selected slot that has liquidity is not in any tick array passed. |

#### SDK

`client.position.refreshFeesAndRewards`.

### claim\_fee

Pays out the pending fees of every slot of a position and resets them. The NFT owner can call it, or a delegate with the ClaimFee permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `min_amount_x` | `u64` | Least token X the receiver must get, in atoms, after the Token 2022 transfer fee of mint X. 0 skips the check. |
| `min_amount_y` | `u64` | Least token Y the receiver must get, in atoms, after the Token 2022 transfer fee of mint Y. 0 skips the check. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `position` | Yes | No | Position array whose pending fees are reset. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with ClaimFee. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `user_token_x` | Yes | No | Token account that receives token X. Only used when the pending fee in token X is above 0, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `user_token_y` | Yes | No | Token account that receives token Y. Only used when the pending fee in token Y is above 0, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_account_info` argument. `TransferHookX` and `TransferHookY` are accepted. No tick arrays are needed.

#### Checks and Effects

* The signer must be the NFT owner, or a delegate of the token account with a zero delegated amount and the ClaimFee permission.
* Sums the pending fees of every slot and sets them to 0. Only fees already accrued to the slots are included, so refresh first (or have added or removed liquidity) to include recent swaps.
* The reserve pays the full pending amount. The receiver gets it minus the Token 2022 transfer fee. `min_amount_x` and `min_amount_y` are checked against the amounts after that fee, and 0 skips the check. Nothing is transferred for a token whose pending amount is 0.
* A delegate can only pay into the associated token account of the NFT owner for that mint and token program. If the receiver is a Token 2022 account that requires incoming transfer memos, a memo is written first.

#### Events

[`EvtClaimFee`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtclaimfee) is emitted with the amounts paid, before the transfer fee, even when both are 0.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `ExceededSlippage` | The amount of token X or Y after the transfer fee is below `min_amount_x` or `min_amount_y`. |
| `IncorrectATA` | A delegate signed and a receiving account is not the associated token account of the NFT owner for that mint. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

`client.position.claimFee`.

### lock\_permanent\_position

Locks a share of the unlocked liquidity of every slot of a position for good. Only the NFT owner can call it. The locked liquidity keeps earning fees and rewards but can never be removed.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `LockPermanentPositionParameters` | Lock request. The fields follow. |
| `parameters.bps` | `u16` | Share of the unlocked liquidity of each slot to lock, in basis points, 1 to 10000 inclusive. 10000 locks all of it. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read, for the extensions and the activation type. |
| `position` | Yes | No | Position array whose slots are updated. |
| `nft_account` | No | No | Token account that holds the position NFT. Its owner must be `signer`. |
| `signer` | No | Yes | Signs. Must be the owner of `nft_account`. Delegates cannot lock. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The signer must own the NFT token account. `expected_layout_version`, when set, must match, and `bps` must be 1 to 10000.
* Released vesting liquidity is unlocked first, so it is included in the amount that is locked.
* Every slot moves `unlocked liquidity * bps / 10000`, rounded down, from unlocked to permanently locked liquidity. All slots are affected, there is no bitmap. At least one slot must move a non-zero amount.
* No tokens, ticks or pool values change. Locked liquidity stays in the pool, so fees and rewards keep accruing.
* There is no way to unlock. `close_position` and `remove_position` stay blocked for a slot that holds locked liquidity.

#### Events

[`EvtLockPermanent`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtlockpermanent) is emitted with `bps` and the liquidity locked in each slot.

#### Errors

| Error | Cause |
| - | - |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `InvalidParameters` | `bps` is 0 or above 10000. |
| `LiquidityIsZero` | No slot has liquidity to lock after rounding. |

#### SDK

`client.position.lockPermanentPosition`.

### lock\_vesting\_position

Moves a share of the unlocked liquidity of every slot into one vesting schedule, with an optional cliff and then periodic releases. Only the NFT owner can call it. A position can have one schedule in its lifetime.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `LockVestingPositionParameters` | Schedule. The fields follow. |
| `parameters.cliff_point` | `Option<u64>` | Slot or timestamp, by the pool activation type, at which the cliff releases. `None` starts at the current point. Must not be in the past. |
| `parameters.cliff_unlock_bps` | `u16` | Share of the vested liquidity released at the cliff, in basis points. |
| `parameters.bps_per_period` | `u16` | Share of the vested liquidity released each period after the cliff, in basis points. |
| `parameters.period_frequency` | `u64` | Length of a period, in slots or seconds by the pool activation type. |
| `parameters.number_of_period` | `u16` | Number of periods after the cliff. |
| `parameters.bps` | `u16` | Share of the unlocked liquidity of each slot to put into vesting, in basis points, 1 to 10000 inclusive. |
| `parameters.expected_layout_version` | `Option<u16>` | Position layout version the caller built its slot selection against. `None` skips the check. The version starts at 0 and `expand_position` and `remove_position` add 1, wrapping at 65535, because they change the slot order or count. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read, for the activation type and the extensions. |
| `position` | Yes | No | Position array that stores the schedule and whose slots are updated. |
| `nft_account` | No | No | Token account that holds the position NFT. Its owner must be `signer`. |
| `signer` | No | Yes | Signs. Must be the owner of `nft_account`. Delegates cannot lock. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The signer must own the NFT token account. `expected_layout_version`, when set, must match.
* Schedule rules: `cliff_unlock_bps` is above 0, or all of `period_frequency`, `bps_per_period` and `number_of_period` are above 0. If any of those three is above 0, all three must be. `cliff_unlock_bps + bps_per_period * number_of_period` must equal exactly 10000. The cliff point is not in the past. The wait until the cliff plus `period_frequency * number_of_period` is at most 10 years, which is 315360000 seconds or 1261440000 slots.
* The position must not already have a schedule, even a fully released one.
* Every slot moves `unlocked liquidity * bps / 10000`, rounded down, from unlocked to vesting liquidity. All slots are affected, there is no bitmap. At least one slot must move a non-zero amount.
* Release: nothing before the cliff point. From the cliff the released share is `cliff_unlock_bps` plus `bps_per_period` for each full period elapsed since the cliff, of the vested total, and everything after `number_of_period` periods. Released liquidity becomes unlocked the next time the position is refreshed or its liquidity is changed. Vesting liquidity cannot be removed until released.
* No tokens, ticks or pool values change. Vesting liquidity keeps earning fees and rewards.

#### Events

[`EvtLockVesting`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtlockvesting) is emitted with the schedule and the liquidity moved in each slot.

#### Errors

| Error | Cause |
| - | - |
| `InvalidLayoutVersion` | `expected_layout_version` differs from the position `layout_version`. |
| `InvalidParameters` | The schedule breaks one of the rules above, or `bps` is 0 or above 10000. |
| `PositionAlreadyHadVesting` | The position already has a vesting schedule. |
| `LiquidityIsZero` | No slot has liquidity to vest after rounding. |
| `MathOverflow` | A schedule value overflows when multiplied, for example `bps_per_period * number_of_period`. |

#### SDK

`client.position.lockVestingPosition`.

### open\_limit\_order

Mints a limit order NFT to `owner` and deposits one token into up to 25 ticks as resting orders. The owner and the payer sign. An ask order deposits token X above the current tick, a bid order deposits token Y at or below it.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `OpenLimitOrderParameters` | Order request. The fields follow. |
| `parameters.is_ask_side` | `bool` | `true` for an ask order: deposits token X, and swaps that buy token X fill it. `false` for a bid order: deposits token Y, and swaps that sell token X fill it. |
| `parameters.max_amount` | `u64` | Most to take from `user_token`, in atoms, including the Token 2022 transfer fee of the deposited mint. The sum of the tick amounts plus that fee must not exceed it. |
| `parameters.relative_tick` | `Option<RelativeTick>` | `None` means the `ticks[].id` values are absolute tick ids. `Some` means they are offsets: the tick used is the current tick id aligned down to the tick spacing, plus `id * tick_spacing`. `Some` also guards against price movement by bounding the aligned current tick. |
| `parameters.relative_tick.spacing_aligned_min_tick_id` | `i32` | Lowest accepted value of the aligned current tick id. Must be a multiple of the tick spacing. |
| `parameters.relative_tick.spacing_aligned_max_tick_id` | `i32` | Highest accepted value of the aligned current tick id. Must be a multiple of the tick spacing and at least the minimum. The current aligned tick id must be inside the bounds, inclusive. |
| `parameters.ticks` | `Vec<TickLimitOrderAmount>` | 1 to 25 entries, with strictly ascending `id`, each with an amount above 0. |
| `parameters.ticks[].id` | `i32` | Absolute tick id, or the offset in tick spacings when `relative_tick` is set. After conversion it must be a multiple of the tick spacing within -443636 to 443636. An ask order needs every tick id above the current tick id, a bid order needs every tick id at or below it. |
| `parameters.ticks[].amount` | `u64` | Amount of the deposited token for this tick, in atoms, before the Token 2022 transfer fee. This exact amount is credited to the order. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts only `TransferHookX` for an ask order and only `TransferHookY` for a bid order. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts only `TransferHookX` for an ask order and only `TransferHookY` for a bid order. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Only the tick bitmap changes, through the tick arrays. It must allow adding liquidity for `owner`. |
| `pool_authority` | No | No | Mint authority and close authority of the NFT mint. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `nft_mint` | Yes | Yes | New Token 2022 mint of the limit order NFT, a fresh keypair that signs. Created with 0 decimals, the pool authority as mint authority, the pool as freeze authority, and its token metadata stored in the mint. |
| `nft_account` | Yes | No | Token account of `owner` for the NFT, created by this instruction and paid by `payer`. Associated token account of `owner` for `nft_mint` under Token 2022. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when a tick array outside indexes -512 to 511 becomes non-empty. When omitted, pass the program ID as placeholder. |
| `reserve` | Yes | No | Reserve that receives the deposit: `reserve_x` of the pool for an ask order, `reserve_y` for a bid order. |
| `token_mint` | No | No | Mint of the deposited token: the token X mint for an ask order, the token Y mint for a bid order. |
| `limit_order` | Yes | No | New limit order account paid by `payer`, with one entry per tick. PDA with seeds `"limit_order"`, `nft_mint`. |
| `user_token` | Yes | No | Token account that pays the deposit, for `token_mint`. `owner` must be its authority. |
| `referral` (optional) | No | No | Wallet address recorded as the referral of the order, not a token account. It can receive 20% of the order fee when the order is cancelled. When omitted, pass the program ID as placeholder and the order has no referral. |
| `payer` | Yes | Yes | Pays the rent of the NFT mint, the NFT token account, the limit order, missing tick arrays, and one tick entry per order tick. |
| `owner` | No | Yes | Signs, owns the order and pays the deposit. Receives the NFT. |
| `token_program` | No | No | Token program of `token_mint`, Token or Token 2022. |
| `token2022_program` | No | No | Token 2022 program, used for the NFT. Fixed address `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `associated_token_program` | No | No | Associated token account program. Fixed address `ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slice for the deposited token (`TransferHookX` for an ask order, `TransferHookY` for a bid order), then tick arrays, all writable. With `relative_tick` unset, pass one tick array per distinct tick array index of the order ticks in ascending index order. With `relative_tick` set, pass them in any order, extra arrays are allowed, and the program picks the ones it needs by address, so include the arrays for every offset you may land on. A missing array is created at its derived address.

#### Checks and Effects

* The pool must have adding liquidity enabled in `pool_status`, and with ActivationAccess every activation slot must allow adding liquidity at the current point, unless `owner` is `whitelisted_add_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its add liquidity point.
* The `reserve` and `token_mint` accounts must be the ones of the deposited side. With `relative_tick`, the aligned current tick id must be inside its bounds.
* Ticks: 1 to 25, strictly ascending ids, amounts above 0, valid tick ids after conversion, and on the correct side of the current tick. A tick that already holds unfilled orders accepts new orders only on the same side as the existing ones.
* Each tick adds the amount to its open order amount and records the order age of the tick. The order stores amount, age, side and tick id per entry. A tick with pending orders counts as having liquidity for the pool bitmap, so tick arrays can flip to non-empty in the bitmap or extension.
* `payer` pays the rent of one tick entry per order tick. Missing tick arrays are created and tick arrays grow to hold new ticks. Each tick keeps a reference count that goes up by one per use. The same rent returns to the `rent_receiver` of `close_limit_order`.
* The deposit moves from `user_token` to the reserve: the sum of the tick amounts plus the Token 2022 transfer fee, so that the reserve receives the sum exactly. That total must not exceed `max_amount`.
* Mints exactly 1 of the NFT to `owner`.

#### Events

[`EvtOpenLimitOrder`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtopenlimitorder) is emitted with the ticks as converted to absolute tick ids and the order age of each.

#### Errors

| Error | Cause |
| - | - |
| `InvalidParameters` | No ticks or more than 25, an amount of 0, ids not strictly ascending, a relative bound that is not a multiple of the tick spacing or reversed, a tick id that is not usable, an ask tick not above the current tick or a bid tick above it, or a tick that holds orders of the other side. |
| `ExceededSlippage` | The aligned current tick is outside the relative bounds, or the amount including the transfer fee is above `max_amount`. |
| `InvalidActivationAccess` | Adding liquidity is disabled in `pool_status`, or the activation rules do not allow it yet for the owner. |
| `InvalidTickArray` | A tick array is missing, is not at its derived address, or belongs to another pool or index. |
| `InsufficientRemainingAccounts` | With `relative_tick`, a tick array needed for a tick is not among the remaining accounts. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 becomes non-empty and `tick_array_bitmap_extension` was not passed. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

`client.limitOrder.openLimitOrder`. The `nftMint` keypair must co-sign the transaction.

### cancel\_limit\_order

Cancels the order at the listed ticks and pays out the unfilled amount, the proceeds of the filled part and the owner share of the fee. The NFT owner can call it, or a delegate with the CancelLimitOrder permission. The order account and its tick references stay until `close_limit_order`.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `CancelLimitOrderParameters` | Cancel request. The fields follow. |
| `parameters.tick_ids` | `Vec<i32>` | Absolute tick ids to cancel. At least one, strictly ascending, and each must be a tick of this order that is not canceled yet. |
| `parameters.min_amount_x` | `u64` | Least token X the receiver must get, in atoms, after the Token 2022 transfer fee of mint X. It counts the owner share of the fee. 0 skips the check. |
| `parameters.min_amount_y` | `u64` | Least token Y the receiver must get, in atoms, after the Token 2022 transfer fee of mint Y. It counts the owner share of the fee. 0 skips the check. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX`, `TransferHookY` and `TransferHookReferral`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX`, `TransferHookY` and `TransferHookReferral`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Only the tick bitmap changes, through the tick arrays. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `tick_array_bitmap_extension` (optional) | Yes | No | Bitmap extension of the pool. Needed when a tick array outside indexes -512 to 511 becomes empty. When omitted, pass the program ID as placeholder. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `limit_order` | Yes | No | Limit order to cancel from. Its `pool` field must equal `pool`. |
| `nft_account` | No | No | Token account that holds the limit order NFT, with amount 1 of the mint stored in `limit_order`. |
| `user_token_x` | Yes | No | Token account that receives token X. Only used when the payout includes token X, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `user_token_y` | Yes | No | Token account that receives token Y. Only used when the payout includes token Y, but it must still be passed. A delegate must pass the associated token account of the NFT owner. |
| `referral_token` (optional) | Yes | No | Token account of the fee token owned by the referral wallet of the order. It receives the referral share. When omitted, pass the program ID as placeholder and the owner keeps the whole fee. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with CancelLimitOrder. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_account_info` argument (`TransferHookX`, `TransferHookY`, `TransferHookReferral`), then tick arrays, all writable, in any order, that hold every tick listed. Every account after the hook slices must be a tick array of the pool.

#### Checks and Effects

* The signer must be the NFT owner, or a delegate with a zero delegated amount and the CancelLimitOrder permission.
* Cancelling cannot be disabled in `pool_status`. With ActivationAccess every activation slot must allow removing liquidity at the current point, unless the NFT owner is `whitelisted_remove_liquidity`. BondingCurve allows only after its target is reached, TimeBased from its remove liquidity point.
* For each tick id, the order entry must exist and not be canceled. What it gets depends on how far the tick was filled. Unfilled: the whole amount comes back in the deposited token. Partly filled: the amount is split in proportion between the unfilled part (rounded up, so earlier cancellers get slightly more of the unfilled side) and the filled part. Fully filled: the whole amount has been exchanged.
* The filled part is paid in the other token at the tick price (token Y per token X, the square of the tick square root price), rounded down, so the pool never pays out more than it took in. An ask order receives token Y and a bid order receives token X.
* The order also gets its share of the limit order fee collected at the tick, in proportion to its filled amount, rounded down. The fee token is token X for an ask order and token Y for a bid order with `OutputToken`, and always token Y with `OnlyY`.
* If the order has a referral wallet that is not the owner, `referral_token` is passed and owned by that wallet, the referral gets 20% of the fee, rounded down, paid from the reserve of the fee token, and the owner gets the rest. Otherwise the owner gets all of it. A referral account that is missing or not owned by the referral wallet is not an error, the owner just keeps the whole fee. An account owned by the referral wallet must be for the fee token, or the transfer fails.
* The owner payout is the unfilled amount plus the filled proceeds plus the owner fee, per token. It leaves the reserves in full and the receiver gets it minus the Token 2022 transfer fee. `min_amount_x` and `min_amount_y` are checked against the amounts after that fee.
* A delegate can only pay into the associated token account of the NFT owner for that mint and token program. If a receiver is a Token 2022 account that requires incoming transfer memos, a memo is written first.
* Each canceled entry is zeroed and the tick drops the amounts. Ticks and their rent stay referenced by the order until it is closed. Tick arrays that change between holding no liquidity and holding some flip their bit in the pool bitmap, or in the extension for indexes outside -512 to 511.

#### Events

[`EvtCancelLimitOrder`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtcancellimitorder) is emitted with the amounts paid to the owner, the fee parts and the referral fee.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `InvalidParameters` | `tick_ids` is empty or not strictly ascending. |
| `InvalidActivationAccess` | The activation rules do not allow removing liquidity yet for the owner. |
| `CannotFindTickFromId` | A listed tick is not in any tick array passed. |
| `CannotFindLimitOrderByTickId` | The order has no entry for a listed tick id. |
| `CancelNonEmptyLimitOrder` | A listed tick of the order is already canceled. |
| `ExceededSlippage` | The amount of token X or Y after the transfer fee is below `min_amount_x` or `min_amount_y`. |
| `IncorrectATA` | A delegate signed and a receiving account is not the associated token account of the NFT owner for that mint. |
| `InvalidTickArray` | A remaining account after the hook slices belongs to another pool. |
| `TickArrayBitmapExtensionAccountIsNotProvided` | A tick array outside indexes -512 to 511 flips and `tick_array_bitmap_extension` was not passed. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

`client.limitOrder.cancelLimitOrder`.

### close\_limit\_order

Closes a limit order whose ticks are all canceled. Only the NFT owner can call it. It burns the NFT, closes the NFT token account, the NFT mint and the limit order account, and sends the freed rent to `rent_receiver`.

#### Arguments

This instruction takes no arguments.

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `limit_order` | Yes | No | Limit order to close. It is closed and its lamports go to `rent_receiver`. |
| `nft_mint` | Yes | No | Mint of the limit order NFT. Must equal `limit_order.nft_mint`. It is closed. |
| `nft_account` | Yes | No | Token account of the owner that holds the NFT. It is burned from and closed. |
| `owner` | No | Yes | Signs. Must be the authority of `nft_account`. |
| `rent_receiver` | Yes | No | Receives the rent of the limit order, the NFT token account, the NFT mint and the tick references. |
| `token_program` | No | No | Token 2022 program. Fixed address `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Tick arrays, all writable, one per distinct tick array index of the ticks of the order, in ascending index order with no duplicates and no other accounts in between.

#### Checks and Effects

* Every tick entry of the order must be canceled. Cancel first and claim the payout.
* Pause and activation rules do not apply: an owner can always close.
* Burns the 1 NFT, closes the NFT token account and the NFT mint (the pool authority signs for the mint), and closes the limit order. The rent of all three goes to `rent_receiver`.
* Drops the reference of every tick of the order and returns the rent of one tick entry per order tick to `rent_receiver`. Ticks left without references are removed and their tick arrays shrink.

#### Events

[`EvtCloseLimitOrder`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtcloselimitorder) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `LimitOrderIsNotEmpty` | A tick of the order is not canceled yet. |
| `InvalidTickArray` | A tick array is missing, has the wrong index or belongs to another pool. |
| `CannotFindTickFromId` | A tick of the order is not in the tick array passed. |

#### SDK

`client.limitOrder.closeLimitOrder`.

### update\_limit\_order\_delegate\_permission

Sets the permission bitmask that the NFT delegate has on a limit order. Only the NFT owner can call it.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `permission` | `u32` | Bitmask, 0 or 1. Bit 0 CancelLimitOrder. 0 removes the permission. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `limit_order` | Yes | No | Limit order that stores the bitmask. |
| `nft_account` | No | No | Token account that holds the NFT. Its authority must be `owner`. |
| `owner` | No | Yes | Signs. Must be the authority of `nft_account`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* `permission` is at most 1.
* Stores the bitmask on the limit order. It does not approve a delegate: the owner does that with a Token 2022 `approve` of amount 0 on the NFT token account. A delegate with a non-zero delegated amount fails every delegated call.
* The bitmask stays on the order when the NFT moves, so a new owner and the delegate they approve inherit it until it is changed.

#### Events

[`EvtUpdateLimitOrderDelegatePermission`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtupdatelimitorderdelegatepermission) is emitted with the permission and the current delegate of the NFT token account, if any.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPermission` | `permission` is above 1. |

#### SDK

`client.limitOrder.updateLimitOrderDelegatePermission`.

### initialize\_reward

Creates the reward vault of a reward slot and sets its mint and authority. Needs an operator with the InitializeReward permission, or the pool creator for slot 0. Only pools with the LiquidityMining extension have rewards.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `index` | `u8` | Reward slot, 0 or 1. The slot must not be initialized yet: its reward vault would already exist, so a second call fails when the vault account is created, with a system program error and not a program error. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. The reward slot is set up in its tail. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `reward_vault` | Yes | No | New token account for the reward, owned by the pool authority, created in `token_program` and paid by `payer`. PDA with seeds `"reward"`, `pool`, `index` (u8). |
| `reward_mint` | No | No | Mint of the reward token. |
| `token_badge` (optional) | No | No | Access registry `TokenBadge` account for the reward mint. Needed when the mint is not supported without a badge. When omitted, pass the program ID as placeholder. |
| `operator` (optional) | No | No | `Operator` account of the signer. Pass it when an operator initializes the slot. When omitted, pass the program ID as placeholder, and the signer must then be the pool creator and the slot must be 0. |
| `signer` | No | Yes | The operator wallet, or the pool creator for slot 0. |
| `payer` | Yes | Yes | Pays the rent of the reward vault. |
| `reward_authority` | No | No | Address that can set the emission of this slot and withdraw its ineligible rewards. Can be any account. |
| `token_program` | No | No | Token program of the reward mint, Token or Token 2022. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The pool must have the LiquidityMining extension, `index` must be 0 or 1, and the slot must not be initialized.
* With `operator` passed, its `whitelisted_address` must equal the signer and its permission bitmask must include InitializeReward. The mint is then checked like a pool mint: native Token 2022 mint fails, a passed badge must match the mint, and without a badge the mint must be supported without one (a freeze authority is allowed).
* Without `operator`, the signer must be the pool creator and `index` must be 0. The mint is checked the same way, but a freeze authority is not allowed without a badge, unless the mint is wrapped SOL or USDC.
* Creates the vault and records the mint, the vault, the authority and the token program flag in the slot. No emission is set yet, so nothing is paid or accrued until `set_reward_emission`.

#### Events

[`EvtInitializeReward`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtinitializereward) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPoolType` | The pool does not have the LiquidityMining extension. |
| `InvalidRewardIndex` | `index` is not 0 or 1. |
| `InvalidPermission` | The signer is not the whitelisted wallet of `operator` or lacks InitializeReward, or no operator was passed and the signer is not the pool creator, or `index` is not 0. |
| `UnsupportNativeMintToken2022` | The reward mint is the Token 2022 native mint. |
| `UnsupportedMint` | The reward mint is not supported without a badge and none was passed, including a freeze authority when the pool creator initializes. |
| `InvalidTokenBadge` | The badge passed belongs to another mint. |

#### SDK

`client.reward.initializeReward`. The builder covers the pool creator path only: slot 0 with no operator account. For an operator or slot 1, build it with `client.program.methods.initializeReward`.

### update\_reward\_authority

Changes the authority of a reward slot. The pool creator can do it for slot 0, and an operator with the UpdateRewardAuthority permission for any slot. The current reward authority cannot change itself.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `index` | `u8` | Reward slot, 0 or 1. The slot must be initialized. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. The authority is changed in its tail. |
| `signer` | No | Yes | The pool creator for slot 0, or an operator wallet. |
| `new_authority` | No | No | New authority of the slot. Must differ from the current one. |
| `operator` (optional) | No | No | `Operator` account of the signer. Needed unless the signer is the pool creator and `index` is 0. When omitted, pass the program ID as placeholder. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The pool must have the LiquidityMining extension, `index` must be 0 or 1, and the slot must be initialized.
* `new_authority` must differ from the current authority.
* If the signer is the pool creator and `index` is 0, no operator is needed. Otherwise `operator` must be passed, its `whitelisted_address` must equal the signer and its permission bitmask must include UpdateRewardAuthority.
* Stores the new authority. The vault, mint and emission do not change.

#### Events

[`EvtUpdateRewardAuthority`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtupdaterewardauthority) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPoolType` | The pool does not have the LiquidityMining extension. |
| `InvalidRewardIndex` | `index` is not 0 or 1. |
| `RewardUninitialized` | The slot is not initialized. |
| `InvalidParameters` | `new_authority` equals the current authority. |
| `MissingOperatorAccount` | The signer is not the pool creator for slot 0 and no `operator` was passed. |
| `InvalidPermission` | The operator is not the signer or lacks UpdateRewardAuthority. |

#### SDK

`client.reward.updateRewardAuthority`. The builder covers the pool creator path only: slot 0 with no operator account. For an operator or slot 1, build it with `client.program.methods.updateRewardAuthority`.

### set\_reward\_emission

Funds the reward vault for a new emission window and sets its rate. The reward authority of the slot must sign, and a funder pays the tokens. The slot must have no emission running.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `SetRewardEmissionParameters` | Emission request. The fields follow. |
| `parameters.index` | `u8` | Reward slot, 0 or 1. The slot must be initialized. |
| `parameters.open_time` | `Option<u64>` | Unix timestamp in seconds at which emission starts. `None` starts now. Must be between now and 2592000 seconds (30 days) from now, inclusive. |
| `parameters.end_time` | `u64` | Unix timestamp in seconds at which emission ends. The window `end_time - open_time` must be 86400 to 31536000 seconds inclusive. |
| `parameters.emission_per_second` | `u128` | Tokens per second in atoms, Q64.64. Must be above 0. The amount funded is `emission_per_second * (end_time - open_time) / 2^64`, rounded up, and must be above 0. |
| `parameters.max_amount` | `u64` | Most to take from the funder, in atoms, including the Token 2022 transfer fee of the reward mint. |
| `remaining_accounts_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts only `TransferHookReward`. |
| `remaining_accounts_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_accounts_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts only `TransferHookReward`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_accounts_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. The emission is set in its tail. |
| `reward_vault` | Yes | No | Reward vault of the slot. Must equal the vault recorded in the slot. |
| `reward_mint` | No | No | Reward mint of the slot. Must equal the mint recorded in the slot. |
| `funder_token_account` | Yes | No | Token account that pays the reward, for the reward mint. `funder` must be its authority. |
| `funder` | No | Yes | Signs and pays the reward. |
| `authority` | No | Yes | Signs. Must be the authority recorded in the slot. |
| `token_program` | No | No | Token program of the reward mint, Token or Token 2022. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slice from the `remaining_accounts_info` argument. Only `TransferHookReward` is accepted.

#### Checks and Effects

* The pool must have the LiquidityMining extension, `index` must be 0 or 1, the slot must be initialized, and the mint and vault must be the ones of the slot. `authority` must be the authority of the slot.
* `emission_per_second` is above 0.
* Pool reward state is brought up to now first. The previous window must have ended, and no ineligible reward from it may be waiting (see `withdraw_ineligible_rewards`). A slot with no emission yet counts as ended.
* The open time must not be before now and at most 30 days after it. The window must be 1 to 365 days.
* The whole reward for the window is paid up front into the vault: the amount is computed with rounding up, the Token 2022 transfer fee is added so the vault receives exactly that, and the total must not exceed `max_amount`.
* Sets the open time, end time and rate of the slot and the last update time to the open time. Rewards then accrue to in-range positions in proportion to their liquidity while the pool `liquidity` is above 0.

#### Events

[`EvtSetRewardEmission`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtsetrewardemission) is emitted with the resulting window and rate.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPoolType` | The pool does not have the LiquidityMining extension. |
| `InvalidRewardIndex` | `index` is not 0 or 1. |
| `RewardUninitialized` | The slot is not initialized. |
| `InvalidRewardMint` | `reward_mint` is not the mint of the slot. |
| `InvalidRewardVault` | `reward_vault` is not the vault of the slot. |
| `InvalidPermission` | `authority` is not the authority of the slot. |
| `InvalidRewardState` | The previous emission has not ended, or it left ineligible rewards that were not withdrawn. |
| `InvalidParameters` | `emission_per_second` is 0, `open_time` is in the past or more than 30 days ahead, or the window is outside 1 to 365 days. |
| `ExceededSlippage` | The amount to fund plus the transfer fee is above `max_amount`. |
| `MathOverflow` | `end_time` is before `open_time`, or an amount overflows. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` other than `TransferHookReward`. |

#### SDK

`client.reward.setRewardEmission`.

### claim\_reward

Pays out the pending amount of one reward slot, summed over every range slot of a position. The NFT owner can call it, or a delegate with the ClaimReward permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `reward_index` | `u8` | Reward slot, 0 or 1. |
| `min_amount` | `u64` | Least reward the receiver must get, in atoms, after the Token 2022 transfer fee of the reward mint. 0 skips the check. |
| `remaining_account_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts only `TransferHookReward`. |
| `remaining_account_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_account_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts only `TransferHookReward`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_account_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | No | No | The pool. Only read. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `position` | Yes | No | Position array whose pending rewards for the slot are reset. |
| `nft_account` | No | No | Token account that holds the position NFT, with amount 1 of the mint stored in `position`. |
| `signer` | No | Yes | Owner of the NFT token account, or its delegate with ClaimReward. |
| `reward_vault` | Yes | No | Reward vault of the slot. Must equal the vault recorded in the slot. |
| `reward_mint` | No | No | Reward mint of the slot. Must equal the mint recorded in the slot. |
| `user_token_account` | Yes | No | Token account that receives the reward, for the reward mint. A delegate must pass the associated token account of the NFT owner. |
| `token_program` | No | No | Token program of the reward mint, Token or Token 2022. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slice from the `remaining_account_info` argument. Only `TransferHookReward` is accepted. No tick arrays are needed.

#### Checks and Effects

* The signer must be the NFT owner, or a delegate with a zero delegated amount and the ClaimReward permission. A delegate can only pay into the associated token account of the NFT owner for the reward mint.
* The pool must have the LiquidityMining extension, `reward_index` must be 0 or 1, the slot must be initialized, and the mint and vault must be those of the slot.
* Sums the pending reward of the slot over every range slot of the position and sets it to 0. Only rewards already accrued to the range slots are included, so refresh first (or have added or removed liquidity).
* The vault pays the full amount. The receiver gets it minus the Token 2022 transfer fee, checked against `min_amount`, and 0 skips the check. A memo is written first if the receiver requires incoming transfer memos. Nothing is paid when the total is 0.

#### Events

[`EvtClaimReward`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtclaimreward) is emitted only when the amount paid is above 0.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the owner of the NFT token account, and is not its delegate. |
| `DelegatedAmountNonZero` | The signer is the delegate of the NFT token account, but the delegated amount is not 0. |
| `InvalidPermission` | The signer is a delegate and the position or limit order permission bits do not include the permission this instruction needs. |
| `IncorrectATA` | A delegate signed and `user_token_account` is not the associated token account of the NFT owner. |
| `InvalidPoolType` | The pool does not have the LiquidityMining extension. With the derived reward vault the call fails earlier with the Anchor error `AccountNotInitialized` (3012), because the vault does not exist. |
| `InvalidRewardIndex` | `reward_index` is not 0 or 1. |
| `RewardUninitialized` | The slot is not initialized. With the derived reward vault the call fails earlier with the Anchor error `AccountNotInitialized` (3012), because the vault does not exist. |
| `InvalidRewardMint` | `reward_mint` is not the mint of the slot. |
| `InvalidRewardVault` | `reward_vault` is not the vault of the slot. |
| `ExceededSlippage` | The reward after the transfer fee is below `min_amount`. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

`client.reward.claimReward`.

### withdraw\_ineligible\_rewards

Withdraws the rewards that were emitted while the pool `liquidity` was 0, meaning no liquidity was in range at the current price, after the emission has ended. The reward authority of the slot signs and picks the receiving account.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `index` | `u8` | Reward slot, 0 or 1. |
| `min_amount` | `u64` | Least reward the receiver must get, in atoms, after the Token 2022 transfer fee of the reward mint. 0 skips the check. |
| `remaining_accounts_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts only `TransferHookReward`. |
| `remaining_accounts_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_accounts_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts only `TransferHookReward`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_accounts_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. Reward state is accrued and the ineligible counter is reset. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `reward_vault` | Yes | No | Reward vault of the slot. Must equal the vault recorded in the slot. |
| `reward_mint` | No | No | Reward mint of the slot. Must equal the mint recorded in the slot. |
| `receiver_token_account` | Yes | No | Token account that receives the reward. The authority chooses it, and it does not need to belong to the wallet that funded the reward. |
| `authority` | No | Yes | Signs. Must be the authority recorded in the slot. |
| `token_program` | No | No | Token program of the reward mint, Token or Token 2022. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slice from the `remaining_accounts_info` argument. Only `TransferHookReward` is accepted.

#### Checks and Effects

* The pool must have the LiquidityMining extension, `index` must be 0 or 1, the slot must be initialized, the mint and vault must be those of the slot, and `authority` must be the authority of the slot.
* The pool reward state is brought up to now. The emission must have been set and must have ended, meaning the last update time equals the end time and is above 0.
* The amount is the seconds counted with zero pool liquidity times `emission_per_second`, divided by 2^64, rounded down. The counter is reset to 0 and the amount is checked against `min_amount` after the transfer fee.
* If the amount is 0 the call returns without moving tokens and without an event. Otherwise the vault pays the full amount, the receiver gets it minus the Token 2022 transfer fee, and a memo is written first if the receiver requires incoming transfer memos.
* The slot only counts as finished for `set_reward_emission` after this counter is 0, so withdraw before starting a new emission.

#### Events

[`EvtWithdrawIneligibleReward`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtwithdrawineligiblereward) is emitted only when the amount is above 0.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPoolType` | The pool does not have the LiquidityMining extension. |
| `InvalidRewardIndex` | `index` is not 0 or 1. |
| `RewardUninitialized` | The slot is not initialized. |
| `InvalidRewardMint` | `reward_mint` is not the mint of the slot. |
| `InvalidRewardVault` | `reward_vault` is not the vault of the slot. |
| `InvalidPermission` | `authority` is not the authority of the slot. |
| `InvalidRewardState` | No emission was ever set, or it has not ended yet. |
| `ExceededSlippage` | The amount after the transfer fee is below `min_amount`. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

`client.reward.withdrawIneligibleRewards`.

### claim\_partner\_fee

Pays out the accrued partner fee of a pool to receiver accounts chosen by the partner. Only the pool partner can call it.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `parameters` | `ClaimPartnerFeeParameters` | Claim request. The fields follow. |
| `parameters.max_amount_x` | `u64` | Cap on the token X partner fee to claim, in atoms, before the Token 2022 transfer fee. |
| `parameters.max_amount_y` | `u64` | Cap on the token Y partner fee to claim, in atoms, before the Token 2022 transfer fee. |
| `parameters.min_amount_x` | `u64` | Least token X the receiver must get, in atoms, after the Token 2022 transfer fee of mint X. 0 skips the check. |
| `parameters.min_amount_y` | `u64` | Least token Y the receiver must get, in atoms, after the Token 2022 transfer fee of mint Y. 0 skips the check. |
| `remaining_accounts_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_accounts_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_accounts_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_accounts_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool. The pending partner fee is reduced. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `receiver_token_x` | Yes | No | Token account that receives token X. Only used when the claim in token X is above 0, but it must still be passed. Any account of the X mint. |
| `receiver_token_y` | Yes | No | Token account that receives token Y. Only used when the claim in token Y is above 0, but it must still be passed. Any account of the Y mint. |
| `signer` | No | Yes | Signs. Must be the pool partner, which for a dynamic-config pool is the pool creator authority of the config. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `memo_program` | No | No | Memo program. The program writes a memo before paying into a Token 2022 account that requires incoming transfer memos. Fixed address `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Remaining Accounts

Transfer hook slices from the `remaining_accounts_info` argument. `TransferHookX` and `TransferHookY` are accepted. No tick arrays are needed.

#### Checks and Effects

* The signer must equal the partner stored in the pool. Pools without a partner (static-config and launch pools) have no one who can claim.
* Claims the smaller of the pending fee and the cap, per token, and reduces the pending fee by that amount.
* `min_amount_x` and `min_amount_y` are checked against the claimed amounts after the Token 2022 transfer fee. This runs even when the amount is 0, so a minimum above 0 fails then.
* If both claimed amounts are 0 the call returns without an event. Otherwise the reserve pays the full claimed amount, the receiver gets it minus the transfer fee, and a memo is written first if the receiver requires incoming transfer memos.

#### Events

[`EvtClaimPartnerFee`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtclaimpartnerfee) is emitted only when at least one amount is above 0.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAuthority` | The signer is not the pool partner. |
| `ExceededSlippage` | The amount of token X or Y after the transfer fee is below `min_amount_x` or `min_amount_y`. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

`client.pool.claimPartnerFee`.

### claim\_protocol\_fee2

Pays out the accrued protocol fee of one token of a pool to the protocol. Only the fixed protocol fee authority can sign, so integrators cannot call it.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `max_amount` | `u64` | Cap on the protocol fee to claim, in atoms, before the Token 2022 transfer fee. |
| `min_amount` | `u64` | Least amount the receiver must get, in atoms, after the Token 2022 transfer fee. 0 skips the check. |
| `remaining_accounts_info` | `RemainingAccountsInfo` | Describes the transfer hook accounts at the start of the remaining accounts. This instruction accepts `TransferHookX` and `TransferHookY`. |
| `remaining_accounts_info.slices` | `Vec<RemainingAccountsSlice>` | Slices in order. The program takes `length` accounts for each slice from the front of the remaining accounts. An empty list means no transfer hook accounts. |
| `remaining_accounts_info.slices[].accounts_type` | `AccountsType` | Which mint the slice serves, one of `TransferHookX`, `TransferHookY`, `TransferHookReferral` and `TransferHookReward`. This instruction accepts `TransferHookX` and `TransferHookY`. Each type may appear once with accounts. Any other type fails with InvalidRemainingAccountSlice. |
| `remaining_accounts_info.slices[].length` | `u8` | Number of remaining accounts in the slice. A slice of length 0 is skipped. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `receiver_token_account` | Yes | No | Token account that receives the fee. Its mint decides the token claimed: the token X mint claims `protocol_fee_x`, the token Y mint claims `protocol_fee_y`. It must be owned by the token program of that mint. |
| `token_x_mint` | No | No | Token X mint. Must equal `pool.token_x_mint`. |
| `token_y_mint` | No | No | Token Y mint. Must equal `pool.token_y_mint`. |
| `token_x_program` | No | No | Token program that owns the token X mint, Token or Token 2022. Must be the program the transfers of token X run through. |
| `token_y_program` | No | No | Token program that owns the token Y mint, Token or Token 2022. Must be the program the transfers of token Y run through. |
| `pool` | Yes | No | The pool. The pending protocol fee is reduced. |
| `reserve_x` | Yes | No | Token X reserve of the pool. Must equal `pool.reserve_x`. |
| `reserve_y` | Yes | No | Token Y reserve of the pool. Must equal `pool.reserve_y`. |
| `signer` | No | Yes | Signs. Must be the fixed protocol fee authority. Fixed address `FkU5rQCWQM131skHCpcEbK8P1JrQGsBgqXe55w525SSF`. |
| `pool_authority` | No | No | Pool authority. It signs token transfers out of reserves and vaults, and holds no data. Fixed address `FSUXyUKbTJ4A5Ccz5M6Uo4J2myc3RsDKTPU9vZwyeXru`. |

#### Remaining Accounts

Transfer hook slices from the `remaining_accounts_info` argument. `TransferHookX` and `TransferHookY` are accepted.

#### Checks and Effects

* The signer must be the fixed address of the protocol fee authority.
* The mint of `receiver_token_account` must be the token X or token Y mint of the pool, and the account must be owned by the token program passed for that token.
* Claims the smaller of the pending protocol fee of that token and `max_amount`, reduces the pending fee, and checks the amount after the transfer fee against `min_amount`.
* If the amount is 0 the call returns without moving tokens and without an event. Otherwise the reserve pays the full amount and the receiver gets it minus the Token 2022 transfer fee. No memo is written.

#### Events

[`EvtClaimProtocolFee`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtclaimprotocolfee) is written to the log, not as an inner instruction, and only when the amount is above 0. This instruction has no event authority account.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAccount` | The mint of `receiver_token_account` is not a pool mint, or the account is not owned by the token program passed for it. |
| `ExceededSlippage` | The amount after the transfer fee is below `min_amount`. |
| `MissingRemainingAccountForTransferHook` | A mint in a transfer has a transfer hook program and no transfer hook slice with accounts of the matching type was passed. |
| `NoTransferHookProgram` | A transfer hook slice with accounts was passed for a mint that has no transfer hook program. |
| `InvalidRemainingAccountSlice` | A slice has an `accounts_type` that this instruction does not accept. |
| `DuplicatedRemainingAccountTypes` | Two slices with accounts share the same `accounts_type`. |
| `InsufficientRemainingAccounts` | A slice `length` is larger than the number of remaining accounts left. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.claimProtocolFee2`. Only the protocol fee authority can sign it.

### create\_operator\_account

Creates an `Operator` account that gives an address a set of operator permissions. Only the admin can call it.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `permission` | `u128` | Permission bitmask, 1 to 63. Bit 0 CreateConfigKey, 1 RemoveConfigKey, 2 SetPoolStatus, 3 InitializeReward, 4 UpdateRewardAuthority, 5 UpdatePartnerFee. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `operator` | Yes | No | New operator account. One per whitelisted address. PDA with seeds `"operator"`, `whitelisted_address`. |
| `whitelisted_address` | No | No | Address that receives the permissions. It does not sign. Can be any address. |
| `signer` | No | Yes | Signs. Must be the admin key of the program. |
| `payer` | Yes | Yes | Pays the rent of the operator account. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The signer must be the admin key, which is fixed in the program and not part of the IDL.
* `permission` is above 0 and uses only bits 0 to 5.
* Creates the account with the whitelisted address and the bitmask. The operator account is 48 bytes after the discriminator.

#### Events

No event is emitted, although the instruction lists the event accounts.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAdmin` | The signer is not the admin key. |
| `InvalidPermission` | `permission` is 0 or has a bit above bit 5. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.createOperatorAccount`.

### close\_operator\_account

Closes an `Operator` account and removes its permissions. Only the admin can call it.

#### Arguments

This instruction takes no arguments.

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `operator` | Yes | No | Operator account to close. |
| `signer` | No | Yes | Signs. Must be the admin key of the program. |
| `rent_receiver` | Yes | No | Receives the lamports of the closed account. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The signer must be the admin key.
* Closes the account and sends its lamports to `rent_receiver`. Pools and configs are not affected.

#### Events

No event is emitted, although the instruction lists the event accounts.

#### Errors

| Error | Cause |
| - | - |
| `InvalidAdmin` | The signer is not the admin key. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.closeOperatorAccount`.

### create\_static\_config

Creates a `StaticConfig` that fixes the fees, tick spacing, collect fee mode, activation type and extensions of pools created from it. Needs an operator with the CreateConfigKey permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `index` | `u64` | Config index, part of the config address. A used index fails because the account exists. |
| `config_parameters` | `StaticConfigParameters` | Config settings. The fields follow. |
| `config_parameters.pool_fees` | `PoolFeeParameters` | Fee schedule of the pool. |
| `config_parameters.pool_fees.base_fee_parameter` | `BaseFeeConfigParameters` | Base fee, 32 bytes in two fields. |
| `config_parameters.pool_fees.base_fee_parameter.base_fee_mode` | `u8` | Base fee schedule. 0 Fixed, 1 TimeSchedulerLinear, 2 TimeSchedulerExponential, 3 MarketCapSchedulerLinear, 4 MarketCapSchedulerExponential. |
| `config_parameters.pool_fees.base_fee_parameter.data` | `[u8;31]` | Mode-specific parameters, encoded and validated as in the base fee data table above. Unused bytes must be zero. |
| `config_parameters.pool_fees.dynamic_fee_parameter` | `Option<DynamicFeeParameters>` | `None` turns the dynamic fee off. `Some` turns it on and the fields below apply. |
| `config_parameters.pool_fees.dynamic_fee_parameter.max_volatility_accumulator` | `u32` | Cap on the volatility accumulator. At most 16777215. One unit is 1 over 10000 of a tick of price movement from the reference price. |
| `config_parameters.pool_fees.dynamic_fee_parameter.variable_fee_control` | `u32` | Scale of the variable fee. At most 16777215. The variable fee numerator is the ceiling of `variable_fee_control * volatility_accumulator^2 / 100000000000`, in units of 1 over 1000000000. At the cap it must not exceed 990000000. |
| `config_parameters.pool_fees.dynamic_fee_parameter.filter_period` | `u16` | Seconds. Must be above 0 and below `decay_period`. Swaps closer than this to the last reference update or significant swap keep the volatility reference unchanged. |
| `config_parameters.pool_fees.dynamic_fee_parameter.decay_period` | `u16` | Seconds. Must be above `filter_period` and at most 3600. After this long the volatility reference resets to 0. The reference also resets once it is more than 3600 seconds old, even when significant swaps keep arriving. |
| `config_parameters.pool_fees.dynamic_fee_parameter.reduction_factor` | `u16` | Basis points, 1 to 10000. Between the filter and decay periods the volatility reference becomes the accumulator times this value over 10000. |
| `config_parameters.pool_fees.dynamic_fee_parameter.min_delta_tick_for_significant_swap` | `u16` | Must be above 0. A swap counts as significant when its price movement, measured in ticks, is at least this value. |
| `config_parameters.tick_spacing` | `u16` | Distance between usable tick ids. 1 to 256 inclusive. |
| `config_parameters.collect_fee_mode` | `u8` | 0 OutputToken, 1 OnlyY. Any other value fails to convert. |
| `config_parameters.activation_type` | `u8` | Unit of the activation point and schedules of pools from this config. 0 Slot, 1 Timestamp. |
| `config_parameters.extensions` | `u8` | Bitmask of extensions for pools from this config. Only bit 0 (LiquidityMining) is allowed, so 0 or 1. |
| `config_parameters.pool_creator_authority` | `Option<Pubkey>` | Address that must sign pool creation from this config. `None` makes the config public, stored as the default key. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `config` | Yes | No | New static config account paid by `payer`. PDA with seeds `"s_config"`, `index` (u64 little-endian). |
| `operator` | No | No | Operator account of the signer. Its `whitelisted_address` must equal `signer` and its permission bitmask must include CreateConfigKey. |
| `signer` | No | Yes | Signs. Must be the operator wallet. |
| `payer` | Yes | Yes | Pays the rent of the config account. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The operator must be the signer with CreateConfigKey.
* Fees are validated as in pool creation: base fee mode and data as in the base fee data table, and the dynamic fee fields as in the argument table.
* `tick_spacing` is 1 to 256, `collect_fee_mode` and `activation_type` are valid values, and `extensions` has no bits other than bit 0. ActivationAccess is not allowed on static configs.
* Stores the settings. Pools created later copy them, so closing or replacing a config does not change existing pools.

#### Events

[`EvtCreateStaticConfig`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtcreatestaticconfig) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPermission` | The operator is not the signer or lacks CreateConfigKey. |
| `InvalidParameters` | A fee value, the tick spacing or `extensions` is out of range, including the ActivationAccess bit. |
| `MathOverflow` | A linear fee schedule whose `cliff_fee_numerator` is below `reduction_factor * number_of_period`, or an exponential schedule with a `reduction_factor` of 10000 or more. |
| `InvalidBaseFeeMode` | `base_fee_mode` is not 0 to 4. |
| `TypeCastFailed` | `collect_fee_mode` or `activation_type` is not 0 or 1. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.createStaticConfig`.

### create\_dynamic\_config

Creates a `DynamicConfig` that authorizes one pool creator authority to create pools with its own parameters and makes it the partner of those pools. Needs an operator with the CreateConfigKey permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `index` | `u64` | Config index, part of the config address. A used index for the same authority fails because the account exists. |
| `config_parameters` | `DynamicConfigParameters` | Config settings. The fields follow. |
| `config_parameters.permission` | `u128` | Bitmask of config permissions, 0 or 1. Bit 0 CreatePoolWithoutMintValidation skips the per-mint token badge and Token 2022 extension checks for pools of this config. The Token 2022 native mint is still rejected, and an `OnlyY` pool whose token Y is not wrapped SOL or USDC still needs `token_badge_y`. |
| `config_parameters.partner_fee_bps` | `u16` | Partner share of the protocol fee for pools of this config, in basis points, 0 to 5000. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `config` | Yes | No | New dynamic config account paid by `payer`. PDA with seeds `"d_config"`, `pool_creator_authority`, `index` (u64 little-endian). |
| `operator` | No | No | Operator account of the signer. Its `whitelisted_address` must equal `signer` and its permission bitmask must include CreateConfigKey. |
| `signer` | No | Yes | Signs. Must be the operator wallet. |
| `payer` | Yes | Yes | Pays the rent of the config account. |
| `system_program` | No | No | System program. Fixed address `11111111111111111111111111111111`. |
| `pool_creator_authority` | No | No | Address that will sign pool creation from this config and becomes the partner of its pools. Must not be the default key. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The operator must be the signer with CreateConfigKey.
* `permission` is at most 1 and `partner_fee_bps` is at most 5000.
* `pool_creator_authority` is not the default key.
* Stores the settings. Pools created later copy `partner_fee_bps`, and an operator can change a pool partner fee with `update_partner_fee`.

#### Events

[`EvtCreateDynamicConfig`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtcreatedynamicconfig) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPermission` | The operator is not the signer or lacks CreateConfigKey. |
| `InvalidParameters` | `permission` is above 1, `partner_fee_bps` is above 5000, or `pool_creator_authority` is the default key. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.createDynamicConfig`.

### close\_config

Closes a static or a dynamic config and sends its rent to `rent_receiver`. Needs an operator with the RemoveConfigKey permission.

#### Arguments

This instruction takes no arguments.

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `static_config` (optional) | Yes | No | Static config to close. Pass it to close a static config. When omitted, pass the program ID as placeholder. |
| `dynamic_config` (optional) | Yes | No | Dynamic config to close. Pass it to close a dynamic config. When omitted, pass the program ID as placeholder. |
| `operator` | No | No | Operator account of the signer. Its `whitelisted_address` must equal `signer` and its permission bitmask must include RemoveConfigKey. |
| `signer` | No | Yes | Signs. Must be the operator wallet. |
| `rent_receiver` | Yes | No | Receives the lamports of the closed config. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The operator must be the signer with RemoveConfigKey.
* Exactly one of `static_config` and `dynamic_config` must be passed.
* Closes it and sends its lamports to `rent_receiver`. Pools already created from the config keep working, because pool creation copies the settings.

#### Events

[`EvtCloseConfig`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtcloseconfig) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPermission` | The operator is not the signer or lacks RemoveConfigKey. |
| `InvalidParameters` | Both configs were passed, or neither. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.closeConfig`.

### set\_pool\_status

Sets the status bitmask of a pool, which disables or enables swaps and adding liquidity. Needs an operator with the SetPoolStatus permission. Removing liquidity cannot be disabled.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `status` | `u16` | Bitmask of disabled actions, 0 to 3. Bit 0 disables swaps. Bit 1 disables adding liquidity, which also blocks `open_position`, `expand_position` and `open_limit_order`. 0 enables everything. Must differ from the current status. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool whose status changes. |
| `operator` | No | No | Operator account of the signer. Its `whitelisted_address` must equal `signer` and its permission bitmask must include SetPoolStatus. |
| `signer` | No | Yes | Signs. Must be the operator wallet. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The operator must be the signer with SetPoolStatus.
* `status` is at most 3 and differs from the current status.
* Stores the status. Swaps and deposits fail with InvalidActivationAccess while their bit is set. Withdrawals, claims and closes are not affected.

#### Events

[`EvtSetPoolStatus`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtsetpoolstatus) is emitted.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPermission` | The operator is not the signer or lacks SetPoolStatus. |
| `InvalidParameters` | `status` is above 3 or equals the current status. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.setPoolStatus`.

### update\_partner\_fee

Sets the partner fee share of a pool that has a partner. Needs an operator with the UpdatePartnerFee permission.

#### Arguments

| Name | Type | Meaning |
| - | - | - |
| `partner_fee_bps` | `u16` | Partner share of the protocol fee, in basis points, 0 to 5000 inclusive. |

#### Accounts

| Account | Writable | Signer | Description |
| - | - | - | - |
| `pool` | Yes | No | The pool whose partner fee share changes. |
| `operator` | No | No | Operator account of the signer. Its `whitelisted_address` must equal `signer` and its permission bitmask must include UpdatePartnerFee. |
| `signer` | No | Yes | Signs. Must be the operator wallet. |
| `event_authority` | No | No | Event authority, the standard Anchor event CPI account. |
| `program` | No | No | The DLMM Pro program, required by event CPI. |

#### Checks and Effects

* The operator must be the signer with UpdatePartnerFee.
* `partner_fee_bps` is at most 5000, and the pool must have a partner, which only pools from a dynamic config have.
* Stores the new share. It applies to swaps after the change, and fees already accrued stay as they are.

#### Events

[`EvtUpdatePartnerFee`](https://docs.meteora.ag/developer-guides/dlmm-pro/program/events#evtupdatepartnerfee) is emitted with the old and new values.

#### Errors

| Error | Cause |
| - | - |
| `InvalidPermission` | The operator is not the signer or lacks UpdatePartnerFee. |
| `InvalidParameters` | `partner_fee_bps` is above 5000, or the pool has no partner. |

#### SDK

Not wrapped by the SDK. Build it with `client.program.methods.updatePartnerFee`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.