The Staking Contract allows users to stake tokens and earn rewards over time on the Stellar blockchain. This is a production-ready implementation with comprehensive features and security measures.
✅ Time-Based Rewards - Earn rewards proportional to your stake and duration
✅ Flexible Staking - Stake and unstake at any time
✅ Separate Claiming - Claim rewards independently from staking
✅ Emergency Withdrawal - Quick exit option (forfeits rewards)
✅ Admin Controls - Configurable reward periods and amounts
✅ Multi-User Support - Fair distribution among all stakers
✅ Event Emission - Track all contract activities
✅ Comprehensive Tests - Full test coverage included
cargo build --release --target wasm32-unknown-unknowncargo test --package stellar-defi-toolkit --lib contracts::staking::testscargo run --example staking// Stake 1000 tokens
staking_contract.stake(&user_address, &1_000_000_000);// View earned rewards
let earned = staking_contract.get_earned(&user_address);// Claim all earned rewards
let claimed = staking_contract.claim_rewards(&user_address);// Unstake 500 tokens (keeps rewards)
staking_contract.unstake(&user_address, &500_000_000);staking_contract.initialize(
&admin_address,
&staking_token_address,
&reward_token_address,
&17280, // 1 day reward period
);// Distribute 10,000 reward tokens over the period
staking_contract.notify_reward_amount(&admin_address, &10_000_000_000);- Admin sets reward amount for a specific duration (e.g., 10,000 tokens over 7 days)
- Reward rate is calculated automatically (e.g., ~1,428 tokens per day)
- Users stake tokens and start earning immediately
- Rewards accumulate proportionally based on:
- Amount staked
- Time staked
- Total pool size
- Users claim rewards at any time without unstaking
Initial State:
- Reward Pool: 10,000 REWARD tokens
- Duration: 7 days (120,960 ledgers)
- Reward Rate: ~0.083 REWARD per ledger
Day 1:
- Alice stakes 1,000 USDC
- Bob stakes 500 USDC
- Total Staked: 1,500 USDC
Day 2:
- Alice earned: ~952 REWARD (66.7% of daily rewards)
- Bob earned: ~476 REWARD (33.3% of daily rewards)
Day 3:
- Alice claims her 952 REWARD
- Alice still has 1,000 USDC staked
- Bob's rewards continue accumulating
Day 4:
- Bob unstakes 200 USDC
- Bob still has 300 USDC staked
- Bob's unclaimed rewards: ~1,428 REWARD
Stellar uses ledgers (≈5 seconds each):
| Duration | Ledgers |
|---|---|
| 1 minute | 12 |
| 1 hour | 720 |
| 1 day | 17,280 |
| 1 week | 120,960 |
| 1 month | 518,400 |
stake(user, amount)- Stake tokensunstake(user, amount)- Unstake tokensclaim_rewards(user)- Claim earned rewardsemergency_withdraw(user)- Withdraw all (forfeit rewards)get_staked_balance(user)- View staked amountget_earned(user)- View earned rewards
initialize(...)- Set up the contractnotify_reward_amount(admin, amount)- Add rewards
get_total_staked()- Total staked in contractget_reward_rate()- Current reward rateget_info()- All contract information
🔒 Authorization Checks - All actions require proper authentication
🔒 Overflow Protection - Safe math operations
🔒 Balance Validation - Comprehensive checks
🔒 Initialization Guard - Prevents double initialization
🔒 Admin Controls - Restricted administrative functions
The contract includes extensive tests:
# Run all staking tests
cargo test --package stellar-defi-toolkit --lib contracts::staking
# Run specific test
cargo test --package stellar-defi-toolkit --lib contracts::staking::tests::test_rewardsTest coverage includes:
- ✅ Initialization
- ✅ Staking/Unstaking
- ✅ Reward calculations
- ✅ Multiple users
- ✅ Edge cases
- ✅ Error conditions
- ✅ Emergency withdrawals
For detailed documentation, see:
- Full Documentation: docs/staking_contract.md
- Example Code: examples/staking.rs
- Contract Source: src/contracts/staking.rs
Reward users for providing liquidity to your protocol.
Distribute governance tokens to long-term holders.
Create yield opportunities for token holders.
Bootstrap network effects by rewarding early adopters.
Before deploying to production:
- Run all tests
- Conduct security audit
- Test with actual token contracts
- Verify reward token supply
- Set appropriate reward duration
- Configure admin keys securely
- Test emergency scenarios
- Document deployment parameters
- Set up monitoring and alerts
- Ensure you're staking/unstaking a positive amount
- Check your staked balance before unstaking
- Use
get_staked_balance()to verify
- Ensure you're using the correct admin address
- Verify admin authorization
- You must stake tokens before earning rewards
- Check if you have any staked balance
To calculate the Annual Percentage Yield:
APY = (reward_rate × 6,307,200 / total_staked) × 100
where:
- reward_rate = rewards per ledger
- 6,307,200 = ledgers per year (≈365.25 days)
- total_staked = total tokens staked
Example:
reward_rate = 0.083 REWARD per ledger
total_staked = 1,000,000 USDC
APY = (0.083 × 6,307,200 / 1,000,000) × 100
= 52.35%
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: See
/docsdirectory
MIT OR Apache-2.0
Built with ❤️ for the Stellar ecosystem