Position Module
Manages liquidity position NFTs and their associated metadata.
Data Structures
Position
The main NFT struct representing position ownership:
struct Position has key, store {
id: UID, // Unique identifier
pool: ID, // Associated pool ID
index: u64, // Position index number
coin_type_a: TypeName, // First token type
coin_type_b: TypeName, // Second token type
name: String, // Display name
description: String, // Description
url: String, // Icon URL
tick_lower_index: I32, // Lower tick bound
tick_upper_index: I32, // Upper tick bound
liquidity: u128, // Current liquidity amount
lock_until: u64, // Lock expiration timestamp
}PositionInfo
The computational data for position calculations:
PositionManager
Central registry managing all positions:
PositionReward
Individual reward token tracking:
Core Functions
Position Creation
open_position<CoinTypeA, CoinTypeB>
Creates a new liquidity position NFT.
Parameters:
manager: Mutable reference to PositionManagerpool_id: ID of the target poolpool_index: Pool's index numbericon_url: URL for position icontick_lower_index: Lower bound of liquidity rangetick_upper_index: Upper bound of liquidity rangelock_until: Timestamp until position is lockedctx: Transaction context
Returns: New Position NFT
Example:
Liquidity Management
increase_liquidity
Adds liquidity to an existing position.
Parameters:
manager: Mutable reference to PositionManagerposition: Mutable reference to Position NFTdelta_liquidity: Amount of liquidity to addfee_growth_inside_a: Current fee growth for token Afee_growth_inside_b: Current fee growth for token Bpoints_growth_inside: Current points growthrewards_growth_inside: Vector of current reward growth rates
Returns: New total liquidity amount
decrease_liquidity
Removes liquidity from a position.
Parameters: Similar to increase_liquidity but removes instead of adds Additional Checks:
Validates position is not locked
Ensures sufficient liquidity exists
Fee Management
update_fee
Updates accumulated fees for a position.
reset_fee
Collects accumulated fees and resets counters.
Position Lifecycle
1. Creation
2. Liquidity Addition
3. Fee Collection
4. Liquidity Removal
5. Position Closure
Fee and Reward Management
Fee Calculation
Fees are calculated using the formula:
The system tracks fee growth both globally and per position to calculate accumulated fees accurately.
Multi-token Rewards
The rewards system supports multiple reward tokens simultaneously:
Reward Distribution
Rewards are distributed proportionally based on:
Position liquidity amount
Time in range
Growth rates specific to the position's tick range
Position Locking
Lock Mechanism
Positions can be locked until a specific timestamp to prevent premature liquidity removal:
Lock Validation
When decreasing liquidity, the system validates:
API Reference
Query Functions
Position Information
liquidity(position: &Position): u128- Get position liquiditytick_range(position: &Position): (I32, I32)- Get tick rangepool_id(position: &Position): ID- Get associated pool IDindex(position: &Position): u64- Get position index
Position Info Queries
info_liquidity(info: &PositionInfo): u128- Get liquidity from infoinfo_fee_owned(info: &PositionInfo): (u64, u64)- Get accumulated feesinfo_points_owned(info: &PositionInfo): u128- Get accumulated pointsinfo_rewards(info: &PositionInfo): &vector<PositionReward>- Get rewards
Manager Queries
is_position_exist(manager: &PositionManager, id: ID): bool- Check if position existsfetch_positions(manager: &PositionManager, start: vector<ID>, limit: u64): vector<PositionInfo>- Get multiple positions
Validation Functions
check_position_tick_range
Validates tick range parameters:
tick_lower < tick_upperTicks within valid bounds
Ticks align with tick spacing
is_empty
Checks if position can be closed:
Zero liquidity
No accumulated fees
No pending rewards
Examples
Complete Position Lifecycle Example
Batch Position Query Example
Best Practices
Position Management
Always validate tick ranges before creating positions
Check lock status before attempting to decrease liquidity
Update fees and rewards before liquidity changes
Use batch queries for efficient data retrieval
Error Handling
The module uses various assertion codes:
1: Fee overflow in token A/B2: Reward overflow3: Points overflow5: Invalid tick range6: Position not found7: Cannot close non-empty position8: Liquidity addition overflow9: Insufficient liquidity to remove10: Invalid reward index11: Position is locked
Gas Optimization
Use
fetch_positionsfor batch operationsCombine fee updates with liquidity changes
Close empty positions to free storage
Security Considerations
Position Ownership: Only the NFT holder can modify the position
Tick Validation: All tick ranges are validated for correctness
Overflow Protection: All arithmetic operations include overflow checks
Lock Enforcement: Locked positions cannot have liquidity decreased
Access Control: Critical functions are
friend-only
This documentation provides a comprehensive guide to the Ferra CLMM Position Management system. For additional technical details, refer to the source code and inline comments.
Last updated