> 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
