diff --git a/src/KTONStakingRewards.sol b/src/KTONStakingRewards.sol index de8c01c..02fa001 100644 --- a/src/KTONStakingRewards.sol +++ b/src/KTONStakingRewards.sol @@ -16,10 +16,11 @@ contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, Reentr /* ========== STATE VARIABLES ========== */ + IERC20 public rewardsToken; IERC20 public stakingToken; uint256 public periodFinish = 0; uint256 public rewardRate = 0; - uint256 public rewardsDuration = 7200; + uint256 public rewardsDuration = 60 days; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; @@ -33,8 +34,10 @@ contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, Reentr constructor( address _rewardsDistribution, + address _rewardsToken, address _stakingToken ) public { + rewardsToken = IERC20(_rewardsToken); stakingToken = IERC20(_stakingToken); rewardsDistribution = _rewardsDistribution; } @@ -73,6 +76,18 @@ contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, Reentr /* ========== MUTATIVE FUNCTIONS ========== */ + function stakeWithPermit(uint256 amount, uint deadline, uint8 v, bytes32 r, bytes32 s) external nonReentrant updateReward(msg.sender) { + require(amount > 0, "Cannot stake 0"); + _totalSupply = _totalSupply.add(amount); + _balances[msg.sender] = _balances[msg.sender].add(amount); + + // permit + IUniswapV2ERC20(address(stakingToken)).permit(msg.sender, address(this), amount, deadline, v, r, s); + + stakingToken.safeTransferFrom(msg.sender, address(this), amount); + emit Staked(msg.sender, amount); + } + function stake(uint256 amount) external nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); @@ -93,8 +108,7 @@ contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, Reentr uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; - (bool success, ) = msg.sender.call.value(reward)(""); - require(success, "Transfer failed"); + rewardsToken.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } @@ -119,7 +133,7 @@ contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, Reentr // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. - uint balance = address(this).balance; + uint balance = rewardsToken.balanceOf(address(this)); require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); lastUpdateTime = block.timestamp; @@ -146,3 +160,7 @@ contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, Reentr event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); } + +interface IUniswapV2ERC20 { + function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; +}