# CLMM pools

Tapp's Concentrated Liquidity Market Maker (CLMM) is an advanced pool type modelled\
on Uniswap v3. Liquidity providers choose a price range (a pair of "ticks") and\
only trade within that range earns fees. The logic lives in the `clmm::clmm`\
Move module.

This document walks through the main data types and entry functions so integrators\
can understand how CLMM pools operate.

## Key data types

### Config

* `authority` – address allowed to manage global settings.
* `pending_authority` – temporary storage when transferring authority.
* `fee_amount_tick_spacing` – mapping from fee tier to tick spacing.

### Pool

A pool tracks its price and liquidity discretely across ticks:

```move
struct Pool has key, store {
    pool_addr: address,
    asset_a: address,
    asset_b: address,
    tick_spacing: u64,
    fee_rate: u64,
    reserve_a: u64,
    reserve_b: u64,
    liquidity: u128,
    current_sqrt_price: u128,
    current_tick_index: I64,
    fee_growth_global_a: u128,
    fee_growth_global_b: u128,
    tick_indexes: SimpleMap<u64, BitVector>,
    ticks: BigOrderedMap<I64, Tick>,
    positions: BigOrderedMap<u64, Position>,
    position_index: u64,
}
```

### Position

Holds the liquidity amount supplied between a lower and upper tick index and the\
fees owed to that position.

### Tick

Represents a single price step. Each tick stores the `sqrt_price`, liquidity\
net values when crossing the tick and fee growth data used for fee accounting.

## Creating a pool

`create_pool(pool_signer, assets, fee, rest_args, creator)` deploys a new pool\
resource. `assets` contains the two coin types; `fee` must match a supported\
fee tier. `rest_args` encodes the initial square‑root price. The tick spacing is\
looked up from `fee_amount_tick_spacing`.

A `PoolCreated` event records the pool address and initial parameters.

## Adding liquidity

Liquidity can be added in two ways:

* `add_liquidity(pool_signer, position_idx, stream, creator)` – `stream` encodes`delta_liquidity`, `max_amount_a`, `max_amount_b`, `lower_tick_idx` and`upper_tick_idx`.
* `add_liquidity_fix_token(pool_signer, position_idx, stream, creator)` – the\
  stream encodes a fixed amount of A or B to deposit and whether the amount is\
  in token A or token B.

If `position_idx` is `none`, the function opens a new position via `open_position`.\
Otherwise it modifies the existing position. The pool calculates how much of\
each token must be deposited based on the current price and tick range, updates\
liquidity and emits `LiquidityAdded`.

Returned values are the actual token amounts deposited and optionally the newly\
created position index.

## Removing liquidity

`remove_liquidity(pool_signer, position_idx, stream, creator)` burns part of a\
position's liquidity. The stream provides `delta_liquidity`, `min_amount_a` and`min_amount_b`. Fees earned by the position are first collected with`internal_collect_fee`. If after removing liquidity the position balance reaches\
zero it is closed. A `LiquidityRemoved` event logs the withdrawal.

The function returns the withdrawn token amounts (including fees) and optionally\
the index of any position that was burned.

## Swapping tokens

`swap(pool_signer, stream, creator)` performs trades against the pool. The\
stream encodes:

1. `a2b` – `true` to swap A for B, `false` for B → A.
2. `fixed_amount_in` – indicates whether `amount` is the exact input or the\
   desired output.
3. `amount` – amount being swapped.
4. `amount_limit` – slippage limit depending on `fixed_amount_in`.
5. `sqrt_price` – limit price expressed as the square‑root price X64.

The pool iterates across ticks using `swap_in_pool`, updating the current price\
and liquidity along the path. A `Swapped` event contains the final amounts and\
post‑swap price.

## Fees

Every swap accrues fees in proportion to the traded amount. Global accumulators`fee_growth_global_a` and `fee_growth_global_b` track the total fee growth per\
unit of liquidity. When adding or removing liquidity the pool updates a\
position's fee data so providers can later claim their earned fees via`collect_fee`.

## Utility functions

The module exposes several helpers for off‑chain queries:

* `current_sqrt_price(address)`
* `liquidity(address)`
* `reserve_a(address)` and `reserve_b(address)`
* `current_tick_idx(address)`
* `fee_rate(address)`
* `get_positions(address)` and `get_position(address, index)`
* `calculate_swap_result(address, a2b, fixed_amount_in, amount)`

These assist front‑ends in showing pool state and estimating trade outcomes.

## Events

CLMM emits many events to make indexing simple:

* `PoolCreated`
* `LiquidityAdded`
* `LiquidityRemoved`
* `Swapped`
* `OpenPositionEvent`
* `ClosePositionEvent`
* `CollectFeeEvent`
* `CollectProtocolFeeEvent`

## Security checks

The Move code contains numerous assertions that enforce valid tick ranges,\
prevent overflows when updating liquidity and fees, and ensure the swap logic\
cannot violate pool invariants. Transactions that violate these conditions\
abort, protecting both LPs and traders.

***

Concentrated liquidity pools provide fine‑grained control over where liquidity is\
active and can achieve greater capital efficiency than constant product pools.\
Understanding the module internals helps builders integrate with Tapp's CLMM and\
visualise liquidity positions accurately.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tapp-exchange.gitbook.io/tapp-exchange/developer-docs/clmm.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
