Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
표시
레이아웃
나란히 보기
합쳐 보기
실시간 편집
공백 변경 숨기기
변경 없는 행 숨기기
줄바꿈 비활성화
비교 단위
스마트
구문
없음
모양 변경
처리
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
TombBasedRewardPools
생성일
5년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
77 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
274 행
복사
103 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
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
t
SHARE (rewards).
// Note that this pool has no minter key of
b
SHARE (rewards).
// Instead, the governance will call
t
SHARE distributeReward method and send reward to this pool at the beginning.
// Instead, the governance will call
b
SHARE distributeReward method and send reward to this pool at the beginning.
contract
T
ShareRewardPool {
contract
B
ShareRewardPool {
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.
t
SHAREs to distribute per block.
uint256 allocPoint; // How many allocation points assigned to this pool.
b
SHAREs to distribute per block.
uint256 lastRewardTime; // Last time that
t
SHAREs distribution occurs.
uint256 lastRewardTime; // Last time that
b
SHAREs distribution occurs.
uint256 acc
T
SharePerShare; // Accumulated
t
SHAREs per share, times 1e18. See below.
uint256 acc
B
SharePerShare; // Accumulated
b
SHAREs per share, times 1e18. See below.
bool isStarted; // if lastRewardTime has passed
bool isStarted; // if lastRewardTime has passed
}
}
복사
복사됨
복사
복사됨
IERC20 public
t
share;
IERC20 public
b
share;
// 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
t
SHARE mining starts.
// The time when
b
SHARE mining starts.
uint256 public poolStartTime;
uint256 public poolStartTime;
복사
복사됨
복사
복사됨
// The time when
t
SHARE mining ends.
// The time when
b
SHARE mining ends.
uint256 public poolEndTime;
uint256 public poolEndTime;
복사
복사됨
복사
복사됨
uint256 public
t
SharePerSecond = 0.
00186122
ether; //
59500 t
share / (
370
days * 24h * 60min * 60s)
address public daoFundAddress;
uint256 public runningTime =
370
days; //
370
days
uint256 public constant TOTAL_REWARDS =
59500
ether;
uint256 public
b
SharePerSecond = 0.
003486
ether; //
50000 b
share / (
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 _
t
share,
address _
b
share,
address _daoFund,
uint256 _poolStartTime
uint256 _poolStartTime
복사
복사됨
복사
복사됨
)
public
{
)
{
require(block.timestamp < _poolStartTime, "
late
");
require(block.timestamp < _poolStartTime, "
pool cant be started in the past
");
if (_
t
share != address(0))
t
share = IERC20(_
t
share);
if (_
b
share != address(0))
b
share = IERC20(_
b
share);
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, "
T
ShareRewardPool: caller is not the operator");
require(operator == msg.sender, "
B
ShareRewardPool: 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, "
T
ShareRewardPool: existing pool?");
require(poolInfo[pid].token != _token, "
B
ShareRewardPool: 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({
저장된 비교 결과
원본
파일 열기
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; // Note that this pool has no minter key of tSHARE (rewards). // Instead, the governance will call tSHARE distributeReward method and send reward to this pool at the beginning. contract TShareRewardPool { 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 allocPoint; // How many allocation points assigned to this pool. tSHAREs to distribute per block. uint256 lastRewardTime; // Last time that tSHAREs distribution occurs. uint256 accTSharePerShare; // Accumulated tSHAREs per share, times 1e18. See below. bool isStarted; // if lastRewardTime has passed } IERC20 public tshare; // 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 tSHARE mining starts. uint256 public poolStartTime; // The time when tSHARE mining ends. uint256 public poolEndTime; uint256 public tSharePerSecond = 0.00186122 ether; // 59500 tshare / (370 days * 24h * 60min * 60s) uint256 public runningTime = 370 days; // 370 days uint256 public constant TOTAL_REWARDS = 59500 ether; 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 _tshare, uint256 _poolStartTime ) public { require(block.timestamp < _poolStartTime, "late"); if (_tshare != address(0)) tshare = IERC20(_tshare); poolStartTime = _poolStartTime; poolEndTime = poolStartTime + runningTime; operator = msg.sender; } modifier onlyOperator() { require(operator == msg.sender, "TShareRewardPool: 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, "TShareRewardPool: existing pool?"); } } // Add a new lp 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, accTSharePerShare : 0, isStarted : _isStarted })); if (_isStarted) { totalAllocPoint = totalAllocPoint.add(_allocPoint); } } // Update the given pool's tSHARE 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(tSharePerSecond); return poolEndTime.sub(_fromTime).mul(tSharePerSecond); } else { if (_toTime <= poolStartTime) return 0; if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(tSharePerSecond); return _toTime.sub(_fromTime).mul(tSharePerSecond); } } // View function to see pending tSHAREs on frontend. function pendingShare(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accTSharePerShare = pool.accTSharePerShare; uint256 tokenSupply = pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _tshareReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); accTSharePerShare = accTSharePerShare.add(_tshareReward.mul(1e18).div(tokenSupply)); } return user.amount.mul(accTSharePerShare).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 _tshareReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); pool.accTSharePerShare = pool.accTSharePerShare.add(_tshareReward.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.accTSharePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeTShareTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } } if (_amount > 0) { pool.token.safeTransferFrom(_sender, address(this), _amount); user.amount = user.amount.add(_amount); } user.rewardDebt = user.amount.mul(pool.accTSharePerShare).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.accTSharePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeTShareTransfer(_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.accTSharePerShare).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 tshare transfer function, just in case if rounding error causes pool to not have enough tSHAREs. function safeTShareTransfer(address _to, uint256 _amount) internal { uint256 _tshareBal = tshare.balanceOf(address(this)); if (_tshareBal > 0) { if (_amount > _tshareBal) { tshare.safeTransfer(_to, _tshareBal); } else { tshare.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 (tSHARE or lps) if less than 90 days after pool ends require(_token != tshare, "tshare"); 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); } }
수정본
파일 열기
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; // Note that this pool has no minter key of bSHARE (rewards). // Instead, the governance will call bSHARE distributeReward method and send reward to this pool at the beginning. contract BShareRewardPool { 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 allocPoint; // How many allocation points assigned to this pool. bSHAREs to distribute per block. uint256 lastRewardTime; // Last time that bSHAREs distribution occurs. uint256 accBSharePerShare; // Accumulated bSHAREs per share, times 1e18. See below. bool isStarted; // if lastRewardTime has passed } IERC20 public bshare; // 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 bSHARE mining starts. uint256 public poolStartTime; // The time when bSHARE mining ends. uint256 public poolEndTime; address public daoFundAddress; 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 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 _bshare, address _daoFund, uint256 _poolStartTime ) { require(block.timestamp < _poolStartTime, "pool cant be started in the past"); if (_bshare != address(0)) bshare = IERC20(_bshare); if(_daoFund != address(0)) daoFundAddress = _daoFund; poolStartTime = _poolStartTime; poolEndTime = poolStartTime + runningTime; operator = msg.sender; } modifier onlyOperator() { require(operator == msg.sender, "BShareRewardPool: 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, "BShareRewardPool: existing pool?"); } } // Add new lp to the pool. Can only be called by operator. 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, accBSharePerShare: 0, isStarted: _isStarted })); if (_isStarted) { totalAllocPoint = totalAllocPoint.add(_allocPoint); } } // starting allocations for our pools // BASED-TOMB LP: 21500 $BSHARE // BSHARE-TOMB LP: 21000 $BSHARE // TEAM: 4500 $BSHARE // CURVE STABLES LP (OR GEIST STABLES LP): 3000 $BSHARE // Update the given pool's bSHARE allocation point. Can only be called by the operator. // @allocPoints for TEAM can NOT be altered after added - PID 2 // @allocPoints for main LP pools can NOT be smaller than 12,000 function set(uint256 _pid, uint256 _allocPoint) public onlyOperator { massUpdatePools(); require (_pid != 2, "CAN NOT ADJUST TEAM ALLOCATIONS"); PoolInfo storage pool = poolInfo[_pid]; if (_pid == 0 || _pid == 1) { require(_allocPoint >= 12000 * 10**18, "out of range"); // >= allocations for lp pools cant be less than 12,000 if (pool.isStarted) { totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(_allocPoint); } } else if (_pid > 2) { 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(bSharePerSecond); return poolEndTime.sub(_fromTime).mul(bSharePerSecond); } else { if (_toTime <= poolStartTime) return 0; if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(bSharePerSecond); return _toTime.sub(_fromTime).mul(bSharePerSecond); } } // View function to see pending bSHAREs on frontend. function pendingShare(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accBSharePerShare = pool.accBSharePerShare; uint256 tokenSupply = pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _bshareReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); accBSharePerShare = accBSharePerShare.add(_bshareReward.mul(1e18).div(tokenSupply)); } return user.amount.mul(accBSharePerShare).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 _bshareReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); pool.accBSharePerShare = pool.accBSharePerShare.add(_bshareReward.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.accBSharePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeBShareTransfer(_sender, _pending); emit RewardPaid(_sender, _pending); } } if (_amount > 0 && _pid > 2) { pool.token.safeTransferFrom(_sender, address(this), _amount); uint256 depositDebt = _amount.mul(20).div(10000); user.amount = user.amount.add(_amount.sub(depositDebt)); pool.token.safeTransfer(daoFundAddress, depositDebt); } else if (_amount > 0 && _pid <= 2) { pool.token.safeTransferFrom(_sender, address(this), _amount); user.amount = user.amount.add(_amount); } user.rewardDebt = user.amount.mul(pool.accBSharePerShare).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.accBSharePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { safeBShareTransfer(_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.accBSharePerShare).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 bshare transfer function, just in case if rounding error causes pool to not have enough bSHAREs. function safeBShareTransfer(address _to, uint256 _amount) internal { uint256 _bshareBal = bshare.balanceOf(address(this)); if (_bshareBal > 0) { if (_amount > _bshareBal) { bshare.safeTransfer(_to, _bshareBal); } else { bshare.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 (tSHARE or lps) if less than 90 days after pool ends require(_token != bshare, "bshare"); 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); } }
비교하기