Pool Module

The pool module is the core component of the CLMM protocol, defining trading pairs and handling all operations related to trading and liquidity management.

Data Structures

Pool Struct

struct Pool<phantom CoinTypeA, phantom CoinTypeB> has key, store {
    id: UID,
    coin_a: Balance<CoinTypeA>,
    coin_b: Balance<CoinTypeB>,
    tick_spacing: u32,
    fee_rate: u64,
    liquidity: u128,
    current_sqrt_price: u128,
    current_tick_index: I32,
    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:

  • coin_a, coin_b: Balance of both token types in the pool

  • tick_spacing: Distance between ticks

  • fee_rate: Trading fee rate

  • liquidity: Current total liquidity

  • current_sqrt_price: Square root of the current price

  • current_tick_index: Current tick index

Receipt Structs

FlashSwapReceipt

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

AddLiquidityReceipt

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

FlashLoanReceipt

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

Core Functions

1. Position Management

Open Position

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

Description: Creates a new liquidity position within the specified tick range.

Parameters:

  • tick_lower_idx: Lower tick index

  • tick_upper_idx: Upper tick index

  • lock_until: Position lock timestamp

Close Position

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

2. Liquidity Management

Add Liquidity

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

Add Liquidity with Fixed Amount

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>

Remove Liquidity

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>)

3. Trading

Flash Swap

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,
): (Balance<CoinTypeA>, Balance<CoinTypeB>, FlashSwapReceipt<CoinTypeA, CoinTypeB>)

Parameters:

  • a2b: True if swapping from CoinA to CoinB

  • by_amount_in: True if specifying input amount

  • amount: Token amount

  • sqrt_price_limit: Price limit protection

Calculate Swap Result

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

4. Flash Loans

Create Flash Loan

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

Repay Flash Loan

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

5. Fee and Reward Collection

Collect Position Fees

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

Collect Rewards

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>

Collect Protocol Fees

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

Events

OpenPositionEvent

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

SwapEvent

struct SwapEvent has copy, drop, store {
    atob: bool,
    pool: ID,
    amount_in: u64,
    amount_out: u64,
    fee_amount: u64,
    vault_a_amount: u64,
    vault_b_amount: u64,
    before_sqrt_price: u128,
    after_sqrt_price: u128,
    steps: u64,
}

AddLiquidityEvent

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,
}

Utility Functions

Pool Information Queries

// 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 fee rate
public fun fee_rate<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): u64

// Get tick spacing
public fun tick_spacing<CoinTypeA, CoinTypeB>(pool: &Pool<CoinTypeA, CoinTypeB>): u32

Position Information Queries

// 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: &mut 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)

Rewarder Management

Initialize New Rewarder

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

Update Emission Rate

public fun update_emission<CoinTypeA, CoinTypeB, RewardCoin>(
    config: &GlobalConfig,
    pool: &mut Pool<CoinTypeA, CoinTypeB>,
    rewarder_vault: &RewarderGlobalVault,
    emissions_per_second: u128,
    clock: &Clock,
    ctx: &TxContext
)

Pool Management

Pause Pool

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

Unpause Pool

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

Update Fee Rate

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

Important Notes

Security Considerations

  1. Slippage Protection: Always use sqrt_price_limit when swapping to protect against slippage

  2. Receipt Validation: Carefully validate receipts before repaying

  3. Permission Checks: Only admins can pause/unpause pools

  4. Lock Period: Positions can be locked for specified time periods

Gas Optimization

  1. Batch Operations: Group multiple operations in a single transaction

  2. Efficient Calculations: Module uses optimized math libraries

  3. Event Emission: Events are optimized to save gas

Error Codes

  • 0: Insufficient balance or invalid amount

  • 3: Invalid liquidity amount

  • 4: No tick available for swap

  • 5: Insufficient amount for subtraction

  • 9: Fee rate exceeds maximum

  • 11: Invalid sqrt price limit

  • 13: Pool is paused

  • 17: Rewarder not found

  • 18: No amount out from swap

  • 19: Pool ID mismatch

  • 20: Flash loan pool mismatch

Last updated