A secure and efficient ERC20 token staking pool that allows users to earn rewards for staking their tokens.
The StakingPool contract enables users to:
- Stake ERC20 tokens
- Earn rewards based on staking duration
- Unstake tokens at any time
- Claim accumulated rewards
The contract includes security features like reentrancy protection and proper access control.
- Token Staking: Users can stake any ERC20 token
- Reward System: Rewards accumulate based on staking duration
- Admin Controls: Contract owner can fund the reward pool and adjust reward rates
- Security: Protected against reentrancy attacks
- Events: Comprehensive event logging for all major actions
The contract inherits from:
ReentrancyGuard: Prevents reentrancy attacksOwnable: Provides basic authorization control
- StakeInfo Struct
struct StakeInfo {
uint256 amount; // Amount of tokens staked
uint256 timestamp; // When the stake was made
uint256 lastRewardTimestamp; // Last time rewards were claimed
}- State Variables
stakingToken: The ERC20 token being stakedtotalStaked: Total amount of tokens stakedrewardRate: Reward rate (tokens per day per 1000 tokens)rewardPool: Available rewards for distribution
stake(uint256 _amount): Stake tokensunstake(uint256 _amount): Unstake tokensclaimRewards(): Claim accumulated rewards
fundRewardPool(uint256 _amount): Fund the reward poolsetRewardRate(uint256 _newRate): Update reward rate
Staked(address indexed user, uint256 amount)Unstaked(address indexed user, uint256 amount)RewardClaimed(address indexed user, uint256 amount)RewardPoolFunded(uint256 amount)
Rewards are calculated using the formula:
reward = (stakedAmount * rewardRate * timeStaked) / (1000 * 1 days)
Where:
stakedAmount: Amount of tokens stakedrewardRate: Current reward ratetimeStaked: Time since last reward claim
-
Reentrancy Protection
- All external functions are protected with
nonReentrantmodifier - Prevents reentrancy attacks during token transfers
- All external functions are protected with
-
Access Control
- Admin functions restricted to contract owner
- User functions accessible to all
-
Input Validation
- Amount checks
- Balance checks
- Transfer validations
The contract includes comprehensive tests using Foundry:
-
Basic Operations
- Staking
- Unstaking
- Reward claiming
-
Edge Cases
- Insufficient stake
- Multiple stakes
- Reward calculations
To run tests:
forge test- Deploy an ERC20 token contract
- Deploy the StakingPool contract with the token address
- Fund the reward pool with tokens
- Set the initial reward rate
// Approve tokens
token.approve(stakingPoolAddress, amount);
// Stake tokens
stakingPool.stake(amount);
// Claim rewards
stakingPool.claimRewards();
// Unstake tokens
stakingPool.unstake(amount);- Always check token approvals before staking
- Monitor reward pool balance
- Consider gas costs for frequent operations
- Keep track of reward rates
MIT License