> For the complete documentation index, see [llms.txt](https://docs.ferra.ag/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ferra.ag/integration/damm/smart-contract/pool-module.md).

# Pool Module

### Overview

The Pool module provides:

* Core swap functionality with dynamic and scheduled fees
* Concentrated liquidity management
* Flash swap and flash loan capabilities
* Position and fee management
* Reward distribution integration
* Whitelist and activation controls

### Data Structures

#### Pool Struct

```move
struct Pool<phantom CoinTypeA, phantom CoinTypeB> has key, store {
    id: UID,
    creator: address,
    parameters: PairParameters,
    coin_a: Balance<CoinTypeA>,
    coin_b: Balance<CoinTypeB>,
    liquidity: u128,
    whitelisted: VecSet<address>,
    collect_fee_mode: u8,
    is_quote_y: bool,
    fee_growth_global_a: u128,
    fee_growth_global_b: u128,
    fee_protocol_coin_a: u64,
    fee_protocol_coin_b: u64,
    tick_manager: TickManager,
    rewarder_manager: RewarderManager,
    position_manager: PositionManager,
    is_pause: bool,
    index: u64,
    url: String,
}
```

**Key Fields:**

| Field                   | Type              | Description                                 |
| ----------------------- | ----------------- | ------------------------------------------- |
| `creator`               | `address`         | Pool creator address                        |
| `parameters`            | `PairParameters`  | Fee scheduler and dynamic fee configuration |
| `coin_a`, `coin_b`      | `Balance`         | Token balances in the pool                  |
| `liquidity`             | `u128`            | Current active liquidity                    |
| `whitelisted`           | `VecSet<address>` | Pre-activation whitelist                    |
| `collect_fee_mode`      | `u8`              | Fee collection mode                         |
| `is_quote_y`            | `bool`            | Whether token Y is quote                    |
| `fee_growth_global_a/b` | `u128`            | Global fee growth trackers                  |
| `fee_protocol_coin_a/b` | `u64`             | Accumulated protocol fees                   |

#### Receipt Structs

**FlashSwapReceipt**

```move
struct FlashSwapReceipt<phantom CoinTypeA, phantom CoinTypeB> {
    pool_id: ID,
    a2b: bool,
    pay_amount: u64,
}
```

**AddLiquidityReceipt**

```move
struct AddLiquidityReceipt<phantom CoinTypeA, phantom CoinTypeB> {
    pool_id: ID,
    amount_a: u64,
    amount_b: u64,
}
```

**FlashLoanReceipt**

```move
struct FlashLoanReceipt {
    pool_id: ID,
    loan_a: bool,
    amount: u64,
    fee_amount: u64,
}
```

#### CalculatedSwapResult

```move
struct CalculatedSwapResult has copy, drop, store {
    amount_in: u64,
    amount_out: u64,
    atob: bool,
    collect_fee_on_input: bool,
    fee_amount: u64,
    base_fee: u64,
    dynamic_fee: u64,
    before_sqrt_price: u128,
    after_sqrt_price: u128,
    is_exceed: bool,
    step_results: vector<SwapStepResult>,
}
```

### Core Functions

#### 1. Position Management

**Open Position**

```move
public fun open_position<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    tick_lower_idx: u32,
    tick_upper_idx: u32,
    ctx: &mut TxContext
): Position
```

Creates a new liquidity position within the specified tick range.

**Parameters:**

| Parameter        | Description                                            |
| ---------------- | ------------------------------------------------------ |
| `tick_lower_idx` | Lower tick index (as u32, converted to I32 internally) |
| `tick_upper_idx` | Upper tick index                                       |

**Close Position**

```move
public fun close_position<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position: Position
)
```

Closes an empty position and removes it from the registry.

**Lock Position**

```move
public fun lock_position<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position: &mut Position,
    lock_until: u64,
    clock: &Clock,
)
```

Locks a position until a specified timestamp, preventing liquidity removal.

#### 2. Liquidity Management

**Add Liquidity**

```move
public fun add_liquidity<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position: &mut Position,
    delta_liquidity: u128,
    clock: &Clock,
): AddLiquidityReceipt<CoinTypeA, CoinTypeB>
```

Adds liquidity to an existing position by specifying liquidity amount.

**Add Liquidity with Fixed Amount**

```move
public fun add_liquidity_fix_coin<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position: &mut Position,
    amount: u64,
    is_fixed_a: bool,
    clock: &Clock,
): AddLiquidityReceipt<CoinTypeA, CoinTypeB>
```

Adds liquidity by fixing one token amount.

**Repay Add Liquidity**

```move
public fun repay_add_liquidity<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    coin_a: Balance<CoinTypeA>,
    coin_b: Balance<CoinTypeB>,
    receipt: AddLiquidityReceipt<CoinTypeA, CoinTypeB>,
)
```

Completes liquidity addition by providing required tokens.

**Remove Liquidity**

```move
public fun remove_liquidity<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position: &mut Position,
    liquidity_amount: u128,
    clock: &Clock,
): (Balance<CoinTypeA>, Balance<CoinTypeB>)
```

Removes liquidity from a position and returns token balances.

#### 3. Trading

**Flash Swap**

```move
public fun flash_swap<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    a2b: bool,
    by_amount_in: bool,
    amount: u64,
    sqrt_price_limit: u128,
    clock: &Clock,
    ctx: &TxContext,
): (Balance<CoinTypeA>, Balance<CoinTypeB>, FlashSwapReceipt<CoinTypeA, CoinTypeB>)
```

Executes a flash swap operation.

**Parameters:**

| Parameter          | Description                            |
| ------------------ | -------------------------------------- |
| `a2b`              | `true` if swapping from CoinA to CoinB |
| `by_amount_in`     | `true` if specifying input amount      |
| `amount`           | Token amount to swap                   |
| `sqrt_price_limit` | Price limit for slippage protection    |

**Repay Flash Swap**

```move
public fun repay_flash_swap<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    coin_a: Balance<CoinTypeA>,
    coin_b: Balance<CoinTypeB>,
    receipt: FlashSwapReceipt<CoinTypeA, CoinTypeB>,
)
```

Completes flash swap by providing input tokens.

**Calculate Swap Result**

```move
public fun calculate_swap_result<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    a2b: bool,
    by_amount_in: bool,
    amount: u64,
    clock: &Clock
): CalculatedSwapResult
```

Simulates a swap without executing, useful for quotes.

#### 4. Flash Loans

**Create Flash Loan**

```move
public fun flash_loan<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    is_coin_a: bool,
    amount: u64,
    clock: &Clock
): (Balance<CoinTypeA>, Balance<CoinTypeB>, FlashLoanReceipt)
```

Borrows tokens for atomic operations.

**Repay Flash Loan**

```move
public fun repay_flash_loan<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    coin_a: Balance<CoinTypeA>,
    coin_b: Balance<CoinTypeB>,
    receipt: FlashLoanReceipt,
)
```

Repays flash loan with fee.

#### 5. Fee and Reward Collection

**Collect Position Fees**

```move
public fun collect_fee<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position: &Position,
    recalculate: bool,
): (Balance<CoinTypeA>, Balance<CoinTypeB>)
```

Collects accumulated trading fees for a position.

**Collect Rewards**

```move
public fun collect_reward<CoinTypeA, CoinTypeB, RewardCoin>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position: &Position,
    rewarder_vault: &mut RewarderGlobalVault,
    recalculate: bool,
    clock: &Clock,
): Balance<RewardCoin>
```

Collects accumulated rewards for a position.

**Collect Protocol Fees**

```move
public fun collect_protocol_fee<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    ctx: &mut TxContext
)
```

Collects protocol fees (admin only).

#### 6. Fee Configuration

**Update Fee Rate**

```move
public fun update_fee_rate<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    new_fee_rate: u64,
    ctx: &TxContext,
)
```

Updates the base fee rate (admin only).

**Enable/Disable Fee Scheduler**

```move
public fun enable_fee_scheduler<X, Y>(
    config: &GlobalConfig,
    pool: &mut Pool<X, Y>,
    ctx: &TxContext,
)

public fun disable_fee_scheduler<X, Y>(
    config: &GlobalConfig,
    pool: &mut Pool<X, Y>,
    ctx: &TxContext,
)
```

**Enable/Disable Dynamic Fee**

```move
public fun enable_dynamic_fee<X, Y>(
    config: &GlobalConfig,
    pool: &mut Pool<X, Y>,
    ctx: &TxContext,
)

public fun disable_dynamic_fee<X, Y>(
    config: &GlobalConfig,
    pool: &mut Pool<X, Y>,
    ctx: &TxContext,
)
```

#### 7. Whitelist Management

**Add Whitelist**

```move
public fun add_whitelist<X, Y>(
    config: &GlobalConfig,
    pool: &mut Pool<X, Y>,
    users: vector<address>,
    ctx: &mut TxContext,
)
```

Adds addresses to pre-activation whitelist.

**Remove Whitelist**

```move
public fun remove_whitelist<X, Y>(
    config: &GlobalConfig,
    pool: &mut Pool<X, Y>,
    users: vector<address>,
    ctx: &mut TxContext,
)
```

Removes addresses from whitelist.

#### 8. Pool Management

**Pause/Unpause Pool**

```move
public fun pause<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    ctx: &TxContext,
)

public fun unpause<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    ctx: &TxContext,
)
```

### Query Functions

#### Pool Information

```move
// Get current liquidity
public fun liquidity<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): u128

// Get current sqrt price
public fun current_sqrt_price<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): u128

// Get current tick index
public fun current_tick_index<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): I32

// Get total fee rate at current time
public fun get_total_fee_rate<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    current_timestamp: u64
): u64

// Get pool balances
public fun balances<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>
): (&Balance<CoinTypeA>, &Balance<CoinTypeB>)

// Check if pool is paused
public fun is_pause<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): bool

// Get protocol fees
public fun protocol_fee<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): (u64, u64)

// Get fee growth globals
public fun fees_growth_global<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): (u128, u128)
```

#### Position Information

```move
// Check if position exists
public fun is_position_exist<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    position_id: ID
): bool

// Get position token amounts
public fun get_position_amounts<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    position_id: ID,
): (u64, u64)

// Get position fees
public fun get_position_fee<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    position_id: ID,
): (u64, u64)

// Get position points
public fun get_position_points<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    position_id: ID,
): u128

// Get position rewards
public fun get_position_rewards<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    position_id: ID,
): vector<u64>

// Fetch multiple positions
public fun fetch_positions<CoinTypeA, CoinTypeB>(
    pool: &Pool<CoinTypeA, CoinTypeB>,
    start: vector<ID>,
    limit: u64
): vector<PositionInfo>
```

#### Calculate and Update Functions

```move
// Calculate and update position fee
public fun calculate_and_update_fee<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position_id: ID
): (u64, u64)

// Calculate and update position points
public fun calculate_and_update_points<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position_id: ID,
    clock: &Clock
): u128

// Calculate and update position rewards
public fun calculate_and_update_rewards<CoinTypeA, CoinTypeB>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    position_id: ID,
    clock: &Clock
): vector<u64>
```

### Events

#### SwapEvent

```move
struct SwapEvent has copy, drop, store {
    atob: bool,
    pool: ID,
    amount_in: u64,
    amount_out: u64,
    fee_a: u64,
    fee_b: u64,
    base_fee: u64,
    dynamic_fee: u64,
    collect_fee_on_input: bool,
    vault_a_amount: u64,
    vault_b_amount: u64,
    before_sqrt_price: u128,
    after_sqrt_price: u128,
    steps: u64,
}
```

#### AddLiquidityEvent

```move
struct AddLiquidityEvent has copy, drop, store {
    pool: ID,
    position: ID,
    tick_lower: I32,
    tick_upper: I32,
    liquidity: u128,
    after_liquidity: u128,
    amount_a: u64,
    amount_b: u64,
}
```

#### RemoveLiquidityEvent

```move
struct RemoveLiquidityEvent has copy, drop, store {
    pool: ID,
    position: ID,
    tick_lower: I32,
    tick_upper: I32,
    liquidity: u128,
    after_liquidity: u128,
    amount_a: u64,
    amount_b: u64,
}
```

#### OpenPositionEvent

```move
struct OpenPositionEvent has copy, drop, store {
    pool: ID,
    tick_lower: I32,
    tick_upper: I32,
    position: ID,
}
```

#### LockPositionEvent

```move
struct LockPositionEvent has copy, drop, store {
    pool: ID,
    position: ID,
    lock_until: u64,
}
```

#### FlashLoanEvent

```move
struct FlashLoanEvent has copy, drop, store {
    pool: ID,
    loan_a: bool,
    amount: u64,
    fee_amount: u64,
    vault_a_amount: u64,
    vault_b_amount: u64,
}
```

### Error Codes

| Code | Constant                     | Description                                |
| ---- | ---------------------------- | ------------------------------------------ |
| 400  | `E_INVALID_AMOUNT`           | Invalid token amount                       |
| 401  | `E_LIQUIDITY_OVERFLOW`       | Liquidity calculation overflow             |
| 403  | `E_LIQUIDITY_ZERO`           | Zero liquidity provided                    |
| 405  | `E_INSUFFICIENT_AMOUNT`      | Insufficient token amount                  |
| 406  | `E_SWAP_AMOUNT_IN_OVERFLOW`  | Swap input amount overflow                 |
| 407  | `E_SWAP_AMOUNT_OUT_OVERFLOW` | Swap output amount overflow                |
| 408  | `E_SWAP_FEE_AMOUNT_OVERFLOW` | Fee amount overflow                        |
| 410  | `E_POOL_TICK_OUT_OF_RANGE`   | Tick outside valid range                   |
| 412  | `E_POOL_ID_MISMATCH`         | Pool ID mismatch                           |
| 413  | `E_POOL_PAUSED`              | Pool is paused                             |
| 417  | `E_REWARDER_NOT_FOUND`       | Rewarder not initialized                   |
| 418  | `E_SWAP_ZERO_OUTPUT`         | Swap resulted in zero output               |
| 419  | `E_POSITION_POOL_MISMATCH`   | Position doesn't belong to pool            |
| 423  | `E_INVALID_LOCK_TIME`        | Invalid lock duration                      |
| 424  | `E_POSITION_LOCKED`          | Position is currently locked               |
| 430  | `E_FLASH_LOAN_PAUSED`        | Flash loans are disabled                   |
| 431  | `E_PENDING_ADD_LIQUIDITY`    | Pending liquidity operation                |
| 432  | `E_NOT_WHITELISTED`          | Address not whitelisted for pre-activation |
| 433  | `E_MAX_TOTAL_FEE_EXCEEDED`   | Total fee exceeds maximum                  |
| 434  | `E_NO_PERMISSION`            | Insufficient permissions                   |
| 435  | `E_CLIFF_FEE_BELOW_BASE_FEE` | Cliff fee must be >= base fee              |

### Fee Collection Modes

#### COLLECT\_FEE\_ON\_BOTH (0)

Fees are always collected from the input token.

#### COLLECT\_FEE\_ON\_QUOTE (1)

Fees are collected from the quote token:

* If `is_quote_y = true` and swapping A→B: fee from output (B)
* If `is_quote_y = true` and swapping B→A: fee from input (B)
* If `is_quote_y = false` and swapping A→B: fee from input (A)
* If `is_quote_y = false` and swapping B→A: fee from output (A)

### Usage Examples

#### Complete Swap Flow

```move
// 1. Calculate expected output
let result = pool::calculate_swap_result<USDC, TOKEN>(
    &pool,
    true,           // a2b
    true,           // by_amount_in
    1000000,        // 1 USDC
    &clock
);

// 2. Execute flash swap
let (coin_a, coin_b, receipt) = pool::flash_swap<USDC, TOKEN>(
    &config,
    &mut pool,
    true,           // a2b
    true,           // by_amount_in
    1000000,        // amount
    min_sqrt_price, // slippage protection
    &clock,
    ctx
);

// 3. Repay with input token
pool::repay_flash_swap<USDC, TOKEN>(
    &config,
    &mut pool,
    coin::into_balance(payment_coin),
    balance::zero(),
    receipt
);
```

#### Adding Liquidity

```move
// 1. Open position
let position = pool::open_position<USDC, TOKEN>(
    &config,
    &mut pool,
    tick_lower,
    tick_upper,
    ctx
);

// 2. Add liquidity with fixed amount
let receipt = pool::add_liquidity_fix_coin<USDC, TOKEN>(
    &config,
    &mut pool,
    &mut position,
    1000000,    // fix 1 USDC
    true,       // is_fixed_a
    &clock
);

// 3. Get required amounts
let (amount_a, amount_b) = pool::add_liquidity_pay_amount(&receipt);

// 4. Repay
pool::repay_add_liquidity<USDC, TOKEN>(
    &config,
    &mut pool,
    coin::into_balance(coin_a),
    coin::into_balance(coin_b),
    receipt
);
```

### Security Considerations

1. **Slippage Protection**: Always use `sqrt_price_limit` when swapping
2. **Receipt Validation**: Carefully validate receipts before repaying
3. **Permission Checks**: Only admins can pause/unpause pools
4. **Lock Period**: Positions can be locked to prevent premature withdrawal
5. **Whitelist Check**: Pre-activation swaps require whitelist membership


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.ferra.ag/integration/damm/smart-contract/pool-module.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
