TombBasedRewardPools

创建于 差异永不过期
77 删除
274 行
103 添加
299 行
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT


pragma solidity 0.6.12;
pragma solidity ^0.8.0;


import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";


// Note that this pool has no minter key of tSHARE (rewards).
// Note that this pool has no minter key of bSHARE (rewards).
// Instead, the governance will call tSHARE distributeReward method and send reward to this pool at the beginning.
// Instead, the governance will call bSHARE distributeReward method and send reward to this pool at the beginning.
contract TShareRewardPool {
contract BShareRewardPool {
using SafeMath for uint256;
using SafeMath for uint256;
using SafeERC20 for IERC20;
using SafeERC20 for IERC20;


// governance
// governance
address public operator;
address public operator;


// Info of each user.
// Info of each user.
struct UserInfo {
struct UserInfo {
uint256 amount; // How many LP tokens the user has provided.
uint256 amount; // How many LP tokens the user has provided.
uint256 rewardDebt; // Reward debt. See explanation below.
uint256 rewardDebt; // Reward debt. See explanation below.
}
}


// Info of each pool.
// Info of each pool.
struct PoolInfo {
struct PoolInfo {
IERC20 token; // Address of LP token contract.
IERC20 token; // Address of LP token contract.
uint256 allocPoint; // How many allocation points assigned to this pool. tSHAREs to distribute per block.
uint256 allocPoint; // How many allocation points assigned to this pool. bSHAREs to distribute per block.
uint256 lastRewardTime; // Last time that tSHAREs distribution occurs.
uint256 lastRewardTime; // Last time that bSHAREs distribution occurs.
uint256 accTSharePerShare; // Accumulated tSHAREs per share, times 1e18. See below.
uint256 accBSharePerShare; // Accumulated bSHAREs per share, times 1e18. See below.
bool isStarted; // if lastRewardTime has passed
bool isStarted; // if lastRewardTime has passed
}
}


IERC20 public tshare;
IERC20 public bshare;


// Info of each pool.
// Info of each pool.
PoolInfo[] public poolInfo;
PoolInfo[] public poolInfo;


// Info of each user that stakes LP tokens.
// Info of each user that stakes LP tokens.
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
mapping(uint256 => mapping(address => UserInfo)) public userInfo;


// Total allocation points. Must be the sum of all allocation points in all pools.
// Total allocation points. Must be the sum of all allocation points in all pools.
uint256 public totalAllocPoint = 0;
uint256 public totalAllocPoint = 0;


// The time when tSHARE mining starts.
// The time when bSHARE mining starts.
uint256 public poolStartTime;
uint256 public poolStartTime;


// The time when tSHARE mining ends.
// The time when bSHARE mining ends.
uint256 public poolEndTime;
uint256 public poolEndTime;


uint256 public tSharePerSecond = 0.00186122 ether; // 59500 tshare / (370 days * 24h * 60min * 60s)
address public daoFundAddress;
uint256 public runningTime = 370 days; // 370 days

uint256 public constant TOTAL_REWARDS = 59500 ether;
uint256 public bSharePerSecond = 0.003486 ether; // 50000 bshare / (166 days * 24h * 60min * 60s)
uint256 public runningTime = 166 days; // 166 days
uint256 public constant TOTAL_REWARDS = 50000 ether;


event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);
event RewardPaid(address indexed user, uint256 amount);
event RewardPaid(address indexed user, uint256 amount);


constructor(
constructor(
address _tshare,
address _bshare,
address _daoFund,
uint256 _poolStartTime
uint256 _poolStartTime
) public {
) {
require(block.timestamp < _poolStartTime, "late");
require(block.timestamp < _poolStartTime, "pool cant be started in the past");
if (_tshare != address(0)) tshare = IERC20(_tshare);
if (_bshare != address(0)) bshare = IERC20(_bshare);
if(_daoFund != address(0)) daoFundAddress = _daoFund;

poolStartTime = _poolStartTime;
poolStartTime = _poolStartTime;
poolEndTime = poolStartTime + runningTime;
poolEndTime = poolStartTime + runningTime;
operator = msg.sender;
operator = msg.sender;
}
}


modifier onlyOperator() {
modifier onlyOperator() {
require(operator == msg.sender, "TShareRewardPool: caller is not the operator");
require(operator == msg.sender, "BShareRewardPool: caller is not the operator");
_;
_;
}
}


function checkPoolDuplicate(IERC20 _token) internal view {
function checkPoolDuplicate(IERC20 _token) internal view {
uint256 length = poolInfo.length;
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
for (uint256 pid = 0; pid < length; ++pid) {
require(poolInfo[pid].token != _token, "TShareRewardPool: existing pool?");
require(poolInfo[pid].token != _token, "BShareRewardPool: existing pool?");
}
}
}
}


// Add a new lp to the pool. Can only be called by the owner.
// Add new lp to the pool. Can only be called by operator.
function add(
function add(
uint256 _allocPoint,
uint256 _allocPoint,
IERC20 _token,
IERC20 _token,
bool _withUpdate,
bool _withUpdate,
uint256 _lastRewardTime
uint256 _lastRewardTime
) public onlyOperator {
) public onlyOperator {
checkPoolDuplicate(_token);
checkPoolDuplicate(_token);
if (_withUpdate) {
if (_withUpdate) {
massUpdatePools();
massUpdatePools();
}
}
if (block.timestamp < poolStartTime) {
if (block.timestamp < poolStartTime) {
// chef is sleeping
// chef is sleeping
if (_lastRewardTime == 0) {
if (_lastRewardTime == 0) {
_lastRewardTime = poolStartTime;
_lastRewardTime = poolStartTime;
} else {
} else {
if (_lastRewardTime < poolStartTime) {
if (_lastRewardTime < poolStartTime) {
_lastRewardTime = poolStartTime;
_lastRewardTime = poolStartTime;
}
}
}
}
} else {
} else {
// chef is cooking
// chef is cooking
if (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) {
if (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) {
_lastRewardTime = block.timestamp;
_lastRewardTime = block.timestamp;
}
}
}
}
bool _isStarted =
bool _isStarted = (_lastRewardTime <= poolStartTime) || (_lastRewardTime <= block.timestamp);
(_lastRewardTime <= poolStartTime) ||
(_lastRewardTime <= block.timestamp);
poolInfo.push(PoolInfo({
poolInfo.push(PoolInfo({