Skip to content

Instantly share code, notes, and snippets.

@k06a
Last active November 6, 2019 12:13
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save k06a/3acc48d1d0e9ed8cc9316d7ea6fa15f4 to your computer and use it in GitHub Desktop.
Save k06a/3acc48d1d0e9ed8cc9316d7ea6fa15f4 to your computer and use it in GitHub Desktop.
ETH-sETH Staking Pool for SNX reward
pragma solidity ^0.5.0;
import "github.com/openzeppelin/openzeppelin-contracts/contracts/math/SafeMath.sol";
import "github.com/openzeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import "github.com/openzeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20Detailed.sol";
import "github.com/openzeppelin/openzeppelin-contracts/contracts/token/ERC20/SafeERC20.sol";
contract Unipool is ERC20, ERC20Detailed("Unipool", "SNX-UNP", 18) {
using SafeMath for uint256;
using SafeERC20 for IERC20;
uint256 constant public REWARD_RATE = uint256(72000e18) / 7 days;
IERC20 public snx = IERC20(0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F);
IERC20 public uni = IERC20(0xe9Cf7887b93150D4F2Da7dFc6D502B216438F244);
uint256 public lastUpdateTime;
uint256 public rewardPerTokenStored;
mapping(address => uint256) public userRewardPerTokenPaid;
event Staked(address indexed user, uint256 amount);
event Withdrawed(address indexed user, uint256 amount);
event RewardPaid(address indexed user, uint256 reward);
modifier updateRewardPerToken {
getReward();
_;
}
function rewardPerToken() public view returns(uint256) {
return rewardPerTokenStored.add(
totalSupply() == 0 ? 0 : (now.sub(lastUpdateTime)).mul(REWARD_RATE).mul(1e18).div(totalSupply())
);
}
function earned(address account) public view returns(uint256) {
return balanceOf(account).mul(
rewardPerToken().sub(userRewardPerTokenPaid[account])
).div(1e18);
}
function stake(uint256 amount) public updateRewardPerToken {
_mint(msg.sender, amount);
uni.safeTransferFrom(msg.sender, address(this), amount);
emit Staked(msg.sender, amount);
}
function withdraw(uint256 amount) public updateRewardPerToken {
_burn(msg.sender, amount);
uni.safeTransfer(msg.sender, amount);
emit Withdrawed(msg.sender, amount);
}
function withdrawAll() public {
withdraw(balanceOf(msg.sender));
}
function getReward() public {
uint256 reward = earned(msg.sender);
rewardPerTokenStored = rewardPerToken();
userRewardPerTokenPaid[msg.sender] = rewardPerTokenStored;
lastUpdateTime = now;
if (reward > 0) {
snx.safeTransfer(msg.sender, reward);
emit RewardPaid(msg.sender, reward);
}
}
}
@hav-noms
Copy link

hav-noms commented Nov 4, 2019

This is great. We're keen to integrate test and audit this.

Use this address https://etherscan.io/address/0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f for the rewward token as we're going to migrate to this one.

@k06a
Copy link
Author

k06a commented Nov 6, 2019

Latest version is here: https://github.com/k06a/Unipool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment