Created
September 4, 2023 13:07
-
-
Save Damkols/9d6ba67a2b715ee56733975df9a556d2 to your computer and use it in GitHub Desktop.
Staking contract that rewards users
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 transferFrom(address from, address to, uint256 value) external returns (bool); | |
function transfer(address to, uint256 value) external returns (bool); | |
function withdrawEther() external; | |
} | |
contract StakingContract is ERC20{ | |
IStandardToken standardToken; | |
// IStandardToken constant public standardToken = IStandardToken(0x8Bc4b37aff83FdA8a74d2b5732437037B801183e); | |
struct Stakings{ | |
uint amountStaked; | |
uint timeStaked; | |
uint rewardDuration; | |
} | |
uint public rewardPercent = 1; | |
mapping(address => Stakings) public userStakingsMap; | |
event Staked(uint amountstake, uint totalAmountStaked, uint time); | |
event unStaked(uint amountstake, uint totalAmountStaked, uint time, uint rewards); | |
event claimRewards( uint time, uint rewards); | |
constructor(address _standardToken) ERC20("RewardToken", "RWT"){ | |
standardToken = IStandardToken(_standardToken); | |
// rewardPercent = _rewardPercent; | |
} | |
function stake(uint amount) external { | |
uint balance = standardToken.balanceOf(msg.sender); | |
require(balance >= amount, "ERC20 insuficient balance"); | |
bool status = standardToken.transferFrom(msg.sender, address(this), amount); | |
require(status == true, "transfer Failed"); | |
Stakings storage _user = userStakingsMap[msg.sender]; | |
_user.amountStaked += amount; | |
_user.timeStaked = block.timestamp; | |
_user.rewardDuration += calculateRewards(msg.sender); | |
emit Staked(amount, _user.amountStaked, block.timestamp); | |
} | |
function getStakeAmount(address who) public view returns(uint _staked){ | |
Stakings storage _user = userStakingsMap[who]; | |
_staked = _user.amountStaked; | |
} | |
function unStake(uint amount) external { | |
uint totalStaked = getStakeAmount(msg.sender); | |
require(totalStaked >= amount, "insufficent stake amount"); | |
Stakings storage _user = userStakingsMap[msg.sender]; | |
uint rewards = _user.rewardDuration + calculateRewards(msg.sender); | |
require(rewards > 0,"No reward to claim"); | |
_user.rewardDuration = 0; | |
_user.timeStaked = block.timestamp; | |
_mint(msg.sender, rewards); | |
_user.amountStaked -= amount; | |
standardToken.transfer(msg.sender, amount); | |
emit unStaked(amount, _user.amountStaked, block.timestamp, rewards); | |
} | |
function withdrawEther() external { | |
standardToken.withdrawEther(); | |
payable(msg.sender).transfer(address(this).balance); | |
} | |
function calculateRewards(address user) public view returns (uint256) { | |
Stakings storage _user = userStakingsMap[user]; | |
uint256 stakingDuration = (block.timestamp - _user.timeStaked)/60; //The timestamp of the current block minus time user staked token divided | |
return _user.amountStaked * stakingDuration * rewardPercent / 10e4; | |
} | |
function claimReward() public { | |
Stakings storage _user = userStakingsMap[msg.sender]; | |
uint rewards = _user.rewardDuration + calculateRewards(msg.sender); | |
require(rewards > 0,"No reward to claim"); | |
_user.rewardDuration = 0; | |
_user.timeStaked = block.timestamp; //The timestamp of the current block. | |
_mint(msg.sender, rewards); | |
emit claimRewards(block.timestamp, rewards); | |
} | |
// uint256 secondStaked = block.timestamp - stakedFromTs[msg.sender]; //current time minus the time stake was unlocked | |
// uint256 rewards = staked[msg.sender] * secondStaked / 3.154e7; | |
fallback() external payable{} | |
receive() external payable {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment