Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
실시간 편집
변경 없는 행 숨기기
줄바꿈 비활성화
레이아웃
나란히 보기
합쳐 보기
비교 단위
스마트
단어
글자
구문 강조
언어 선택
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
CookingFirevsMasterChef
생성일
5년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
91 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
314 행
복사
105 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
327 행
복사
복사
복사됨
복사
복사됨
contract
MasterChef
is Ownable, ReentrancyGuard {
contract
CookingFire
is Ownable, ReentrancyGuard {
using SafeMath for uint256;
using SafeMath for uint256;
using SafeBEP20 for IBEP20;
using SafeBEP20 for IBEP20;
// 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.
uint256 rewardLockedUp; // Reward locked up.
uint256 rewardLockedUp; // Reward locked up.
uint256 nextHarvestUntil; // When can the user harvest again.
uint256 nextHarvestUntil; // When can the user harvest again.
//
//
복사
복사됨
복사
복사됨
// We do some fancy math here. Basically, any point in time, the amount of
PANTHERs
// We do some fancy math here. Basically, any point in time, the amount of
BLAZEs
// entitled to a user but is pending to be distributed is:
// entitled to a user but is pending to be distributed is:
//
//
복사
복사됨
복사
복사됨
// pending reward = (user.amount * pool.acc
Panther
PerShare) - user.rewardDebt
// pending reward = (user.amount * pool.acc
Blaze
PerShare) - user.rewardDebt
//
//
// Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:
// Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:
복사
복사됨
복사
복사됨
// 1. The pool's `acc
Panther
PerShare` (and `lastRewardBlock`) gets updated.
// 1. The pool's `acc
Blaze
PerShare` (and `lastRewardBlock`) gets updated.
// 2. User receives the pending reward sent to his/her address.
// 2. User receives the pending reward sent to his/her address.
// 3. User's `amount` gets updated.
// 3. User's `amount` gets updated.
// 4. User's `rewardDebt` gets updated.
// 4. User's `rewardDebt` gets updated.
}
}
// Info of each pool.
// Info of each pool.
struct PoolInfo {
struct PoolInfo {
IBEP20 lpToken; // Address of LP token contract.
IBEP20 lpToken; // Address of LP token contract.
복사
복사됨
복사
복사됨
uint256 allocPoint; // How many allocation points assigned to this pool.
PANTHERs
to distribute per block.
uint256 allocPoint; // How many allocation points assigned to this pool.
BLAZEs
to distribute per block.
uint256 lastRewardBlock; // Last block number that
PANTHERs
distribution occurs.
uint256 lastRewardBlock; // Last block number that
BLAZEs
distribution occurs.
uint256 acc
Panther
PerShare; // Accumulated
PANTHERs
per share, times 1e12. See below.
uint256 acc
Blaze
PerShare; // Accumulated
BLAZEs
per share, times 1e12. See below.
uint16 depositFeeBP; // Deposit fee in basis points
uint16 depositFeeBP; // Deposit fee in basis points
uint256 harvestInterval; // Harvest interval in seconds
uint256 harvestInterval; // Harvest interval in seconds
}
}
복사
복사됨
복사
복사됨
// The
PANTHER
TOKEN!
// The
BLAZE
TOKEN!
PantherToken
public
panther
;
BlazeToken
public
blaze
;
// Dev address.
// Dev address.
address public devAddress;
address public devAddress;
// Deposit Fee address
// Deposit Fee address
address public feeAddress;
address public feeAddress;
복사
복사됨
복사
복사됨
//
PANTHER
tokens created per block.
//
BLAZE
tokens created per block.
uint256 public
panther
PerBlock;
uint256 public
blaze
PerBlock;
// Bonus muliplier for early
panther
makers.
// Bonus muliplier for early
blaze
makers.
uint256 public constant BONUS_MULTIPLIER = 1;
uint256 public constant BONUS_MULTIPLIER = 1;
// Max harvest interval: 14 days.
// Max harvest interval: 14 days.
uint256 public constant MAXIMUM_HARVEST_INTERVAL = 14 days;
uint256 public constant MAXIMUM_HARVEST_INTERVAL = 14 days;
// 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 block number when
PANTHER
mining starts.
// The block number when
BLAZE
mining starts.
uint256 public startBlock;
uint256 public startBlock;
// Total locked up rewards
// Total locked up rewards
uint256 public totalLockedUpRewards;
uint256 public totalLockedUpRewards;
복사
복사됨
복사
복사됨
//
Panther
referral contract address.
//
Blaze
referral contract address.
I
Panther
Referral public
panther
Referral;
I
Blaze
Referral public
blaze
Referral;
// Referral commission rate in basis points.
// Referral commission rate in basis points.
uint16 public referralCommissionRate = 100;
uint16 public referralCommissionRate = 100;
// Max referral commission rate: 10%.
// Max referral commission rate: 10%.
uint16 public constant MAXIMUM_REFERRAL_COMMISSION_RATE = 1000;
uint16 public constant MAXIMUM_REFERRAL_COMMISSION_RATE = 1000;
복사
복사됨
복사
복사됨
address private _operator;
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 EmissionRateUpdated(address indexed caller, uint256 previousAmount, uint256 newAmount);
event EmissionRateUpdated(address indexed caller, uint256 previousAmount, uint256 newAmount);
event ReferralCommissionPaid(address indexed user, address indexed referrer, uint256 commissionAmount);
event ReferralCommissionPaid(address indexed user, address indexed referrer, uint256 commissionAmount);
event RewardLockedUp(address indexed user, uint256 indexed pid, uint256 amountLockedUp);
event RewardLockedUp(address indexed user, uint256 indexed pid, uint256 amountLockedUp);
복사
복사됨
복사
복사됨
modifier onlyOperator() {
require(_operator == msg.sender, "operator: caller is not the operator");
_;
}
복사
복사됨
복사
복사됨
constructor(
constructor(
복사
복사됨
복사
복사됨
PantherToken _panther
,
BlazeToken _blaze
,
uint256 _startBlock,
uint256 _startBlock,
복사
복사됨
복사
복사됨
uint256 _
panther
PerBlock
uint256 _
blaze
PerBlock
) public {
) public {
복사
복사됨
복사
복사됨
panther
= _
panther
;
blaze
= _
blaze
;
startBlock = _startBlock;
startBlock = _startBlock;
복사
복사됨
복사
복사됨
panther
PerBlock = _
panther
PerBlock;
blaze
PerBlock = _
blaze
PerBlock;
_operator = msg.sender;
devAddress = msg.sender;
devAddress = msg.sender;
feeAddress = msg.sender;
feeAddress = msg.sender;
}
}
function poolLength() external view returns (uint256) {
function poolLength() external view returns (uint256) {
return poolInfo.length;
return poolInfo.length;
}
}
복사
복사됨
복사
복사됨
function updateOperator(address _op) public onlyOperator {
_operator = _op;
}
function updateStartBlock(uint256 _startBlock) public onlyOperator {
require(block.number > startBlock, "updateStartBlock: farming already initiated");
startBlock = _startBlock;
}
// Add a new lp to the pool. Can only be called by the owner.
// Add a new lp to the pool. Can only be called by the owner.
// XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.
// XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.
복사
복사됨
복사
복사됨
function add(uint256 _allocPoint, IBEP20 _lpToken, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyO
wner
{
function add(uint256 _allocPoint, IBEP20 _lpToken, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyO
perator
{
require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points");
require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points");
require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "add: invalid harvest interval");
require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "add: invalid harvest interval");
if (_withUpdate) {
if (_withUpdate) {
massUpdatePools();
massUpdatePools();
}
}
uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
totalAllocPoint = totalAllocPoint.add(_allocPoint);
totalAllocPoint = totalAllocPoint.add(_allocPoint);
poolInfo.push(PoolInfo({
poolInfo.push(PoolInfo({
lpToken: _lpToken,
lpToken: _lpToken,
allocPoint: _allocPoint,
allocPoint: _allocPoint,
lastRewardBlock: lastRewardBlock,
lastRewardBlock: lastRewardBlock,
복사
복사됨
복사
복사됨
acc
Panther
PerShare: 0,
acc
Blaze
PerShare: 0,
depositFeeBP: _depositFeeBP,
depositFeeBP: _depositFeeBP,
harvestInterval: _harvestInterval
harvestInterval: _harvestInterval
}));
}));
}
}
복사
복사됨
복사
복사됨
// Update the given pool's
PANTHER
allocation point and deposit fee. Can only be called by the owner.
// Update the given pool's
BLAZE
allocation point and deposit fee. Can only be called by the owner.
function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyO
wner
{
function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyO
perator
{
require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points");
require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points");
require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "set: invalid harvest interval");
require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "set: invalid harvest interval");
if (_withUpdate) {
if (_withUpdate) {
massUpdatePools();
massUpdatePools();
}
}
totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
poolInfo[_pid].allocPoint = _allocPoint;
poolInfo[_pid].allocPoint = _allocPoint;
poolInfo[_pid].depositFeeBP = _depositFeeBP;
poolInfo[_pid].depositFeeBP = _depositFeeBP;
poolInfo[_pid].harvestInterval = _harvestInterval;
poolInfo[_pid].harvestInterval = _harvestInterval;
}
}
// Return reward multiplier over the given _from to _to block.
// Return reward multiplier over the given _from to _to block.
function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) {
function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) {
return _to.sub(_from).mul(BONUS_MULTIPLIER);
return _to.sub(_from).mul(BONUS_MULTIPLIER);
}
}
복사
복사됨
복사
복사됨
// View function to see pending
PANTHERs
on frontend.
// View function to see pending
BLAZEs
on frontend.
function pending
Panther
(uint256 _pid, address _user) external view returns (uint256) {
function pending
Blaze
(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
Panther
PerShare = pool.acc
Panther
PerShare;
uint256 acc
Blaze
PerShare = pool.acc
Blaze
PerShare;
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (block.number > pool.lastRewardBlock && lpSupply != 0) {
if (block.number > pool.lastRewardBlock && lpSupply != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
복사
복사됨
복사
복사됨
uint256
panther
Reward = multiplier.mul(
panther
PerBlock).mul(pool.allocPoint).div(totalAllocPoint);
uint256
blaze
Reward = multiplier.mul(
blaze
PerBlock).mul(pool.allocPoint).div(totalAllocPoint);
acc
Panther
PerShare = acc
Panther
PerShare.add(
panther
Reward.mul(1e12).div(lpSupply));
acc
Blaze
PerShare = acc
Blaze
PerShare.add(
blaze
Reward.mul(1e12).div(lpSupply));
}
}
복사
복사됨
복사
복사됨
uint256 pending = user.amount.mul(acc
Panther
PerShare).div(1e12).sub(user.rewardDebt);
uint256 pending = user.amount.mul(acc
Blaze
PerShare).div(1e12).sub(user.rewardDebt);
return pending.add(user.rewardLockedUp);
return pending.add(user.rewardLockedUp);
}
}
복사
복사됨
복사
복사됨
// View function to see if user can harvest
PANTHERs
.
// View function to see if user can harvest
BLAZEs
.
function canHarvest(uint256 _pid, address _user) public view returns (bool) {
function canHarvest(uint256 _pid, address _user) public view returns (bool) {
UserInfo storage user = userInfo[_pid][_user];
UserInfo storage user = userInfo[_pid][_user];
return block.timestamp >= user.nextHarvestUntil;
return block.timestamp >= user.nextHarvestUntil;
}
}
// Update reward variables for all pools. Be careful of gas spending!
// 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);
}
}
}
}
// 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) public {
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
if (block.number <= pool.lastRewardBlock) {
return;
return;
}
}
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (lpSupply == 0 || pool.allocPoint == 0) {
if (lpSupply == 0 || pool.allocPoint == 0) {
pool.lastRewardBlock = block.number;
pool.lastRewardBlock = block.number;
return;
return;
}
}
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
복사
복사됨
복사
복사됨
uint256
panther
Reward = multiplier.mul(
panther
PerBlock).mul(pool.allocPoint).div(totalAllocPoint);
uint256
blaze
Reward = multiplier.mul(
blaze
PerBlock).mul(pool.allocPoint).div(totalAllocPoint);
panther
.mint(devAddress,
panther
Reward.div(10));
blaze
.mint(devAddress,
blaze
Reward.div(10));
panther
.mint(address(this),
panther
Reward);
blaze
.mint(address(this),
blaze
Reward);
pool.acc
Panther
PerShare = pool.acc
Panther
PerShare.add(
panther
Reward.mul(1e12).div(lpSupply));
pool.acc
Blaze
PerShare = pool.acc
Blaze
PerShare.add(
blaze
Reward.mul(1e12).div(lpSupply));
pool.lastRewardBlock = block.number;
pool.lastRewardBlock = block.number;
}
}
복사
복사됨
복사
복사됨
// Deposit LP tokens to
MasterChef
for
PANTHER
allocation.
// Deposit LP tokens to
CookingFire
for
BLAZE
allocation.
function deposit(uint256 _pid, uint256 _amount, address _referrer) public nonReentrant {
function deposit(uint256 _pid, uint256 _amount, address _referrer) 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];
updatePool(_pid);
updatePool(_pid);
복사
복사됨
복사
복사됨
if (_amount > 0 && address(
panther
Referral) != address(0) && _referrer != address(0) && _referrer != msg.sender) {
if (_amount > 0 && address(
blaze
Referral) != address(0) && _referrer != address(0) && _referrer != msg.sender) {
panther
Referral.recordReferral(msg.sender, _referrer);
blaze
Referral.recordReferral(msg.sender, _referrer);
}
}
복사
복사됨
복사
복사됨
payOrLockupPending
Panther
(_pid);
payOrLockupPending
Blaze
(_pid);
if (_amount > 0) {
if (_amount > 0) {
pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
복사
복사됨
복사
복사됨
if (address(pool.lpToken) == address(panther)) {
uint256 transferTax = _amount.mul(panther.transferTaxRate()).div(10000);
_amount = _amount.sub(transferTax);
}
if (pool.depositFeeBP > 0) {
if (pool.depositFeeBP > 0) {
uint256 depositFee = _amount.mul(pool.depositFeeBP).div(10000);
uint256 depositFee = _amount.mul(pool.depositFeeBP).div(10000);
pool.lpToken.safeTransfer(feeAddress, depositFee);
pool.lpToken.safeTransfer(feeAddress, depositFee);
user.amount = user.amount.add(_amount).sub(depositFee);
user.amount = user.amount.add(_amount).sub(depositFee);
} else {
} else {
user.amount = user.amount.add(_amount);
user.amount = user.amount.add(_amount);
}
}
}
}
복사
복사됨
복사
복사됨
user.rewardDebt = user.amount.mul(pool.acc
Panther
PerShare).div(1e12);
user.rewardDebt = user.amount.mul(pool.acc
Blaze
PerShare).div(1e12);
emit Deposit(msg.sender, _pid, _amount);
emit Deposit(msg.sender, _pid, _amount);
}
}
복사
복사됨
복사
복사됨
// Withdraw LP tokens from
MasterChef
.
// Withdraw LP tokens from
CookingFire
.
function withdraw(uint256 _pid, uint256 _amount) public nonReentrant {
function withdraw(uint256 _pid, uint256 _amount) 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];
require(user.amount >= _amount, "withdraw: not good");
require(user.amount >= _amount, "withdraw: not good");
updatePool(_pid);
updatePool(_pid);
복사
복사됨
복사
복사됨
payOrLockupPending
Panther
(_pid);
payOrLockupPending
Blaze
(_pid);
if (_amount > 0) {
if (_amount > 0) {
user.amount = user.amount.sub(_amount);
user.amount = user.amount.sub(_amount);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
}
}
복사
복사됨
복사
복사됨
user.rewardDebt = user.amount.mul(pool.acc
Panther
PerShare).div(1e12);
user.rewardDebt = user.amount.mul(pool.acc
Blaze
PerShare).div(1e12);
emit Withdraw(msg.sender, _pid, _amount);
emit Withdraw(msg.sender, _pid, _amount);
}
}
// Withdraw without caring about rewards. EMERGENCY ONLY.
// Withdraw without caring about rewards. EMERGENCY ONLY.
function emergencyWithdraw(uint256 _pid) public nonReentrant {
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;
user.rewardLockedUp = 0;
user.rewardLockedUp = 0;
user.nextHarvestUntil = 0;
user.nextHarvestUntil = 0;
pool.lpToken.safeTransfer(address(msg.sender), amount);
pool.lpToken.safeTransfer(address(msg.sender), amount);
emit EmergencyWithdraw(msg.sender, _pid, amount);
emit EmergencyWithdraw(msg.sender, _pid, amount);
}
}
복사
복사됨
복사
복사됨
// Pay or lockup pending
PANTHERs
.
// Pay or lockup pending
BLAZEs
.
function payOrLockupPending
Panther
(uint256 _pid) internal {
function payOrLockupPending
Blaze
(uint256 _pid) internal {
PoolInfo storage pool = poolInfo[_pid];
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
UserInfo storage user = userInfo[_pid][msg.sender];
if (user.nextHarvestUntil == 0) {
if (user.nextHarvestUntil == 0) {
user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval);
user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval);
}
}
복사
복사됨
복사
복사됨
uint256 pending = user.amount.mul(pool.acc
Panther
PerShare).div(1e12).sub(user.rewardDebt);
uint256 pending = user.amount.mul(pool.acc
Blaze
PerShare).div(1e12).sub(user.rewardDebt);
if (canHarvest(_pid, msg.sender)) {
if (canHarvest(_pid, msg.sender)) {
if (pending > 0 || user.rewardLockedUp > 0) {
if (pending > 0 || user.rewardLockedUp > 0) {
uint256 totalRewards = pending.add(user.rewardLockedUp);
uint256 totalRewards = pending.add(user.rewardLockedUp);
// reset lockup
// reset lockup
totalLockedUpRewards = totalLockedUpRewards.sub(user.rewardLockedUp);
totalLockedUpRewards = totalLockedUpRewards.sub(user.rewardLockedUp);
user.rewardLockedUp = 0;
user.rewardLockedUp = 0;
user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval);
user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval);
// send rewards
// send rewards
복사
복사됨
복사
복사됨
safe
Panther
Transfer(msg.sender, totalRewards);
safe
Blaze
Transfer(msg.sender, totalRewards);
payReferralCommission(msg.sender, totalRewards);
payReferralCommission(msg.sender, totalRewards);
}
}
} else if (pending > 0) {
} else if (pending > 0) {
user.rewardLockedUp = user.rewardLockedUp.add(pending);
user.rewardLockedUp = user.rewardLockedUp.add(pending);
totalLockedUpRewards = totalLockedUpRewards.add(pending);
totalLockedUpRewards = totalLockedUpRewards.add(pending);
emit RewardLockedUp(msg.sender, _pid, pending);
emit RewardLockedUp(msg.sender, _pid, pending);
}
}
}
}
복사
복사됨
복사
복사됨
// Safe
panther
transfer function, just in case if rounding error causes pool to not have enough
PANTHERs
.
// Safe
blaze
transfer function, just in case if rounding error causes pool to not have enough
BLAZEs
.
function safe
Panther
Transfer(address _to, uint256 _amount) internal {
function safe
Blaze
Transfer(address _to, uint256 _amount) internal {
uint256
pantherBal
=
panther
.balanceOf(address(this));
uint256
blazeBal
=
blaze
.balanceOf(address(this));
if (_amount >
pantherBal
) {
if (_amount >
blazeBal
) {
panther
.transfer(_to,
pantherBal
);
blaze
.transfer(_to,
blazeBal
);
} else {
} else {
복사
복사됨
복사
복사됨
panther
.transfer(_to, _amount);
blaze
.transfer(_to, _amount);
}
}
}
}
// Update dev address by the previous dev.
// Update dev address by the previous dev.
복사
복사됨
복사
복사됨
function setOperator(address _op) public onlyOperator {
_operator = _op;
}
function setDevAddress(address _devAddress) public {
function setDevAddress(address _devAddress) public {
require(msg.sender == devAddress, "setDevAddress: FORBIDDEN");
require(msg.sender == devAddress, "setDevAddress: FORBIDDEN");
require(_devAddress != address(0), "setDevAddress: ZERO");
require(_devAddress != address(0), "setDevAddress: ZERO");
devAddress = _devAddress;
devAddress = _devAddress;
}
}
function setFeeAddress(address _feeAddress) public {
function setFeeAddress(address _feeAddress) public {
require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN");
require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN");
require(_feeAddress != address(0), "setFeeAddress: ZERO");
require(_feeAddress != address(0), "setFeeAddress: ZERO");
feeAddress = _feeAddress;
feeAddress = _feeAddress;
}
}
// Pancake has to add hidden dummy pools in order to alter the emission, here we make it simple and transparent to all.
// Pancake has to add hidden dummy pools in order to alter the emission, here we make it simple and transparent to all.
복사
복사됨
복사
복사됨
function updateEmissionRate(uint256 _
panther
PerBlock) public onlyO
wner
{
function updateEmissionRate(uint256 _
blaze
PerBlock) public onlyO
perator
{
massUpdatePools();
massUpdatePools();
복사
복사됨
복사
복사됨
emit EmissionRateUpdated(msg.sender,
panther
PerBlock, _
panther
PerBlock);
emit EmissionRateUpdated(msg.sender,
blaze
PerBlock, _
blaze
PerBlock);
panther
PerBlock = _
panther
PerBlock;
blaze
PerBlock = _
blaze
PerBlock;
}
}
복사
복사됨
복사
복사됨
// Update the
panther
referral contract address by the owner
// Update the
blaze
referral contract address by the owner
function set
Panther
Referral(I
Panther
Referral _
panther
Referral) public onlyOwner {
function set
Blaze
Referral(I
Blaze
Referral _
blaze
Referral) public onlyOwner {
panther
Referral = _
panther
Referral;
blaze
Referral = _
blaze
Referral;
}
}
// Update referral commission rate by the owner
// Update referral commission rate by the owner
function setReferralCommissionRate(uint16 _referralCommissionRate) public onlyOwner {
function setReferralCommissionRate(uint16 _referralCommissionRate) public onlyOwner {
require(_referralCommissionRate <= MAXIMUM_REFERRAL_COMMISSION_RATE, "setReferralCommissionRate: invalid referral commission rate basis points");
require(_referralCommissionRate <= MAXIMUM_REFERRAL_COMMISSION_RATE, "setReferralCommissionRate: invalid referral commission rate basis points");
referralCommissionRate = _referralCommissionRate;
referralCommissionRate = _referralCommissionRate;
}
}
// Pay referral commission to the referrer who referred this user.
// Pay referral commission to the referrer who referred this user.
function payReferralCommission(address _user, uint256 _pending) internal {
function payReferralCommission(address _user, uint256 _pending) internal {
복사
복사됨
복사
복사됨
if (address(
panther
Referral) != address(0) && referralCommissionRate > 0) {
if (address(
blaze
Referral) != address(0) && referralCommissionRate > 0) {
address referrer =
panther
Referral.getReferrer(_user);
address referrer =
blaze
Referral.getReferrer(_user);
uint256 commissionAmount = _pending.mul(referralCommissionRate).div(10000);
uint256 commissionAmount = _pending.mul(referralCommissionRate).div(10000);
if (referrer != address(0) && commissionAmount > 0) {
if (referrer != address(0) && commissionAmount > 0) {
복사
복사됨
복사
복사됨
panther
.mint(referrer, commissionAmount);
blaze
.mint(referrer, commissionAmount);
panther
Referral.recordReferralCommission(referrer, commissionAmount);
blaze
Referral.recordReferralCommission(referrer, commissionAmount);
emit ReferralCommissionPaid(_user, referrer, commissionAmount);
emit ReferralCommissionPaid(_user, referrer, commissionAmount);
}
}
}
}
}
}
}
}
저장된 비교 결과
원본
파일 열기
contract MasterChef is Ownable, ReentrancyGuard { using SafeMath for uint256; using SafeBEP20 for IBEP20; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. uint256 rewardLockedUp; // Reward locked up. uint256 nextHarvestUntil; // When can the user harvest again. // // We do some fancy math here. Basically, any point in time, the amount of PANTHERs // entitled to a user but is pending to be distributed is: // // pending reward = (user.amount * pool.accPantherPerShare) - user.rewardDebt // // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens: // 1. The pool's `accPantherPerShare` (and `lastRewardBlock`) gets updated. // 2. User receives the pending reward sent to his/her address. // 3. User's `amount` gets updated. // 4. User's `rewardDebt` gets updated. } // Info of each pool. struct PoolInfo { IBEP20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. PANTHERs to distribute per block. uint256 lastRewardBlock; // Last block number that PANTHERs distribution occurs. uint256 accPantherPerShare; // Accumulated PANTHERs per share, times 1e12. See below. uint16 depositFeeBP; // Deposit fee in basis points uint256 harvestInterval; // Harvest interval in seconds } // The PANTHER TOKEN! PantherToken public panther; // Dev address. address public devAddress; // Deposit Fee address address public feeAddress; // PANTHER tokens created per block. uint256 public pantherPerBlock; // Bonus muliplier for early panther makers. uint256 public constant BONUS_MULTIPLIER = 1; // Max harvest interval: 14 days. uint256 public constant MAXIMUM_HARVEST_INTERVAL = 14 days; // 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 block number when PANTHER mining starts. uint256 public startBlock; // Total locked up rewards uint256 public totalLockedUpRewards; // Panther referral contract address. IPantherReferral public pantherReferral; // Referral commission rate in basis points. uint16 public referralCommissionRate = 100; // Max referral commission rate: 10%. uint16 public constant MAXIMUM_REFERRAL_COMMISSION_RATE = 1000; 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 EmissionRateUpdated(address indexed caller, uint256 previousAmount, uint256 newAmount); event ReferralCommissionPaid(address indexed user, address indexed referrer, uint256 commissionAmount); event RewardLockedUp(address indexed user, uint256 indexed pid, uint256 amountLockedUp); constructor( PantherToken _panther, uint256 _startBlock, uint256 _pantherPerBlock ) public { panther = _panther; startBlock = _startBlock; pantherPerBlock = _pantherPerBlock; devAddress = msg.sender; feeAddress = msg.sender; } function poolLength() external view returns (uint256) { return poolInfo.length; } // Add a new lp to the pool. Can only be called by the owner. // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do. function add(uint256 _allocPoint, IBEP20 _lpToken, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyOwner { require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points"); require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "add: invalid harvest interval"); if (_withUpdate) { massUpdatePools(); } uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock; totalAllocPoint = totalAllocPoint.add(_allocPoint); poolInfo.push(PoolInfo({ lpToken: _lpToken, allocPoint: _allocPoint, lastRewardBlock: lastRewardBlock, accPantherPerShare: 0, depositFeeBP: _depositFeeBP, harvestInterval: _harvestInterval })); } // Update the given pool's PANTHER allocation point and deposit fee. Can only be called by the owner. function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyOwner { require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points"); require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "set: invalid harvest interval"); if (_withUpdate) { massUpdatePools(); } totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint); poolInfo[_pid].allocPoint = _allocPoint; poolInfo[_pid].depositFeeBP = _depositFeeBP; poolInfo[_pid].harvestInterval = _harvestInterval; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) { return _to.sub(_from).mul(BONUS_MULTIPLIER); } // View function to see pending PANTHERs on frontend. function pendingPanther(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accPantherPerShare = pool.accPantherPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.number > pool.lastRewardBlock && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 pantherReward = multiplier.mul(pantherPerBlock).mul(pool.allocPoint).div(totalAllocPoint); accPantherPerShare = accPantherPerShare.add(pantherReward.mul(1e12).div(lpSupply)); } uint256 pending = user.amount.mul(accPantherPerShare).div(1e12).sub(user.rewardDebt); return pending.add(user.rewardLockedUp); } // View function to see if user can harvest PANTHERs. function canHarvest(uint256 _pid, address _user) public view returns (bool) { UserInfo storage user = userInfo[_pid][_user]; return block.timestamp >= user.nextHarvestUntil; } // 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.number <= pool.lastRewardBlock) { return; } uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (lpSupply == 0 || pool.allocPoint == 0) { pool.lastRewardBlock = block.number; return; } uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 pantherReward = multiplier.mul(pantherPerBlock).mul(pool.allocPoint).div(totalAllocPoint); panther.mint(devAddress, pantherReward.div(10)); panther.mint(address(this), pantherReward); pool.accPantherPerShare = pool.accPantherPerShare.add(pantherReward.mul(1e12).div(lpSupply)); pool.lastRewardBlock = block.number; } // Deposit LP tokens to MasterChef for PANTHER allocation. function deposit(uint256 _pid, uint256 _amount, address _referrer) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); if (_amount > 0 && address(pantherReferral) != address(0) && _referrer != address(0) && _referrer != msg.sender) { pantherReferral.recordReferral(msg.sender, _referrer); } payOrLockupPendingPanther(_pid); if (_amount > 0) { pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); if (address(pool.lpToken) == address(panther)) { uint256 transferTax = _amount.mul(panther.transferTaxRate()).div(10000); _amount = _amount.sub(transferTax); } if (pool.depositFeeBP > 0) { uint256 depositFee = _amount.mul(pool.depositFeeBP).div(10000); pool.lpToken.safeTransfer(feeAddress, depositFee); user.amount = user.amount.add(_amount).sub(depositFee); } else { user.amount = user.amount.add(_amount); } } user.rewardDebt = user.amount.mul(pool.accPantherPerShare).div(1e12); emit Deposit(msg.sender, _pid, _amount); } // Withdraw LP tokens from MasterChef. function withdraw(uint256 _pid, uint256 _amount) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); payOrLockupPendingPanther(_pid); if (_amount > 0) { user.amount = user.amount.sub(_amount); pool.lpToken.safeTransfer(address(msg.sender), _amount); } user.rewardDebt = user.amount.mul(pool.accPantherPerShare).div(1e12); emit Withdraw(msg.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; user.rewardLockedUp = 0; user.nextHarvestUntil = 0; pool.lpToken.safeTransfer(address(msg.sender), amount); emit EmergencyWithdraw(msg.sender, _pid, amount); } // Pay or lockup pending PANTHERs. function payOrLockupPendingPanther(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; if (user.nextHarvestUntil == 0) { user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval); } uint256 pending = user.amount.mul(pool.accPantherPerShare).div(1e12).sub(user.rewardDebt); if (canHarvest(_pid, msg.sender)) { if (pending > 0 || user.rewardLockedUp > 0) { uint256 totalRewards = pending.add(user.rewardLockedUp); // reset lockup totalLockedUpRewards = totalLockedUpRewards.sub(user.rewardLockedUp); user.rewardLockedUp = 0; user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval); // send rewards safePantherTransfer(msg.sender, totalRewards); payReferralCommission(msg.sender, totalRewards); } } else if (pending > 0) { user.rewardLockedUp = user.rewardLockedUp.add(pending); totalLockedUpRewards = totalLockedUpRewards.add(pending); emit RewardLockedUp(msg.sender, _pid, pending); } } // Safe panther transfer function, just in case if rounding error causes pool to not have enough PANTHERs. function safePantherTransfer(address _to, uint256 _amount) internal { uint256 pantherBal = panther.balanceOf(address(this)); if (_amount > pantherBal) { panther.transfer(_to, pantherBal); } else { panther.transfer(_to, _amount); } } // Update dev address by the previous dev. function setDevAddress(address _devAddress) public { require(msg.sender == devAddress, "setDevAddress: FORBIDDEN"); require(_devAddress != address(0), "setDevAddress: ZERO"); devAddress = _devAddress; } function setFeeAddress(address _feeAddress) public { require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN"); require(_feeAddress != address(0), "setFeeAddress: ZERO"); feeAddress = _feeAddress; } // Pancake has to add hidden dummy pools in order to alter the emission, here we make it simple and transparent to all. function updateEmissionRate(uint256 _pantherPerBlock) public onlyOwner { massUpdatePools(); emit EmissionRateUpdated(msg.sender, pantherPerBlock, _pantherPerBlock); pantherPerBlock = _pantherPerBlock; } // Update the panther referral contract address by the owner function setPantherReferral(IPantherReferral _pantherReferral) public onlyOwner { pantherReferral = _pantherReferral; } // Update referral commission rate by the owner function setReferralCommissionRate(uint16 _referralCommissionRate) public onlyOwner { require(_referralCommissionRate <= MAXIMUM_REFERRAL_COMMISSION_RATE, "setReferralCommissionRate: invalid referral commission rate basis points"); referralCommissionRate = _referralCommissionRate; } // Pay referral commission to the referrer who referred this user. function payReferralCommission(address _user, uint256 _pending) internal { if (address(pantherReferral) != address(0) && referralCommissionRate > 0) { address referrer = pantherReferral.getReferrer(_user); uint256 commissionAmount = _pending.mul(referralCommissionRate).div(10000); if (referrer != address(0) && commissionAmount > 0) { panther.mint(referrer, commissionAmount); pantherReferral.recordReferralCommission(referrer, commissionAmount); emit ReferralCommissionPaid(_user, referrer, commissionAmount); } } } }
수정본
파일 열기
contract CookingFire is Ownable, ReentrancyGuard { using SafeMath for uint256; using SafeBEP20 for IBEP20; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. uint256 rewardLockedUp; // Reward locked up. uint256 nextHarvestUntil; // When can the user harvest again. // // We do some fancy math here. Basically, any point in time, the amount of BLAZEs // entitled to a user but is pending to be distributed is: // // pending reward = (user.amount * pool.accBlazePerShare) - user.rewardDebt // // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens: // 1. The pool's `accBlazePerShare` (and `lastRewardBlock`) gets updated. // 2. User receives the pending reward sent to his/her address. // 3. User's `amount` gets updated. // 4. User's `rewardDebt` gets updated. } // Info of each pool. struct PoolInfo { IBEP20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. BLAZEs to distribute per block. uint256 lastRewardBlock; // Last block number that BLAZEs distribution occurs. uint256 accBlazePerShare; // Accumulated BLAZEs per share, times 1e12. See below. uint16 depositFeeBP; // Deposit fee in basis points uint256 harvestInterval; // Harvest interval in seconds } // The BLAZE TOKEN! BlazeToken public blaze; // Dev address. address public devAddress; // Deposit Fee address address public feeAddress; // BLAZE tokens created per block. uint256 public blazePerBlock; // Bonus muliplier for early blaze makers. uint256 public constant BONUS_MULTIPLIER = 1; // Max harvest interval: 14 days. uint256 public constant MAXIMUM_HARVEST_INTERVAL = 14 days; // 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 block number when BLAZE mining starts. uint256 public startBlock; // Total locked up rewards uint256 public totalLockedUpRewards; // Blaze referral contract address. IBlazeReferral public blazeReferral; // Referral commission rate in basis points. uint16 public referralCommissionRate = 100; // Max referral commission rate: 10%. uint16 public constant MAXIMUM_REFERRAL_COMMISSION_RATE = 1000; address private _operator; 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 EmissionRateUpdated(address indexed caller, uint256 previousAmount, uint256 newAmount); event ReferralCommissionPaid(address indexed user, address indexed referrer, uint256 commissionAmount); event RewardLockedUp(address indexed user, uint256 indexed pid, uint256 amountLockedUp); modifier onlyOperator() { require(_operator == msg.sender, "operator: caller is not the operator"); _; } constructor( BlazeToken _blaze, uint256 _startBlock, uint256 _blazePerBlock ) public { blaze = _blaze; startBlock = _startBlock; blazePerBlock = _blazePerBlock; _operator = msg.sender; devAddress = msg.sender; feeAddress = msg.sender; } function poolLength() external view returns (uint256) { return poolInfo.length; } function updateOperator(address _op) public onlyOperator { _operator = _op; } function updateStartBlock(uint256 _startBlock) public onlyOperator { require(block.number > startBlock, "updateStartBlock: farming already initiated"); startBlock = _startBlock; } // Add a new lp to the pool. Can only be called by the owner. // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do. function add(uint256 _allocPoint, IBEP20 _lpToken, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyOperator { require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points"); require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "add: invalid harvest interval"); if (_withUpdate) { massUpdatePools(); } uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock; totalAllocPoint = totalAllocPoint.add(_allocPoint); poolInfo.push(PoolInfo({ lpToken: _lpToken, allocPoint: _allocPoint, lastRewardBlock: lastRewardBlock, accBlazePerShare: 0, depositFeeBP: _depositFeeBP, harvestInterval: _harvestInterval })); } // Update the given pool's BLAZE allocation point and deposit fee. Can only be called by the owner. function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, uint256 _harvestInterval, bool _withUpdate) public onlyOperator { require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points"); require(_harvestInterval <= MAXIMUM_HARVEST_INTERVAL, "set: invalid harvest interval"); if (_withUpdate) { massUpdatePools(); } totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint); poolInfo[_pid].allocPoint = _allocPoint; poolInfo[_pid].depositFeeBP = _depositFeeBP; poolInfo[_pid].harvestInterval = _harvestInterval; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) { return _to.sub(_from).mul(BONUS_MULTIPLIER); } // View function to see pending BLAZEs on frontend. function pendingBlaze(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accBlazePerShare = pool.accBlazePerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.number > pool.lastRewardBlock && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 blazeReward = multiplier.mul(blazePerBlock).mul(pool.allocPoint).div(totalAllocPoint); accBlazePerShare = accBlazePerShare.add(blazeReward.mul(1e12).div(lpSupply)); } uint256 pending = user.amount.mul(accBlazePerShare).div(1e12).sub(user.rewardDebt); return pending.add(user.rewardLockedUp); } // View function to see if user can harvest BLAZEs. function canHarvest(uint256 _pid, address _user) public view returns (bool) { UserInfo storage user = userInfo[_pid][_user]; return block.timestamp >= user.nextHarvestUntil; } // 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.number <= pool.lastRewardBlock) { return; } uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (lpSupply == 0 || pool.allocPoint == 0) { pool.lastRewardBlock = block.number; return; } uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 blazeReward = multiplier.mul(blazePerBlock).mul(pool.allocPoint).div(totalAllocPoint); blaze.mint(devAddress, blazeReward.div(10)); blaze.mint(address(this), blazeReward); pool.accBlazePerShare = pool.accBlazePerShare.add(blazeReward.mul(1e12).div(lpSupply)); pool.lastRewardBlock = block.number; } // Deposit LP tokens to CookingFire for BLAZE allocation. function deposit(uint256 _pid, uint256 _amount, address _referrer) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); if (_amount > 0 && address(blazeReferral) != address(0) && _referrer != address(0) && _referrer != msg.sender) { blazeReferral.recordReferral(msg.sender, _referrer); } payOrLockupPendingBlaze(_pid); if (_amount > 0) { pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); if (pool.depositFeeBP > 0) { uint256 depositFee = _amount.mul(pool.depositFeeBP).div(10000); pool.lpToken.safeTransfer(feeAddress, depositFee); user.amount = user.amount.add(_amount).sub(depositFee); } else { user.amount = user.amount.add(_amount); } } user.rewardDebt = user.amount.mul(pool.accBlazePerShare).div(1e12); emit Deposit(msg.sender, _pid, _amount); } // Withdraw LP tokens from CookingFire. function withdraw(uint256 _pid, uint256 _amount) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); payOrLockupPendingBlaze(_pid); if (_amount > 0) { user.amount = user.amount.sub(_amount); pool.lpToken.safeTransfer(address(msg.sender), _amount); } user.rewardDebt = user.amount.mul(pool.accBlazePerShare).div(1e12); emit Withdraw(msg.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; user.rewardLockedUp = 0; user.nextHarvestUntil = 0; pool.lpToken.safeTransfer(address(msg.sender), amount); emit EmergencyWithdraw(msg.sender, _pid, amount); } // Pay or lockup pending BLAZEs. function payOrLockupPendingBlaze(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; if (user.nextHarvestUntil == 0) { user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval); } uint256 pending = user.amount.mul(pool.accBlazePerShare).div(1e12).sub(user.rewardDebt); if (canHarvest(_pid, msg.sender)) { if (pending > 0 || user.rewardLockedUp > 0) { uint256 totalRewards = pending.add(user.rewardLockedUp); // reset lockup totalLockedUpRewards = totalLockedUpRewards.sub(user.rewardLockedUp); user.rewardLockedUp = 0; user.nextHarvestUntil = block.timestamp.add(pool.harvestInterval); // send rewards safeBlazeTransfer(msg.sender, totalRewards); payReferralCommission(msg.sender, totalRewards); } } else if (pending > 0) { user.rewardLockedUp = user.rewardLockedUp.add(pending); totalLockedUpRewards = totalLockedUpRewards.add(pending); emit RewardLockedUp(msg.sender, _pid, pending); } } // Safe blaze transfer function, just in case if rounding error causes pool to not have enough BLAZEs. function safeBlazeTransfer(address _to, uint256 _amount) internal { uint256 blazeBal = blaze.balanceOf(address(this)); if (_amount > blazeBal) { blaze.transfer(_to, blazeBal); } else { blaze.transfer(_to, _amount); } } // Update dev address by the previous dev. function setOperator(address _op) public onlyOperator { _operator = _op; } function setDevAddress(address _devAddress) public { require(msg.sender == devAddress, "setDevAddress: FORBIDDEN"); require(_devAddress != address(0), "setDevAddress: ZERO"); devAddress = _devAddress; } function setFeeAddress(address _feeAddress) public { require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN"); require(_feeAddress != address(0), "setFeeAddress: ZERO"); feeAddress = _feeAddress; } // Pancake has to add hidden dummy pools in order to alter the emission, here we make it simple and transparent to all. function updateEmissionRate(uint256 _blazePerBlock) public onlyOperator { massUpdatePools(); emit EmissionRateUpdated(msg.sender, blazePerBlock, _blazePerBlock); blazePerBlock = _blazePerBlock; } // Update the blaze referral contract address by the owner function setBlazeReferral(IBlazeReferral _blazeReferral) public onlyOwner { blazeReferral = _blazeReferral; } // Update referral commission rate by the owner function setReferralCommissionRate(uint16 _referralCommissionRate) public onlyOwner { require(_referralCommissionRate <= MAXIMUM_REFERRAL_COMMISSION_RATE, "setReferralCommissionRate: invalid referral commission rate basis points"); referralCommissionRate = _referralCommissionRate; } // Pay referral commission to the referrer who referred this user. function payReferralCommission(address _user, uint256 _pending) internal { if (address(blazeReferral) != address(0) && referralCommissionRate > 0) { address referrer = blazeReferral.getReferrer(_user); uint256 commissionAmount = _pending.mul(referralCommissionRate).div(10000); if (referrer != address(0) && commissionAmount > 0) { blaze.mint(referrer, commissionAmount); blazeReferral.recordReferralCommission(referrer, commissionAmount); emit ReferralCommissionPaid(_user, referrer, commissionAmount); } } } }
비교하기