Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
실시간 편집
변경 없는 행 숨기기
줄바꿈 비활성화
레이아웃
나란히 보기
합쳐 보기
비교 단위
스마트
단어
글자
구문 강조
언어 선택
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
Genesis Contract TOMB vs HOG
생성일
작년
비교 결과 만료 없음
초기화
내보내기
공유
설명
106 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
279 행
복사
162 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
326 행
복사
복사
복사됨
복사
복사됨
contract
Tomb
GenesisRewardPool
{
contract
Hog
GenesisRewardPool
is ReentrancyGuard
{
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
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.
TOMB
to distribute
.
uint256 depFee; // deposit fee that is applied to created pool.
uint256 lastRewardTime; // Last time that
TOMB
distribution occurs.
uint256 allocPoint; // How many allocation points assigned to this pool.
HOGs
to distribute
per block
.
uint256 acc
Tomb
PerShare; // Accumulated
TOMB
per share, times 1e18. See below.
uint256 lastRewardTime; // Last time that
HOGs
distribution occurs.
bool isStarted; // if lastReward
Block
has passed
uint256 acc
Hog
PerShare; // Accumulated
HOGs
per share, times 1e18. See below.
bool isStarted; // if lastReward
Time
has passed
uint256 poolHogPerSec; // rewards per second for pool (acts as allocPoint)
}
}
복사
복사됨
복사
복사됨
IERC20 public
tomb
;
IERC20 public
hog
;
address public
shiba
;
address public
devFund
;
// 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
TOMB
mining starts.
// The time when
HOG
mining starts.
uint256 public poolStartTime;
uint256 public poolStartTime;
복사
복사됨
복사
복사됨
// The time when
TOMB
mining ends.
// The time when
HOG
mining ends.
uint256 public poolEndTime;
uint256 public poolEndTime;
복사
복사됨
복사
복사됨
uint256 public
hog
PerSecond =
0
ether;
// TESTNET
uint256 public runningTime =
7 days;
uint256 public
tomb
PerSecond =
3.0555555
ether;
// 11000 TOMB / (1h * 60min * 60s)
uint256 public runningTime =
24 hours; // 1 hours
uint256 public constant TOTAL_REWARDS = 11000 ether;
// END TESTNET
// MAINNET
// uint256 public tombPerSecond = 0.11574 ether; // 10000 TOMB / (24h * 60min * 60s)
// uint256 public runningTime = 1 days; // 1 days
// uint256 public constant TOTAL_REWARDS = 10000 ether;
// END MAINNET
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 _
tomb
,
address _
hog
,
address _
shiba
,
address _
devFund
,
uint256 _poolStartTime
uint256 _poolStartTime
복사
복사됨
복사
복사됨
)
public
{
)
{
require(block.timestamp < _poolStartTime, "
late
");
require(block.timestamp < _poolStartTime, "
pool cant be started in the past
");
if (_
tomb
!= address(0))
tomb
= IERC20(_
tomb
);
if (_
hog
!= address(0))
hog
= IERC20(_
hog
);
if
(_shiba
!= address(0))
shiba
= _
shiba;
if
(_devFund
!= address(0))
devFund
= _
devFund;
poolStartTime = _poolStartTime;
poolStartTime = _poolStartTime;
복사
복사됨
복사
복사됨
poolEndTime =
poolStartTime + runningTime;
poolEndTime =
_
poolStartTime + runningTime;
operator = msg.sender;
operator = msg.sender;
복사
복사됨
복사
복사됨
devFund = _devFund;
// create all the pools (daily rewards divided by 86400 seconds)
add(0.318750000 ether, 0, IERC20(0x784DD93F3c42DCbF88D45E6ad6D3CC20dA169a60), false, 0); // Hog-OS 27% (27540/86400)
add(0.224305556 ether, 100, IERC20(0xb1e25689D55734FD3ffFc939c4C3Eb52DFf8A794), false, 0); // OS 19% (19380/86400)
add(0.118055556 ether, 100, IERC20(0x79bbF4508B1391af3A0F4B30bb5FC4aa9ab0E07C), false, 0); // Anon 10% (10200/86400)
add(0.106250000 ether, 100, IERC20(0x44E23B1F3f4511b3a7e81077Fd9F2858dF1B7579), false, 0); // Mclb 9% (9180/86400)
add(0.129861111 ether, 100, IERC20(0xA04BC7140c26fc9BB1F36B1A604C7A5a88fb0E70), false, 0); // SWPx 11% (11220/86400)
add(0.082638889 ether, 100, IERC20(0xE5DA20F15420aD15DE0fa650600aFc998bbE3955), false, 0); // stS 7% (7140/86400)
add(0.082638889 ether, 100, IERC20(0xd3DCe716f3eF535C5Ff8d041c1A41C3bd89b97aE), false, 0); // scUSD 7% (7140/86400)
add(0.047222222 ether, 100, IERC20(0x4EEC869d847A6d13b0F6D1733C5DEC0d1E741B4f), false, 0); // Indi 4% (4080/86400)
add(0.047222222 ether, 100, IERC20(0x9fDbC3f8Abc05Fa8f3Ad3C17D2F806c1230c4564), false, 0); // Goglz 4% (4080/86400)
add(0.023611111 ether, 100, IERC20(0x2D0E0814E62D80056181F5cd932274405966e4f0), false, 0); // Beets 2% (2040/86400)
}
}
modifier onlyOperator() {
modifier onlyOperator() {
복사
복사됨
복사
복사됨
require(operator == msg.sender, "
Tomb
Genesis
Pool: caller is not the operator");
require(operator == msg.sender, "
Hog
Genesis
Reward
Pool: caller is not the operator");
_;
_;
}
}
복사
복사됨
복사
복사됨
function poolLength() external view returns (uint256) {
return poolInfo.length;
}
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, "
Tomb
Genesis
Pool: existing pool?");
require(poolInfo[pid].token != _token, "
Hog
Genesis
Reward
Pool: existing pool?");
}
}
}
}
복사
복사됨
복사
복사됨
// Add
a
new
token
to the pool. Can only be called by
the owner
.
// bulk add pools
function addBulk(uint256[] calldata _allocPoints, uint256[] calldata _depFees, IERC20[] calldata _tokens, bool _withUpdate, uint256 _lastRewardTime) external onlyOperator {
require(_allocPoints.length == _depFees.length && _allocPoints.length == _tokens.length, "HogGenesisRewardPool: invalid length");
for (uint256 i = 0; i < _allocPoints.length; i++) {
add(_allocPoints[i], _depFees[i], _tokens[i], _withUpdate, _lastRewardTime);
}
}
// Add
new
lp
to the pool. Can only be called by
operator
.
function add(
function add(
uint256 _allocPoint,
uint256 _allocPoint,
복사
복사됨
복사
복사됨
uint256 _depFee,
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({
복사
복사됨
복사
복사됨
token
: _token,
token
: _token,
allocPoint
: _allocPoint,
depFee: _depFee,
lastRewardTime
: _lastRewardTime,
allocPoint: _
allocPoint
,
acc
Tomb
PerShare
: 0,
poolHogPerSec
: _allocPoint,
isStarted
: _isStarted
lastRewardTime
: _lastRewardTime,
}));
acc
Hog
PerShare
: 0,
isStarted
: _isStarted
}));
if (_isStarted) {
if (_isStarted) {
totalAllocPoint = totalAllocPoint.add(_allocPoint);
totalAllocPoint = totalAllocPoint.add(_allocPoint);
복사
복사됨
복사
복사됨
hogPerSecond = hogPerSecond.add(_allocPoint);
}
}
}
}
복사
복사됨
복사
복사됨
// Update the given pool's
TOMB
allocation point. Can only be called by the
owner
.
// Update the given pool's
HOG
allocation point. Can only be called by the
operator
.
function set(uint256 _pid, uint256 _allocPoint
) public onlyOperator {
function set(uint256 _pid, uint256 _allocPoint
, uint256 _depFee
) public onlyOperator {
massUpdatePools();
massUpdatePools();
복사
복사됨
복사
복사됨
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
복사
복사됨
복사
복사됨
require(_depFee < 200); // deposit fee cant be more than 2%;
pool.depFee = _depFee;
if (pool.isStarted) {
if (pool.isStarted) {
복사
복사됨
복사
복사됨
totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(
totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(
_allocPoint);
_allocPoint
hogPerSecond = hogPerSecond.sub(pool.poolHogPerSec).add(
_allocPoint
);
);
}
}
pool.allocPoint = _allocPoint;
pool.allocPoint = _allocPoint;
복사
복사됨
복사
복사됨
pool.poolHogPerSec = _allocPoint;
}
function bulkSet(uint256[] calldata _pids, uint256[] calldata _allocPoints, uint256[] calldata _depFees) external onlyOperator {
require(_pids.length == _allocPoints.length && _pids.length == _depFees.length, "HogGenesisRewardPool: invalid length");
for (uint256 i = 0; i < _pids.length; i++) {
set(_pids[i], _allocPoints[i], _depFees[i]);
}
}
}
// Return accumulate rewards over the given _from to _to block.
// Return accumulate rewards over the given _from to _to block.
function getGeneratedReward(uint256 _fromTime, uint256 _toTime) public view returns (uint256) {
function getGeneratedReward(uint256 _fromTime, uint256 _toTime) public view returns (uint256) {
if (_fromTime >= _toTime) return 0;
if (_fromTime >= _toTime) return 0;
if (_toTime >= poolEndTime) {
if (_toTime >= poolEndTime) {
if (_fromTime >= poolEndTime) return 0;
if (_fromTime >= poolEndTime) return 0;
복사
복사됨
복사
복사됨
if (_fromTime <= poolStartTime) return poolEndTime.sub(poolStartTime).mul(
tomb
PerSecond);
if (_fromTime <= poolStartTime) return poolEndTime.sub(poolStartTime).mul(
hog
PerSecond);
return poolEndTime.sub(_fromTime).mul(
tomb
PerSecond);
return poolEndTime.sub(_fromTime).mul(
hog
PerSecond);
} else {
} else {
if (_toTime <= poolStartTime) return 0;
if (_toTime <= poolStartTime) return 0;
복사
복사됨
복사
복사됨
if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(
tomb
PerSecond);
if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(
hog
PerSecond);
return _toTime.sub(_fromTime).mul(
tomb
PerSecond);
return _toTime.sub(_fromTime).mul(
hog
PerSecond);
}
}
}
}
복사
복사됨
복사
복사됨
// View function to see pending
TOMB
on frontend.
// View function to see pending
HOGs
on frontend.
function pending
TOMB
(uint256 _pid, address _user) external view returns (uint256) {
function pending
HOG
(uint256 _pid, address _user) external view returns (uint256) {
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
UserInfo storage user = userInfo[_pid][_user];
복사
복사됨
복사
복사됨
uint256 acc
Tomb
PerShare = pool.acc
Tomb
PerShare;
uint256 acc
Hog
PerShare = pool.acc
Hog
PerShare;
uint256 tokenSupply = pool.token.balanceOf(address(this));
uint256 tokenSupply = pool.token.balanceOf(address(this));
if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) {
if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) {
uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp);
uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp);
복사
복사됨
복사
복사됨
uint256 _
tomb
Reward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint);
uint256 _
hog
Reward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint);
acc
Tomb
PerShare = acc
Tomb
PerShare.add(_
tomb
Reward.mul(1e18).div(tokenSupply));
acc
Hog
PerShare = acc
Hog
PerShare.add(_
hog
Reward.mul(1e18).div(tokenSupply));
}
}
복사
복사됨
복사
복사됨
return user.amount.mul(acc
Tomb
PerShare).div(1e18).sub(user.rewardDebt);
return user.amount.mul(acc
Hog
PerShare).div(1e18).sub(user.rewardDebt);
}
}
복사
복사됨
복사
복사됨
// Update reward variables for all pools. Be careful of gas spending!
function massUpdatePools() public {
function massUpdatePools() public {
uint256 length = poolInfo.length;
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
updatePool(pid);
}
}
}
}
복사
복사됨
복사
복사됨
// massUpdatePoolsInRange
function massUpdatePoolsInRange(uint256 _fromPid, uint256 _toPid) public {
require(_fromPid <= _toPid, "HogGenesisRewardPool: invalid range");
for (uint256 pid = _fromPid; pid <= _toPid; ++pid) {
updatePool(pid);
}
}
// Update reward variables of the given pool to be up-to-date.
// Update reward variables of the given pool to be up-to-date.
복사
복사됨
복사
복사됨
function updatePool(uint256 _pid)
public
{
function updatePool(uint256 _pid)
private
{
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
if (block.timestamp <= pool.lastRewardTime) {
if (block.timestamp <= pool.lastRewardTime) {
return;
return;
}
}
uint256 tokenSupply = pool.token.balanceOf(address(this));
uint256 tokenSupply = pool.token.balanceOf(address(this));
if (tokenSupply == 0) {
if (tokenSupply == 0) {
pool.lastRewardTime = block.timestamp;
pool.lastRewardTime = block.timestamp;
return;
return;
}
}
if (!pool.isStarted) {
if (!pool.isStarted) {
pool.isStarted = true;
pool.isStarted = true;
totalAllocPoint = totalAllocPoint.add(pool.allocPoint);
totalAllocPoint = totalAllocPoint.add(pool.allocPoint);
복사
복사됨
복사
복사됨
hogPerSecond = hogPerSecond.add(pool.poolHogPerSec);
}
}
if (totalAllocPoint > 0) {
if (totalAllocPoint > 0) {
uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp);
uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp);
복사
복사됨
복사
복사됨
uint256 _
tomb
Reward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint);
uint256 _
hog
Reward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint);
pool.acc
Tomb
PerShare = pool.acc
Tomb
PerShare.add(_
tomb
Reward.mul(1e18).div(tokenSupply));
pool.acc
Hog
PerShare = pool.acc
Hog
PerShare.add(_
hog
Reward.mul(1e18).div(tokenSupply));
}
}
pool.lastRewardTime = block.timestamp;
pool.lastRewardTime = block.timestamp;
}
}
복사
복사됨
복사
복사됨
function setDevFund(address _devFund) public onlyOperator {
devFund = _devFund;
}
// Deposit LP tokens.
// Deposit LP tokens.
복사
복사됨
복사
복사됨
function deposit(uint256 _pid, uint256 _amount) public
{
function deposit(uint256 _pid, uint256 _amount) public
nonReentrant
{
address _sender = msg.sender;
address _sender = msg.sender;
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_sender];
UserInfo storage user = userInfo[_pid][_sender];
updatePool(_pid);
updatePool(_pid);
if (user.amount > 0) {
if (user.amount > 0) {
복사
복사됨
복사
복사됨
uint256 _pending = user.amount.mul(pool.acc
Tomb
PerShare).div(1e18).sub(user.rewardDebt);
uint256 _pending = user.amount.mul(pool.acc
Hog
PerShare).div(1e18).sub(user.rewardDebt);
if (_pending > 0) {
if (_pending > 0) {
복사
복사됨
복사
복사됨
safe
Tomb
Transfer(_sender, _pending);
safe
Hog
Transfer(_sender, _pending);
emit RewardPaid(_sender, _pending);
emit RewardPaid(_sender, _pending);
}
}
}
}
복사
복사됨
복사
복사됨
if (_amount > 0
) {
if (_amount > 0
) {
pool.token.safeTransferFrom(_sender, address(this), _amount);
pool.token.safeTransferFrom(_sender, address(this), _amount);
복사
복사됨
복사
복사됨
if(address(pool.token) == shiba) {
uint256 depositDebt
=
_amount.mul(
pool.depFee
).div(10000)
;
user.amount
=
user.amount.add(
_amount.mul(
9900
).div(10000)
);
user.amount = user.amount.add(_amount
.sub(depositDebt)
);
} else {
pool.token.safeTransfer(devFund, depositDebt);
user.amount = user.amount.add(_amount
);
}
}
}
복사
복사됨
복사
복사됨
user.rewardDebt = user.amount.mul(pool.acc
Tomb
PerShare).div(1e18);
user.rewardDebt = user.amount.mul(pool.acc
Hog
PerShare).div(1e18);
emit Deposit(_sender, _pid, _amount);
emit Deposit(_sender, _pid, _amount);
}
}
// Withdraw LP tokens.
// Withdraw LP tokens.
복사
복사됨
복사
복사됨
function withdraw(uint256 _pid, uint256 _amount) public
{
function withdraw(uint256 _pid, uint256 _amount) public
nonReentrant
{
address _sender = msg.sender;
address _sender = msg.sender;
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_sender];
UserInfo storage user = userInfo[_pid][_sender];
require(user.amount >= _amount, "withdraw: not good");
require(user.amount >= _amount, "withdraw: not good");
updatePool(_pid);
updatePool(_pid);
복사
복사됨
복사
복사됨
uint256 _pending = user.amount.mul(pool.acc
Tomb
PerShare).div(1e18).sub(user.rewardDebt);
uint256 _pending = user.amount.mul(pool.acc
Hog
PerShare).div(1e18).sub(user.rewardDebt);
if (_pending > 0) {
if (_pending > 0) {
복사
복사됨
복사
복사됨
safe
Tomb
Transfer(_sender, _pending);
safe
Hog
Transfer(_sender, _pending);
emit RewardPaid(_sender, _pending);
emit RewardPaid(_sender, _pending);
}
}
if (_amount > 0) {
if (_amount > 0) {
user.amount = user.amount.sub(_amount);
user.amount = user.amount.sub(_amount);
pool.token.safeTransfer(_sender, _amount);
pool.token.safeTransfer(_sender, _amount);
}
}
복사
복사됨
복사
복사됨
user.rewardDebt = user.amount.mul(pool.acc
Tomb
PerShare).div(1e18);
user.rewardDebt = user.amount.mul(pool.acc
Hog
PerShare).div(1e18);
emit Withdraw(_sender, _pid, _amount);
emit Withdraw(_sender, _pid, _amount);
}
}
// Withdraw without caring about rewards. EMERGENCY ONLY.
// Withdraw without caring about rewards. EMERGENCY ONLY.
복사
복사됨
복사
복사됨
function emergencyWithdraw(uint256 _pid) public
{
function emergencyWithdraw(uint256 _pid) public
nonReentrant
{
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
UserInfo storage user = userInfo[_pid][msg.sender];
uint256 _amount = user.amount;
uint256 _amount = user.amount;
user.amount = 0;
user.amount = 0;
user.rewardDebt = 0;
user.rewardDebt = 0;
pool.token.safeTransfer(msg.sender, _amount);
pool.token.safeTransfer(msg.sender, _amount);
emit EmergencyWithdraw(msg.sender, _pid, _amount);
emit EmergencyWithdraw(msg.sender, _pid, _amount);
}
}
복사
복사됨
복사
복사됨
// Safe
TOMB
transfer function, just in case if rounding error causes pool to not have enough
TOMBs
.
// Safe
hog
transfer function, just in case if rounding error causes pool to not have enough
HOGs
.
function safe
Tomb
Transfer(address _to, uint256 _amount) internal {
function safe
Hog
Transfer(address _to, uint256 _amount) internal {
uint256 _
tombBalance
=
tomb
.balanceOf(address(this));
uint256 _
hogBal
=
hog
.balanceOf(address(this));
if (_
tombBalance
> 0) {
if (_
hogBal
> 0) {
if (_amount > _
tombBalance
) {
if (_amount > _
hogBal
) {
tomb
.safeTransfer(_to, _
tombBalance
);
hog
.safeTransfer(_to, _
hogBal
);
} else {
} else {
복사
복사됨
복사
복사됨
tomb
.safeTransfer(_to, _amount);
hog
.safeTransfer(_to, _amount);
}
}
}
}
}
}
function setOperator(address _operator) external onlyOperator {
function setOperator(address _operator) external onlyOperator {
operator = _operator;
operator = _operator;
}
}
복사
복사됨
복사
복사됨
function governanceRecoverUnsupported(
IERC20 _token,
uint256 amount,
address to
) external onlyOperator {
function governanceRecoverUnsupported(
if (block.timestamp < poolEndTime +
90
days) {
IERC20 _token,
// do not allow to drain
core token (TOMB or lps)
if less than
90
days after pool ends
uint256 amount,
require(_token != tomb, "tomb");
address to
) external onlyOperator {
if (block.timestamp < poolEndTime +
7
days) {
// do not allow to drain
tokens
if less than
7
days after pool ends
uint256 length = poolInfo.length;
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
for (uint256 pid = 0; pid < length; ++pid) {
PoolInfo storage pool = poolInfo[pid];
PoolInfo storage pool = poolInfo[pid];
복사
복사됨
복사
복사됨
require(_token != pool.token, "
pool
.
token");
require(_token != pool.token, "
token cannot be
pool
token");
}
}
}
}
복사
복사됨
복사
복사됨
_token.safeTransfer(to, amount);
_token.safeTransfer(to, amount);
}
}
}
}
복사
복사됨
복사
복사됨
저장된 비교 결과
원본
파일 열기
contract TombGenesisRewardPool { using SafeMath for uint256; using SafeERC20 for IERC20; // governance address public operator; // Info of each user. struct UserInfo { uint256 amount; // How many tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } // Info of each pool. struct PoolInfo { IERC20 token; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. TOMB to distribute. uint256 lastRewardTime; // Last time that TOMB distribution occurs. uint256 accTombPerShare; // Accumulated TOMB per share, times 1e18. See below. bool isStarted; // if lastRewardBlock has passed } IERC20 public tomb; address public shiba; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The time when TOMB mining starts. uint256 public poolStartTime; // The time when TOMB mining ends. uint256 public poolEndTime; // TESTNET uint256 public tombPerSecond = 3.0555555 ether; // 11000 TOMB / (1h * 60min * 60s) uint256 public runningTime = 24 hours; // 1 hours uint256 public constant TOTAL_REWARDS = 11000 ether; // END TESTNET // MAINNET // uint256 public tombPerSecond = 0.11574 ether; // 10000 TOMB / (24h * 60min * 60s) // uint256 public runningTime = 1 days; // 1 days // uint256 public constant TOTAL_REWARDS = 10000 ether; // END MAINNET event Deposit(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 RewardPaid(address indexed user, uint256 amount); constructor( address _tomb, address _shiba, uint256 _poolStartTime ) public { require(block.timestamp < _poolStartTime, "late"); if (_tomb != address(0)) tomb = IERC20(_tomb); if (_shiba != address(0)) shiba = _shiba; poolStartTime = _poolStartTime; poolEndTime = poolStartTime + runningTime; operator = msg.sender; } modifier onlyOperator() { require(operator == msg.sender, "TombGenesisPool: caller is not the operator"); _; } function checkPoolDuplicate(IERC20 _token) internal view { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { require(poolInfo[pid].token != _token, "TombGenesisPool: existing pool?"); } } // Add a new token to the pool. Can only be called by the owner. function add( uint256 _allocPoint, IERC20 _token, bool _withUpdate, uint256 _lastRewardTime ) public onlyOperator { checkPoolDuplicate(_token); if (_withUpdate) { massUpdatePools(); } if (block.timestamp < poolStartTime) { // chef is sleeping if (_lastRewardTime == 0) { _lastRewardTime = poolStartTime; } else { if (_lastRewardTime < poolStartTime) { _lastRewardTime = poolStartTime; } } } else { // chef is cooking if (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) { _lastRewardTime = block.timestamp; } } bool _isStarted = (_lastRewardTime <= poolStartTime) || (_lastRewardTime <= block.timestamp); poolInfo.push(PoolInfo({ token : _token, allocPoint : _allocPoint, lastRewardTime : _lastRewardTime, accTombPerShare : 0, isStarted : _isStarted })); if (_isStarted) { totalAllocPoint = totalAllocPoint.add(_allocPoint); } } // Update the given pool's TOMB allocation point. Can only be called by the owner. function set(uint256 _pid, uint256 _allocPoint) public onlyOperator { massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; if (pool.isStarted) { totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add( _allocPoint ); } pool.allocPoint = _allocPoint; } // Return accumulate rewards over the given _from to _to block. function getGeneratedReward(uint256 _fromTime, uint256 _toTime) public view returns (uint256) { if (_fromTime >= _toTime) return 0; if (_toTime >= poolEndTime) { if (_fromTime >= poolEndTime) return 0; if (_fromTime <= poolStartTime) return poolEndTime.sub(poolStartTime).mul(tombPerSecond); return poolEndTime.sub(_fromTime).mul(tombPerSecond); } else { if (_toTime <= poolStartTime) return 0; if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(tombPerSecond); return _toTime.sub(_fromTime).mul(tombPerSecond); } } // View function to see pending TOMB on frontend. function pendingTOMB(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accTombPerShare = pool.accTombPerShare; uint256 tokenSupply = pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _tombReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); accTombPerShare = accTombPerShare.add(_tombReward.mul(1e18).div(tokenSupply)); } return user.amount.mul(accTombPerShare).div(1e18).sub(user.rewardDebt); } // Update reward variables for all pools. Be careful of gas spending! function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 tokenSupply = pool.token.balanceOf(address(this)); if (tokenSupply == 0) { pool.lastRewardTime = block.timestamp; return; } if (!pool.isStarted) { pool.isStarted = true; totalAllocPoint = totalAllocPoint.add(pool.allocPoint); } if (totalAllocPoint > 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _tombReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); pool.accTombPerShare = pool.accTombPerShare.add(_tombReward.mul(1e18).div(tokenSupply)); } pool.lastRewardTime = block.timestamp; } // Deposit LP tokens. function deposit(uint256 _pid, uint256 _amount) public { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; updatePool(_pid); if (user.amount > 0) { uint256 _pending = user.amount.mul(pool.accTombPerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeTombTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } } if (_amount > 0) { pool.token.safeTransferFrom(_sender, address(this), _amount); if(address(pool.token) == shiba) { user.amount = user.amount.add(_amount.mul(9900).div(10000)); } else { user.amount = user.amount.add(_amount); } } user.rewardDebt = user.amount.mul(pool.accTombPerShare).div(1e18); emit Deposit(_sender, _pid, _amount); } // Withdraw LP tokens. function withdraw(uint256 _pid, uint256 _amount) public { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); uint256 _pending = user.amount.mul(pool.accTombPerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeTombTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } if (_amount > 0) { user.amount = user.amount.sub(_amount); pool.token.safeTransfer(_sender, _amount); } user.rewardDebt = user.amount.mul(pool.accTombPerShare).div(1e18); emit Withdraw(_sender, _pid, _amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 _amount = user.amount; user.amount = 0; user.rewardDebt = 0; pool.token.safeTransfer(msg.sender, _amount); emit EmergencyWithdraw(msg.sender, _pid, _amount); } // Safe TOMB transfer function, just in case if rounding error causes pool to not have enough TOMBs. function safeTombTransfer(address _to, uint256 _amount) internal { uint256 _tombBalance = tomb.balanceOf(address(this)); if (_tombBalance > 0) { if (_amount > _tombBalance) { tomb.safeTransfer(_to, _tombBalance); } else { tomb.safeTransfer(_to, _amount); } } } function setOperator(address _operator) external onlyOperator { operator = _operator; } function governanceRecoverUnsupported(IERC20 _token, uint256 amount, address to) external onlyOperator { if (block.timestamp < poolEndTime + 90 days) { // do not allow to drain core token (TOMB or lps) if less than 90 days after pool ends require(_token != tomb, "tomb"); uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; require(_token != pool.token, "pool.token"); } } _token.safeTransfer(to, amount); } }
수정본
파일 열기
contract HogGenesisRewardPool is ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; // governance address public operator; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } // Info of each pool. struct PoolInfo { IERC20 token; // Address of LP token contract. uint256 depFee; // deposit fee that is applied to created pool. uint256 allocPoint; // How many allocation points assigned to this pool. HOGs to distribute per block. uint256 lastRewardTime; // Last time that HOGs distribution occurs. uint256 accHogPerShare; // Accumulated HOGs per share, times 1e18. See below. bool isStarted; // if lastRewardTime has passed uint256 poolHogPerSec; // rewards per second for pool (acts as allocPoint) } IERC20 public hog; address public devFund; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The time when HOG mining starts. uint256 public poolStartTime; // The time when HOG mining ends. uint256 public poolEndTime; uint256 public hogPerSecond = 0 ether; uint256 public runningTime = 7 days; event Deposit(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 RewardPaid(address indexed user, uint256 amount); constructor( address _hog, address _devFund, uint256 _poolStartTime ) { require(block.timestamp < _poolStartTime, "pool cant be started in the past"); if (_hog != address(0)) hog = IERC20(_hog); if(_devFund != address(0)) devFund = _devFund; poolStartTime = _poolStartTime; poolEndTime = _poolStartTime + runningTime; operator = msg.sender; devFund = _devFund; // create all the pools (daily rewards divided by 86400 seconds) add(0.318750000 ether, 0, IERC20(0x784DD93F3c42DCbF88D45E6ad6D3CC20dA169a60), false, 0); // Hog-OS 27% (27540/86400) add(0.224305556 ether, 100, IERC20(0xb1e25689D55734FD3ffFc939c4C3Eb52DFf8A794), false, 0); // OS 19% (19380/86400) add(0.118055556 ether, 100, IERC20(0x79bbF4508B1391af3A0F4B30bb5FC4aa9ab0E07C), false, 0); // Anon 10% (10200/86400) add(0.106250000 ether, 100, IERC20(0x44E23B1F3f4511b3a7e81077Fd9F2858dF1B7579), false, 0); // Mclb 9% (9180/86400) add(0.129861111 ether, 100, IERC20(0xA04BC7140c26fc9BB1F36B1A604C7A5a88fb0E70), false, 0); // SWPx 11% (11220/86400) add(0.082638889 ether, 100, IERC20(0xE5DA20F15420aD15DE0fa650600aFc998bbE3955), false, 0); // stS 7% (7140/86400) add(0.082638889 ether, 100, IERC20(0xd3DCe716f3eF535C5Ff8d041c1A41C3bd89b97aE), false, 0); // scUSD 7% (7140/86400) add(0.047222222 ether, 100, IERC20(0x4EEC869d847A6d13b0F6D1733C5DEC0d1E741B4f), false, 0); // Indi 4% (4080/86400) add(0.047222222 ether, 100, IERC20(0x9fDbC3f8Abc05Fa8f3Ad3C17D2F806c1230c4564), false, 0); // Goglz 4% (4080/86400) add(0.023611111 ether, 100, IERC20(0x2D0E0814E62D80056181F5cd932274405966e4f0), false, 0); // Beets 2% (2040/86400) } modifier onlyOperator() { require(operator == msg.sender, "HogGenesisRewardPool: caller is not the operator"); _; } function poolLength() external view returns (uint256) { return poolInfo.length; } function checkPoolDuplicate(IERC20 _token) internal view { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { require(poolInfo[pid].token != _token, "HogGenesisRewardPool: existing pool?"); } } // bulk add pools function addBulk(uint256[] calldata _allocPoints, uint256[] calldata _depFees, IERC20[] calldata _tokens, bool _withUpdate, uint256 _lastRewardTime) external onlyOperator { require(_allocPoints.length == _depFees.length && _allocPoints.length == _tokens.length, "HogGenesisRewardPool: invalid length"); for (uint256 i = 0; i < _allocPoints.length; i++) { add(_allocPoints[i], _depFees[i], _tokens[i], _withUpdate, _lastRewardTime); } } // Add new lp to the pool. Can only be called by operator. function add( uint256 _allocPoint, uint256 _depFee, IERC20 _token, bool _withUpdate, uint256 _lastRewardTime ) public onlyOperator { checkPoolDuplicate(_token); if (_withUpdate) { massUpdatePools(); } if (block.timestamp < poolStartTime) { // chef is sleeping if (_lastRewardTime == 0) { _lastRewardTime = poolStartTime; } else { if (_lastRewardTime < poolStartTime) { _lastRewardTime = poolStartTime; } } } else { // chef is cooking if (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) { _lastRewardTime = block.timestamp; } } bool _isStarted = (_lastRewardTime <= poolStartTime) || (_lastRewardTime <= block.timestamp); poolInfo.push(PoolInfo({ token: _token, depFee: _depFee, allocPoint: _allocPoint, poolHogPerSec: _allocPoint, lastRewardTime: _lastRewardTime, accHogPerShare: 0, isStarted: _isStarted })); if (_isStarted) { totalAllocPoint = totalAllocPoint.add(_allocPoint); hogPerSecond = hogPerSecond.add(_allocPoint); } } // Update the given pool's HOG allocation point. Can only be called by the operator. function set(uint256 _pid, uint256 _allocPoint, uint256 _depFee) public onlyOperator { massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; require(_depFee < 200); // deposit fee cant be more than 2%; pool.depFee = _depFee; if (pool.isStarted) { totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(_allocPoint); hogPerSecond = hogPerSecond.sub(pool.poolHogPerSec).add(_allocPoint); } pool.allocPoint = _allocPoint; pool.poolHogPerSec = _allocPoint; } function bulkSet(uint256[] calldata _pids, uint256[] calldata _allocPoints, uint256[] calldata _depFees) external onlyOperator { require(_pids.length == _allocPoints.length && _pids.length == _depFees.length, "HogGenesisRewardPool: invalid length"); for (uint256 i = 0; i < _pids.length; i++) { set(_pids[i], _allocPoints[i], _depFees[i]); } } // Return accumulate rewards over the given _from to _to block. function getGeneratedReward(uint256 _fromTime, uint256 _toTime) public view returns (uint256) { if (_fromTime >= _toTime) return 0; if (_toTime >= poolEndTime) { if (_fromTime >= poolEndTime) return 0; if (_fromTime <= poolStartTime) return poolEndTime.sub(poolStartTime).mul(hogPerSecond); return poolEndTime.sub(_fromTime).mul(hogPerSecond); } else { if (_toTime <= poolStartTime) return 0; if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(hogPerSecond); return _toTime.sub(_fromTime).mul(hogPerSecond); } } // View function to see pending HOGs on frontend. function pendingHOG(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accHogPerShare = pool.accHogPerShare; uint256 tokenSupply = pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _hogReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); accHogPerShare = accHogPerShare.add(_hogReward.mul(1e18).div(tokenSupply)); } return user.amount.mul(accHogPerShare).div(1e18).sub(user.rewardDebt); } function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } // massUpdatePoolsInRange function massUpdatePoolsInRange(uint256 _fromPid, uint256 _toPid) public { require(_fromPid <= _toPid, "HogGenesisRewardPool: invalid range"); for (uint256 pid = _fromPid; pid <= _toPid; ++pid) { updatePool(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) private { PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 tokenSupply = pool.token.balanceOf(address(this)); if (tokenSupply == 0) { pool.lastRewardTime = block.timestamp; return; } if (!pool.isStarted) { pool.isStarted = true; totalAllocPoint = totalAllocPoint.add(pool.allocPoint); hogPerSecond = hogPerSecond.add(pool.poolHogPerSec); } if (totalAllocPoint > 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _hogReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); pool.accHogPerShare = pool.accHogPerShare.add(_hogReward.mul(1e18).div(tokenSupply)); } pool.lastRewardTime = block.timestamp; } function setDevFund(address _devFund) public onlyOperator { devFund = _devFund; } // Deposit LP tokens. function deposit(uint256 _pid, uint256 _amount) public nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; updatePool(_pid); if (user.amount > 0) { uint256 _pending = user.amount.mul(pool.accHogPerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeHogTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } } if (_amount > 0 ) { pool.token.safeTransferFrom(_sender, address(this), _amount); uint256 depositDebt = _amount.mul(pool.depFee).div(10000); user.amount = user.amount.add(_amount.sub(depositDebt)); pool.token.safeTransfer(devFund, depositDebt); } user.rewardDebt = user.amount.mul(pool.accHogPerShare).div(1e18); emit Deposit(_sender, _pid, _amount); } // Withdraw LP tokens. function withdraw(uint256 _pid, uint256 _amount) public nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); uint256 _pending = user.amount.mul(pool.accHogPerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeHogTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } if (_amount > 0) { user.amount = user.amount.sub(_amount); pool.token.safeTransfer(_sender, _amount); } user.rewardDebt = user.amount.mul(pool.accHogPerShare).div(1e18); emit Withdraw(_sender, _pid, _amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 _amount = user.amount; user.amount = 0; user.rewardDebt = 0; pool.token.safeTransfer(msg.sender, _amount); emit EmergencyWithdraw(msg.sender, _pid, _amount); } // Safe hog transfer function, just in case if rounding error causes pool to not have enough HOGs. function safeHogTransfer(address _to, uint256 _amount) internal { uint256 _hogBal = hog.balanceOf(address(this)); if (_hogBal > 0) { if (_amount > _hogBal) { hog.safeTransfer(_to, _hogBal); } else { hog.safeTransfer(_to, _amount); } } } function setOperator(address _operator) external onlyOperator { operator = _operator; } function governanceRecoverUnsupported( IERC20 _token, uint256 amount, address to ) external onlyOperator { if (block.timestamp < poolEndTime + 7 days) { // do not allow to drain tokens if less than 7 days after pool ends uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; require(_token != pool.token, "token cannot be pool token"); } } _token.safeTransfer(to, amount); } }
비교하기