Spaces:
No application file
No application file
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
contract EfikcoinStakingPool is Ownable { | |
IERC20 public efikToken; | |
uint256 public rewardRate = 10; // 10 EFIK per day per 1000 staked | |
uint256 public totalStaked; | |
struct StakeInfo { | |
uint256 amount; | |
uint256 startTime; | |
uint256 rewardClaimed; | |
} | |
mapping(address => StakeInfo) public stakes; | |
event Staked(address indexed user, uint256 amount); | |
event RewardClaimed(address indexed user, uint256 reward); | |
event Withdrawn(address indexed user, uint256 amount); | |
constructor(address _efikTokenAddress) { | |
efikToken = IERC20(_efikTokenAddress); | |
} | |
function stake(uint256 _amount) external { | |
require(_amount > 0, "Stake amount must be greater than zero"); | |
efikToken.transferFrom(msg.sender, address(this), _amount); | |
StakeInfo storage user = stakes[msg.sender]; | |
user.amount += _amount; | |
user.startTime = block.timestamp; | |
totalStaked += _amount; | |
emit Staked(msg.sender, _amount); | |
} | |
function calculateReward(address _user) public view returns (uint256) { | |
StakeInfo memory user = stakes[_user]; | |
uint256 duration = block.timestamp - user.startTime; | |
uint256 daysStaked = duration / 1 days; | |
return (user.amount * rewardRate * daysStaked) / 1000; | |
} | |
function claimReward() external { | |
uint256 reward = calculateReward(msg.sender); | |
require(reward > 0, "No reward available"); | |
stakes[msg.sender].rewardClaimed += reward; | |
stakes[msg.sender].startTime = block.timestamp; | |
efikToken.transfer(msg.sender, reward); | |
emit RewardClaimed(msg.sender, reward); | |
} | |
function withdrawStake() external { | |
StakeInfo storage user = stakes[msg.sender]; | |
require(user.amount > 0, "No staked amount"); | |
uint256 reward = calculateReward(msg.sender); | |
uint256 totalAmount = user.amount + reward; | |
efikToken.transfer(msg.sender, totalAmount); | |
totalStaked -= user.amount; | |
delete stakes[msg.sender]; | |
emit Withdrawn(msg.sender, totalAmount); | |
} | |
function updateRewardRate(uint256 _newRate) external onlyOwner { | |
rewardRate = _newRate; | |
} | |
function emergencyWithdraw() external onlyOwner { | |
uint256 balance = efikToken.balanceOf(address(this)); | |
efikToken.transfer(owner(), balance); | |
} | |
} |