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 pooltick_spacing
: Distance between ticksfee_rate
: Trading fee rateliquidity
: Current total liquiditycurrent_sqrt_price
: Square root of the current pricecurrent_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 indextick_upper_idx
: Upper tick indexlock_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 CoinBby_amount_in
: True if specifying input amountamount
: Token amountsqrt_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
Slippage Protection: Always use
sqrt_price_limit
when swapping to protect against slippageReceipt Validation: Carefully validate receipts before repaying
Permission Checks: Only admins can pause/unpause pools
Lock Period: Positions can be locked for specified time periods
Gas Optimization
Batch Operations: Group multiple operations in a single transaction
Efficient Calculations: Module uses optimized math libraries
Event Emission: Events are optimized to save gas
Error Codes
0
: Insufficient balance or invalid amount3
: Invalid liquidity amount4
: No tick available for swap5
: Insufficient amount for subtraction9
: Fee rate exceeds maximum11
: Invalid sqrt price limit13
: Pool is paused17
: Rewarder not found18
: No amount out from swap19
: Pool ID mismatch20
: Flash loan pool mismatch
Last updated