Skip to content

Instantly share code, notes, and snippets.

@Damkols
Last active September 6, 2023 13:32
Show Gist options
  • Save Damkols/e648d893079e928bf835881e1d7f95bd to your computer and use it in GitHub Desktop.
Save Damkols/e648d893079e928bf835881e1d7f95bd to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {ERC20} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
interface IStandardToken {
function balanceOf(address account) external view returns (uint256);
function totalSupply() external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function withdrawEther() external;
}
contract Stake is ERC20 {
IStandardToken standardToken;
struct stakeStruct{
uint amountStaked;
uint timeStaked; // keep track of when stake happened
}
uint public rewardPercent = 1;
mapping(address => stakeStruct) public userStakeMap;
constructor(address _standardToken) ERC20("RewardToken", "RWT"){
standardToken = IStandardToken(_standardToken);
}
event Staked(uint amountstake, uint totalAmountStaked, uint time);
event unStaked(uint amountstake, uint totalAmountStaked, uint time, uint rewards);
event claimReward( uint time, uint rewards);
function stake(uint _amount) external {
uint balance = standardToken.balanceOf(msg.sender);
require(balance >= 0, "You do not have enough tokens to stake");
bool status = standardToken.transferFrom(msg.sender, address(this), _amount);
require(status == true, "Transfer failed");
stakeStruct storage _stake = userStakeMap[msg.sender];
_stake.amountStaked += _amount;
_stake.timeStaked = block.timestamp;
emit Staked(_amount, _stake.amountStaked, block.timestamp);
}
function unStake(uint _amount) external {
stakeStruct storage _stake = userStakeMap[msg.sender];
if (_stake.amountStaked <= 0) {
revert("No stake found");
}
require(_amount <= _stake.amountStaked, "Cant unstake more than your stake balance");
bool status = standardToken.transfer(msg.sender, _amount);
require(status = true, "Transfer failed");
uint rewards = calculateRewards(msg.sender);
if(rewards > 0) {
_mint(msg.sender, rewards);
}
_stake.amountStaked -= _amount;
_stake.timeStaked = block.timestamp;
emit unStaked(_amount, _stake.amountStaked, block.timestamp, rewards); // emit the events
}
function withdrawEther() external {
standardToken.withdrawEther();
payable(msg.sender).transfer(address(this).balance);
}
function calculateRewards(address _staker) public view returns (uint) {
stakeStruct storage _stake = userStakeMap[_staker];
uint stakingDuration = ((block.timestamp - _stake.timeStaked) * 10e18) / 60;
return (_stake.amountStaked * stakingDuration * rewardPercent/ 100) / 10e18;
}
function claimRewards() public {
stakeStruct storage _stake = userStakeMap[msg.sender];
uint rewards = calculateRewards(msg.sender);
require(rewards > 0,"No rewards to claim");
_stake.timeStaked = block.timestamp;
_mint(msg.sender, rewards);
emit claimReward(block.timestamp, rewards); // emit the events
}
fallback() external payable {}
receive() external payable {}
}
//uint32 b = uint32(uint160(address(oXdead))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment