// 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); } }