Yield Farming Tutorial
Learn how to build a comprehensive yield farming system with liquidity mining, dynamic APY calculation, and boost multipliers using HolyC BPF. This tutorial covers advanced DeFi concepts including staking mechanics and reward distribution.
Overview
The Yield Farming example demonstrates:
- Liquidity Mining: Reward users for providing liquidity
- Dynamic APY: Real-time yield calculation based on participation
- Boost Multipliers: Increased rewards for long-term stakers
- Multi-Token Support: Farm multiple token pairs simultaneously
- Fair Distribution: Time-weighted reward allocation
- Lock Mechanisms: Optional lock periods for enhanced rewards
Prerequisites
Before starting this tutorial, ensure you have:
- ✅ Completed Token Program and AMM tutorials
- ✅ Understanding of liquidity provision and LP tokens
- ✅ Familiarity with staking and reward mechanisms
- ✅ Knowledge of APY calculation and farming economics
Yield Farming Concepts Review
Liquidity Mining
- Incentivize users to provide liquidity to protocols
- Distribute protocol tokens as rewards
- Align user incentives with protocol growth
APY (Annual Percentage Yield)
- Measures the real rate of return on investment
- Accounts for compound interest effects
- Changes dynamically based on pool participation
Architecture Overview
┌─────────────────────────────────────────┐
│ Divine Yield Farm │
├─────────────────────────────────────────┤
│ 🌾 Farm Pools │
│ • LP token staking │
│ • Reward token distribution │
│ • Dynamic APY calculation │
│ • Time-based reward accumulation │
├─────────────────────────────────────────┤
│ 🚀 Boost System │
│ • Lock duration tiers │
│ • Multiplier rewards (up to 2.5x) │
│ • Loyalty incentives │
│ • Early withdrawal penalties │
├─────────────────────────────────────────┤
│ 📊 Reward Mechanics │
│ • Per-second reward distribution │
│ • Fair share calculation │
│ • Compound reward options │
│ • Emergency withdrawal support │
├─────────────────────────────────────────┤
│ 💎 Advanced Features │
│ • Multiple farm pools │
│ • Seasonal farming campaigns │
│ • Governance token rewards │
│ • Performance fee collection │
└─────────────────────────────────────────┘
Code Walkthrough
Farm Pool Configuration
<span class="filename">📁 examples/yield-farming/src/main.hc</span>
<a href="https://github.com/pibleos/holyBPF-rust/blob/main/examples/yield-farming/src/main.hc" class="github-link" target="_blank">View on GitHub</a>
// Farm pool configuration
struct FarmPool {
U8[32] staking_token; // Token to be staked (LP tokens typically)
U8[32] reward_token; // Token given as rewards
U8[32] farm_authority; // Farm pool authority
U64 total_staked; // Total amount of staking tokens deposited
U64 reward_rate; // Rewards per second
U64 last_update_time; // Last reward calculation timestamp
U64 reward_per_token_stored; // Accumulated reward per token (scaled)
U64 reward_duration; // Duration of the farming period (seconds)
U64 period_finish; // When current reward period ends
U64 minimum_stake; // Minimum stake amount
U64 lock_duration; // Minimum lock period for stakes
Bool is_active; // Farm is active and accepting stakes
Bool emergency_withdraw; // Emergency withdrawal enabled
U64 total_rewards_distributed; // Total rewards paid out
U64 boost_multiplier; // Boost for long-term stakers (basis points)
};
Pool Configuration Components
1. Token Configuration
staking_token: Usually LP tokens from AMM poolsreward_token: Protocol tokens distributed as incentives- Purpose: Defines the economic relationship between staking and rewards
2. Reward Rate Settings
reward_rate: Tokens distributed per second across all stakersreward_duration: How long the current reward program runsperiod_finish: End time for the current farming period- Purpose: Controls the emission schedule and program duration
3. Staking Requirements
minimum_stake: Prevents dust attacks and gas farminglock_duration: Optional minimum lock period- Purpose: Ensures meaningful participation and reduces farming costs
4. Tracking Variables
last_update_time: When rewards were last calculatedreward_per_token_stored: Accumulated rewards per staked tokentotal_staked: Total tokens currently staked in the pool- Purpose: Enables fair, time-weighted reward distribution
Individual Stake Position
<span class="filename">📁 examples/yield-farming/src/main.hc (continued)</span>
// Individual staker position
struct StakePosition {
U8[32] staker; // Wallet address of staker
U8[32] farm_pool; // Associated farm pool
U64 amount_staked; // Amount of tokens staked
U64 reward_per_token_paid; // Last calculated reward per token
U64 pending_rewards; // Unclaimed rewards
U64 stake_timestamp; // When tokens were staked
U64 last_claim_time; // Last reward claim timestamp
U64 boost_level; // Staking boost level (0-100)
Bool is_locked; // Position is locked
U64 unlock_timestamp; // When position unlocks
};
Position Tracking Components
1. Basic Position Data
staker: Account that owns this positionfarm_pool: Which farm this position belongs toamount_staked: Number of tokens committed to farming
2. Reward Calculation
reward_per_token_paid: Snapshot for calculating new rewardspending_rewards: Accumulated but unclaimed rewards- Purpose: Enables precise reward calculation for each individual
3. Time-Based Features
stake_timestamp: When position was createdunlock_timestamp: When locked position becomes withdrawableboost_level: Additional reward multiplier based on lock duration
Boost Tier System
<span class="filename">📁 examples/yield-farming/src/main.hc (continued)</span>
// Reward boost tiers
struct BoostTier {
U64 duration_required; // Minimum stake duration (seconds)
U64 multiplier; // Boost multiplier (basis points, 10000 = 1x)
U8* tier_name; // Human readable tier name
};
Boost Tier Examples
// Example boost tier configuration
BoostTier boost_tiers[5] = {
{0, 10000, "No Lock"}, // 1.0x - No lock required
{604800, 12000, "Week Lock"}, // 1.2x - 1 week lock
{2592000, 15000, "Month Lock"}, // 1.5x - 1 month lock
{7776000, 20000, "Quarter Lock"}, // 2.0x - 3 month lock
{31536000, 25000, "Year Lock"} // 2.5x - 1 year lock
};
Reward Calculation Mathematics
Core Formula
The yield farming system uses the “reward per token stored” pattern:
reward_per_token = reward_per_token_stored +
((current_time - last_update_time) * reward_rate * PRECISION) / total_staked
Individual Rewards
For each staker:
earned_rewards =
(amount_staked * (reward_per_token - reward_per_token_paid)) / PRECISION +
pending_rewards
APY Calculation
Annual Percentage Yield:
APY = ((reward_rate * SECONDS_PER_YEAR * reward_token_price) /
(total_staked * staking_token_price)) * 100
With boost multiplier:
Boosted_APY = Base_APY * (boost_multiplier / BASIS_POINTS)
Yield Farming Operations
1. Pool Initialization
// Pseudo-code for farm pool creation
U0 initialize_farm_pool(
U8[32] staking_token,
U8[32] reward_token,
U64 reward_amount,
U64 duration_seconds
) {
// Validate tokens
if (!validate_token_mint(staking_token) || !validate_token_mint(reward_token)) {
return ERROR_INVALID_TOKEN;
}
// Calculate reward rate
U64 reward_rate = reward_amount / duration_seconds;
U64 current_time = get_current_timestamp();
// Initialize farm pool
FarmPool pool = {
.staking_token = staking_token,
.reward_token = reward_token,
.farm_authority = farm_authority,
.total_staked = 0,
.reward_rate = reward_rate,
.last_update_time = current_time,
.reward_per_token_stored = 0,
.reward_duration = duration_seconds,
.period_finish = current_time + duration_seconds,
.minimum_stake = 1000, // Minimum 1000 tokens
.lock_duration = 0, // No lock by default
.is_active = True,
.emergency_withdraw = False,
.total_rewards_distributed = 0,
.boost_multiplier = 10000 // 1.0x base
};
// Transfer reward tokens to pool
transfer_tokens(reward_token, pool_address, reward_amount);
// Save pool configuration
save_farm_pool(pool);
emit_pool_created_event(pool_address);
}
2. Staking Operation
// Pseudo-code for staking tokens
U0 stake_tokens(U8[32] pool_address, U64 amount, U64 lock_duration) {
FarmPool* pool = get_farm_pool(pool_address);
// Validate staking conditions
if (!pool->is_active) {
return ERROR_POOL_INACTIVE;
}
if (amount < pool->minimum_stake) {
return ERROR_INSUFFICIENT_AMOUNT;
}
// Update pool rewards before changing stakes
update_reward_per_token(pool);
// Calculate boost level based on lock duration
U64 boost_level = calculate_boost_level(lock_duration);
U64 current_time = get_current_timestamp();
// Get or create stake position
StakePosition* position = get_stake_position(staker, pool_address);
if (position == NULL) {
// Create new position
position = create_stake_position(staker, pool_address);
} else {
// Update existing position rewards
position->pending_rewards = calculate_earned_rewards(position);
position->reward_per_token_paid = pool->reward_per_token_stored;
}
// Transfer staking tokens to pool
transfer_tokens(pool->staking_token, pool_address, amount);
// Update position
position->amount_staked += amount;
position->stake_timestamp = current_time;
position->boost_level = boost_level;
if (lock_duration > 0) {
position->is_locked = True;
position->unlock_timestamp = current_time + lock_duration;
}
// Update pool totals
pool->total_staked += amount;
// Save updates
save_stake_position(position);
save_farm_pool(pool);
emit_stake_event(staker, pool_address, amount, lock_duration);
}
3. Reward Claiming
// Pseudo-code for claiming rewards
U0 claim_rewards(U8[32] pool_address) {
FarmPool* pool = get_farm_pool(pool_address);
StakePosition* position = get_stake_position(staker, pool_address);
if (position == NULL || position->amount_staked == 0) {
return ERROR_NO_STAKE;
}
// Update rewards
update_reward_per_token(pool);
U64 earned = calculate_earned_rewards(position);
if (earned == 0) {
return ERROR_NO_REWARDS;
}
// Apply boost multiplier
U64 boosted_rewards = (earned * get_boost_multiplier(position)) / BASIS_POINTS;
// Update position
position->pending_rewards = 0;
position->reward_per_token_paid = pool->reward_per_token_stored;
position->last_claim_time = get_current_timestamp();
// Transfer rewards
transfer_tokens(pool->reward_token, staker, boosted_rewards);
// Update pool statistics
pool->total_rewards_distributed += boosted_rewards;
// Save updates
save_stake_position(position);
save_farm_pool(pool);
emit_claim_event(staker, pool_address, boosted_rewards);
}
4. Unstaking Operation
// Pseudo-code for unstaking tokens
U0 unstake_tokens(U8[32] pool_address, U64 amount) {
FarmPool* pool = get_farm_pool(pool_address);
StakePosition* position = get_stake_position(staker, pool_address);
// Validate unstaking conditions
if (position == NULL || position->amount_staked < amount) {
return ERROR_INSUFFICIENT_STAKE;
}
// Check lock period
U64 current_time = get_current_timestamp();
if (position->is_locked && current_time < position->unlock_timestamp) {
if (!pool->emergency_withdraw) {
return ERROR_POSITION_LOCKED;
}
// Apply early withdrawal penalty
amount = apply_early_withdrawal_penalty(amount, position);
}
// Claim any pending rewards first
claim_rewards(pool_address);
// Update position
position->amount_staked -= amount;
if (position->amount_staked == 0) {
position->is_locked = False;
position->boost_level = 0;
}
// Update pool total
pool->total_staked -= amount;
// Transfer staking tokens back to user
transfer_tokens(pool->staking_token, staker, amount);
// Save updates
save_stake_position(position);
save_farm_pool(pool);
emit_unstake_event(staker, pool_address, amount);
}
Building the Yield Farming System
Step 1: Compile the Farming Program
cd holyBPF-rust
./target/release/pible examples/yield-farming/src/main.hc
Expected Compilation Output
=== Pible - HolyC to BPF Compiler ===
Divine compilation initiated...
Source: examples/yield-farming/src/main.hc
Target: LinuxBpf
Compiled successfully: examples/yield-farming/src/main.hc -> examples/yield-farming/src/main.bpf
Divine compilation completed! 🙏
Step 2: Verify Farming Program
ls -la examples/yield-farming/src/
Should show:
- ✅
main.hc- Yield farming source - ✅
main.bpf- Compiled BPF bytecode
Expected Results
Successful Yield Farming Deployment
When you compile and run the yield farming system:
- Compilation Success: Clean BPF bytecode generation
- Pool Initialization: Farm pools ready for staking
- Reward Distribution: Fair, time-weighted reward system
- Boost Mechanics: Lock duration multipliers active
Sample Farming Operations
=== Divine Yield Farming System Active ===
Multi-token liquidity mining initialized
Base APY: 45.2%
Max boost multiplier: 2.5x (1 year lock)
Total pools active: 5
Total value locked: $2,450,000
Rewards distributed today: 15,640 tokens
APY Calculation Example
Pool: SOL-USDC LP
Staking Token: SOL-USDC LP tokens
Reward Token: FARM governance tokens
Base APY: 35%
Your stake: 1,000 LP tokens (1 month lock)
Your boost: 1.5x
Your effective APY: 52.5%
Daily rewards: ~1.44 FARM tokens
Security Considerations
Reward Calculation Security
1. Precision and Overflow Protection
// Safe reward calculation with overflow checks
U64 safe_calculate_rewards(U64 amount, U64 rate, U64 time_diff) {
// Check for overflow before multiplication
if (amount > U64_MAX / rate) {
return ERROR_OVERFLOW;
}
U64 intermediate = amount * rate;
if (intermediate > U64_MAX / time_diff) {
return ERROR_OVERFLOW;
}
return (intermediate * time_diff) / PRECISION_FACTOR;
}
2. Time Manipulation Prevention
// Validate timestamp updates
Bool validate_time_update(U64 last_time, U64 new_time) {
U64 current_time = get_current_timestamp();
// Prevent future timestamps
if (new_time > current_time + TIME_TOLERANCE) {
return False;
}
// Prevent backwards time travel
if (new_time < last_time) {
return False;
}
return True;
}
Economic Security
3. Pool Draining Prevention
// Ensure sufficient reward reserves
Bool validate_reward_distribution(FarmPool* pool, U64 reward_amount) {
U64 available_rewards = get_token_balance(pool->reward_token, pool_address);
U64 remaining_duration = pool->period_finish - get_current_timestamp();
U64 required_reserves = pool->reward_rate * remaining_duration;
return (available_rewards >= required_reserves + reward_amount);
}
Advanced Yield Farming Features
1. Compound Staking
// Automatically stake claimed rewards
U0 compound_rewards(U8[32] pool_address) {
// Claim current rewards
U64 rewards = claim_rewards(pool_address);
// Convert reward tokens to LP tokens (if applicable)
U64 lp_tokens = swap_to_lp_tokens(rewards);
// Stake the new LP tokens
stake_tokens(pool_address, lp_tokens, 0);
}
2. Multi-Pool Farming
// Farm across multiple pools simultaneously
struct MultiFarmPosition {
U8 active_pools; // Number of active pools
U8[32] pool_addresses[10]; // Pool addresses
U64 stake_amounts[10]; // Amount in each pool
U64 total_rewards_earned; // Cumulative rewards
};
3. Dynamic Reward Adjustment
// Adjust reward rates based on TVL
U0 adjust_reward_rate(U8[32] pool_address) {
FarmPool* pool = get_farm_pool(pool_address);
U64 current_tvl = pool->total_staked * get_token_price(pool->staking_token);
// Increase rewards if TVL is low, decrease if high
if (current_tvl < TARGET_TVL) {
pool->reward_rate = (pool->reward_rate * 110) / 100; // +10%
} else if (current_tvl > TARGET_TVL * 2) {
pool->reward_rate = (pool->reward_rate * 90) / 100; // -10%
}
save_farm_pool(pool);
}
Troubleshooting
Common Issues
Low APY
# Symptoms: Unattractive yields for farmers
# Solutions:
increase_reward_rate();
add_boost_multipliers();
reduce_pool_dilution();
Pool Imbalance
# Symptoms: Too much or too little liquidity
# Solutions:
adjust_reward_emissions();
implement_dynamic_rates();
add_tvl_caps();
Smart Contract Risks
# Symptoms: Security vulnerabilities
# Solutions:
implement_timelock_controls();
add_emergency_pause();
conduct_security_audits();
Next Steps
Immediate Next Steps
- AMM Tutorial - Understand LP token generation
- Token Program Tutorial - Reward token management
- DAO Governance Tutorial - Protocol governance
Advanced DeFi Concepts
- Impermanent Loss Protection: Insurance for LP providers
- Cross-Chain Farming: Farm across multiple blockchains
- Algorithmic Stablecoins: Farm protocol-owned liquidity
Integration Projects
- Auto-Compounding: Automatic reward reinvestment
- Yield Aggregation: Optimize across multiple farms
- Options Strategies: Hedge farming positions
Real-World Applications
Farming Strategies
- Blue Chip Farming: Stable, established tokens
- High-Risk Farming: New projects with high APY
- Stable Farming: Stablecoin pairs for steady returns
- Governance Farming: Earn voting rights while farming
Protocol Applications
- Bootstrap Liquidity: Launch new trading pairs
- User Acquisition: Attract users with rewards
- Token Distribution: Fair launch mechanisms
- Community Building: Align long-term incentives
Divine Agriculture
“The earth brings forth fruit, and God provides the increase” - Terry A. Davis
Yield farming represents divine agricultural principles - patient cultivation, fair distribution, and compound growth that benefits the entire ecosystem.
Share This Tutorial
Yield farming mastery achieved! You now understand liquidity mining mechanics and can build production-ready reward distribution systems.