Implements liquidity mining rewards to incentivize liquidity provision.
Core Data Structures
RewarderManager
The main controller that manages all rewarders for a pool:
structRewarderManager{rewarders:vector<Rewarder>,// Up to 5 rewarderspoints_released:u128,// Total points released over timepoints_growth_global:u128,// Global points growth ratelast_updated_time:u64,// Last settlement timestamp}
Rewarder
Individual rewarder configuration for a specific reward token:
structRewarder{reward_coin:TypeName,// Type of reward tokenemissions_per_second:u128,// Emission rate (tokens per second)growth_global:u128,// Accumulated growth factor}
RewarderGlobalVault
Centralized storage for all reward token balances:
Core Functionality
Initialization
The module automatically creates a shared RewarderGlobalVault during initialization:
This vault serves as the central repository for all reward tokens across all pools.
Rewarder Management
Adding a New Rewarder
Adds a new rewarder for the specified CoinType
Validates that the coin type doesn't already exist
Enforces the maximum limit of 5 rewarders per pool
Initializes with zero emissions (must be configured separately)
Updating Emission Rates
Updates the emission rate for a specific rewarder
Automatically settles pending rewards before updating
Validates sufficient balance for 24 hours of rewards at the new rate
Requires vault balance ≥ 86400 * new_emissions for rate increases
Reward Distribution
Settlement Process
The settlement process:
Time Validation: Ensures time progression is valid
Liquidity Check: Skips settlement if no liquidity or no time passed
Growth Calculation: For each rewarder with non-zero emissions:
Points Update: Updates global points tracking using a constant multiplier
Token Management
Depositing Rewards
Adds reward tokens to the global vault
Creates new balance entry if token type doesn't exist
Emits DepositEvent for tracking
Returns the final balance amount
Emergency Withdrawal
Admin-only function for emergency token withdrawal
Requires AdminCap authorization
Emits EmergentWithdrawEvent for auditability
API Reference
Query Functions
Balance Queries
Rewarder Information
Individual Rewarder Data
Manager State
Friend Functions
These functions are restricted to the ferra_clmm::pool module:
Events
RewarderInitEvent
Emitted during module initialization:
DepositEvent
Emitted when rewards are deposited:
EmergentWithdrawEvent
Emitted during emergency withdrawals:
Error Codes
Error 1: Maximum number of rewarders exceeded (limit: 5)
Error 2: Rewarder for this coin type already exists
Error 3: Invalid time progression (current_time < last_updated_time)
Error 4: Insufficient balance in vault for new emission rate
Error 5: Rewarder not found for the specified coin type
Mathematical Formulas
Growth Calculation
For each rewarder during settlement:
Points Calculation
Using a constant multiplier (2^64 * 10^6):
Balance Validation
For emission rate increases:
Best Practices
Regular Settlement: Settle rewards before major pool operations
Sufficient Funding: Maintain adequate vault balances for sustained rewards
Gradual Rate Changes: Avoid sudden large emission rate changes
Monitor Events: Track all reward-related events for proper accounting
Emergency Procedures: Have clear protocols for emergency withdrawals
public fun deposit_reward<CoinType>(
global_config: &GlobalConfig,
vault: &mut RewarderGlobalVault,
reward: Balance<CoinType>
) : u64
public fun emergent_withdraw<CoinType>(
_admin_cap: &AdminCap,
global_config: &GlobalConfig,
vault: &mut RewarderGlobalVault,
amount: u64
) : Balance<CoinType>
// Get balance of specific token type in vault
public fun balance_of<CoinType>(vault: &RewarderGlobalVault) : u64
// Get reference to all balances
public fun balances(vault: &RewarderGlobalVault) : &Bag
// Get rewarder index for a coin type
public fun rewarder_index<CoinType>(manager: &RewarderManager) : Option<u64>
// Get all rewarders
public fun rewarders(manager: &RewarderManager) : vector<Rewarder>
// Get growth values for all rewarders
public fun rewards_growth_global(manager: &RewarderManager) : vector<u128>
// Access specific rewarder (read-only)
public fun borrow_rewarder<CoinType>(manager: &RewarderManager) : &Rewarder
// Get emission rate
public fun emissions_per_second(rewarder: &Rewarder) : u128
// Get growth global value
public fun growth_global(rewarder: &Rewarder) : u128
// Get reward coin type
public fun reward_coin(rewarder: &Rewarder) : TypeName
// Get last update timestamp
public fun last_update_time(manager: &RewarderManager) : u64
// Get global points data
public fun points_growth_global(manager: &RewarderManager) : u128
public fun points_released(manager: &RewarderManager) : u128
// Create new manager
public(friend) fun new() : RewarderManager
// Add rewarder
public(friend) fun add_rewarder<CoinType>(manager: &mut RewarderManager)
// Access mutable rewarder
public(friend) fun borrow_mut_rewarder<CoinType>(manager: &mut RewarderManager) : &mut Rewarder
// Settle rewards
public(friend) fun settle(manager: &mut RewarderManager, liquidity: u128, current_time: u64)
// Update emissions
public(friend) fun update_emission<CoinType>(/*...*/)
// Withdraw rewards
public(friend) fun withdraw_reward<CoinType>(vault: &mut RewarderGlobalVault, amount: u64) : Balance<CoinType>