Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
실시간 편집
변경 없는 행 숨기기
줄바꿈 비활성화
레이아웃
나란히 보기
합쳐 보기
비교 단위
스마트
단어
글자
구문 강조
언어 선택
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
LYPTUS Masterchef vs EGG Masterchef
생성일
5년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
79 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
258 행
복사
68 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
246 행
복사
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
pragma solidity 0.6.12;
복사
복사됨
복사
복사됨
// .----------------. .----------------. .----------------. .----------------. .----------------.
import "
@openzeppelin/contracts/math
/SafeMath.sol";
// | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |
import ".
/libs
/IBEP20.sol";
// | | ___ ____ | || | ____ | || | __ | || | _____ | || | __ | |
import "./
libs/
SafeBEP20.sol";
// | | |_ ||_ _| | || | .' `. | || | / \ | || | |_ _| | || | / \ | |
import "
@openzeppelin/contracts/access
/Ownable.sol";
// | | | |_/ / | || | / .--. \ | || | / /\ \ | || | | | | || | / /\ \ | |
// | | | __'. | || | | | | | | || | / ____ \ | || | | | _ | || | / ____ \ | |
// | | _| | \ \_ | || | \ `--' / | || | _/ / \ \_ | || | _| |__/ | | || | _/ / \ \_ | |
// | | |____||____| | || | `.____.' | || ||____| |____|| || | |________| | || ||____| |____|| |
// | | | || | | || | | || | | || | | |
// | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |
// '----------------' '----------------' '----------------' '----------------' '----------------'
import "
.
/SafeMath.sol";
import ".
/IBEP20.sol";
import "./
SafeBEP20.sol";
import "
.
/Ownable.sol";
복사
복사됨
복사
복사됨
import "./
LYPTUSToken
.sol";
import "./
EggToken
.sol";
복사
복사됨
복사
복사됨
// MasterChef is the master of
Lyptus
. He can make
Lyptus
and he is a fair guy.
// MasterChef is the master of
Egg
. He can make
Egg
and he is a fair guy.
//
//
// Note that it's ownable and the owner wields tremendous power. The ownership
// Note that it's ownable and the owner wields tremendous power. The ownership
복사
복사됨
복사
복사됨
// will be transferred to a governance smart contract once
LYPTUS
is sufficiently
// will be transferred to a governance smart contract once
EGG
is sufficiently
// distributed and the community can show to govern itself.
// distributed and the community can show to govern itself.
//
//
// Have fun reading it. Hopefully it's bug-free. God bless.
// Have fun reading it. Hopefully it's bug-free. God bless.
contract MasterChef is Ownable {
contract MasterChef is Ownable {
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.
//
//
복사
복사됨
복사
복사됨
// We do some fancy math here. Basically, any point in time, the amount of
LYPTUSs
// We do some fancy math here. Basically, any point in time, the amount of
EGGs
// 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
Lyptus
PerShare) - user.rewardDebt
// pending reward = (user.amount * pool.acc
Egg
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
Lyptus
PerShare` (and `lastRewardBlock`) gets updated.
// 1. The pool's `acc
Egg
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.
LYPTUSs
to distribute per block.
uint256 allocPoint; // How many allocation points assigned to this pool.
EGGs
to distribute per block.
uint256 lastRewardBlock; // Last block number that
LYPTUSs
distribution occurs.
uint256 lastRewardBlock; // Last block number that
EGGs
distribution occurs.
uint256 acc
Lyptus
PerShare; // Accumulated
LYPTUSs
per share, times 1e12. See below.
uint256 acc
Egg
PerShare; // Accumulated
EGGs
per share, times 1e12. See below.
uint16 depositFeeBP; // Deposit fee in basis points
uint16 depositFeeBP; // Deposit fee in basis points
}
}
복사
복사됨
복사
복사됨
// The
LYPTUS
TOKEN!
// The
EGG
TOKEN!
LyptusToken
public
lyptus
;
EggToken
public
egg
;
// Dev address.
// Dev address.
address public devaddr;
address public devaddr;
복사
복사됨
복사
복사됨
//
LYPTUS
tokens created per block.
//
EGG
tokens created per block.
uint256 public
lyptusPerBlock
;
uint256 public
eggPerBlock
;
// Bonus muliplier for early
lyptus
makers.
// Bonus muliplier for early
egg
makers.
uint256 public constant BONUS_MULTIPLIER = 1;
uint256 public constant BONUS_MULTIPLIER = 1;
// Deposit Fee address
// Deposit Fee address
address public feeAddress;
address public feeAddress;
// 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
LYPTUS
mining starts.
// The block number when
EGG
mining starts.
uint256 public startBlock;
uint256 public startBlock;
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);
constructor(
constructor(
복사
복사됨
복사
복사됨
LyptusToken _lyptus
,
EggToken _egg
,
address _devaddr,
address _devaddr,
address _feeAddress,
address _feeAddress,
복사
복사됨
복사
복사됨
uint256 _
lyptusPerBlock
,
uint256 _
eggPerBlock
,
uint256 _startBlock
uint256 _startBlock
) public {
) public {
복사
복사됨
복사
복사됨
lyptus
= _
lyptus
;
egg
= _
egg
;
devaddr = _devaddr;
devaddr = _devaddr;
feeAddress = _feeAddress;
feeAddress = _feeAddress;
복사
복사됨
복사
복사됨
lyptusPerBlock
= _
lyptusPerBlock
;
eggPerBlock
= _
eggPerBlock
;
startBlock = _startBlock;
startBlock = _startBlock;
}
}
function poolLength() external view returns (uint256) {
function poolLength() external view returns (uint256) {
return poolInfo.length;
return poolInfo.length;
}
}
// 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, bool _withUpdate) public onlyOwner {
function add(uint256 _allocPoint, IBEP20 _lpToken, uint16 _depositFeeBP, bool _withUpdate) public onlyOwner {
require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points");
require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points");
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
Lyptus
PerShare: 0,
acc
Egg
PerShare: 0,
depositFeeBP: _depositFeeBP
depositFeeBP: _depositFeeBP
}));
}));
}
}
복사
복사됨
복사
복사됨
// Update the given pool's
LYPTUS
allocation point and deposit fee. Can only be called by the owner.
// Update the given pool's
EGG
allocation point and deposit fee. Can only be called by the owner.
function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, bool _withUpdate) public onlyOwner {
function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, bool _withUpdate) public onlyOwner {
require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points");
require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points");
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;
}
}
// 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 view returns (uint256) {
function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) {
return _to.sub(_from).mul(BONUS_MULTIPLIER);
return _to.sub(_from).mul(BONUS_MULTIPLIER);
}
}
복사
복사됨
복사
복사됨
// View function to see pending
LYPTUSs
on frontend.
// View function to see pending
EGGs
on frontend.
function
pendingLyptus
(uint256 _pid, address _user) external view returns (uint256) {
function
pendingEgg
(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
Lyptus
PerShare = pool.acc
Lyptus
PerShare;
uint256 acc
Egg
PerShare = pool.acc
Egg
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
lyptusReward
= multiplier.mul(
lyptusPerBlock
).mul(pool.allocPoint).div(totalAllocPoint);
uint256
eggReward
= multiplier.mul(
eggPerBlock
).mul(pool.allocPoint).div(totalAllocPoint);
acc
Lyptus
PerShare = acc
Lyptus
PerShare.add(
lyptusReward
.mul(1e12).div(lpSupply));
acc
Egg
PerShare = acc
Egg
PerShare.add(
eggReward
.mul(1e12).div(lpSupply));
}
}
복사
복사됨
복사
복사됨
return user.amount.mul(acc
Lyptus
PerShare).div(1e12).sub(user.rewardDebt);
return user.amount.mul(acc
Egg
PerShare).div(1e12).sub(user.rewardDebt);
}
}
// 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
lyptusReward
= multiplier.mul(
lyptusPerBlock
).mul(pool.allocPoint).div(totalAllocPoint);
uint256
eggReward
= multiplier.mul(
eggPerBlock
).mul(pool.allocPoint).div(totalAllocPoint);
lyptus
.mint(devaddr,
lyptusReward
.div(10));
egg
.mint(devaddr,
eggReward
.div(10));
lyptus
.mint(address(this),
lyptusReward
);
egg
.mint(address(this),
eggReward
);
pool.acc
Lyptus
PerShare = pool.acc
Lyptus
PerShare.add(
lyptusReward
.mul(1e12).div(lpSupply));
pool.acc
Egg
PerShare = pool.acc
Egg
PerShare.add(
eggReward
.mul(1e12).div(lpSupply));
pool.lastRewardBlock = block.number;
pool.lastRewardBlock = block.number;
}
}
복사
복사됨
복사
복사됨
// Deposit LP tokens to MasterChef for
LYPTUS
allocation.
// Deposit LP tokens to MasterChef for
EGG
allocation.
function deposit(uint256 _pid, uint256 _amount) public {
function deposit(uint256 _pid, uint256 _amount) public {
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 (user.amount > 0) {
if (user.amount > 0) {
복사
복사됨
복사
복사됨
uint256 pending = user.amount.mul(pool.acc
Lyptus
PerShare).div(1e12).sub(user.rewardDebt);
uint256 pending = user.amount.mul(pool.acc
Egg
PerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
if(pending > 0) {
복사
복사됨
복사
복사됨
safe
Lyptus
Transfer(msg.sender, pending);
safe
Egg
Transfer(msg.sender, pending);
}
}
}
}
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(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
Lyptus
PerShare).div(1e12);
user.rewardDebt = user.amount.mul(pool.acc
Egg
PerShare).div(1e12);
emit Deposit(msg.sender, _pid, _amount);
emit Deposit(msg.sender, _pid, _amount);
}
}
// Withdraw LP tokens from MasterChef.
// Withdraw LP tokens from MasterChef.
function withdraw(uint256 _pid, uint256 _amount) public {
function withdraw(uint256 _pid, uint256 _amount) public {
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);
복사
복사됨
복사
복사됨
uint256 pending = user.amount.mul(pool.acc
Lyptus
PerShare).div(1e12).sub(user.rewardDebt);
uint256 pending = user.amount.mul(pool.acc
Egg
PerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
if(pending > 0) {
복사
복사됨
복사
복사됨
safe
Lyptus
Transfer(msg.sender, pending);
safe
Egg
Transfer(msg.sender, pending);
}
}
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
Lyptus
PerShare).div(1e12);
user.rewardDebt = user.amount.mul(pool.acc
Egg
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 {
function emergencyWithdraw(uint256 _pid) public {
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.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);
}
}
복사
복사됨
복사
복사됨
// Safe
lyptus
transfer function, just in case if rounding error causes pool to not have enough
LYPTUSs
.
// Safe
egg
transfer function, just in case if rounding error causes pool to not have enough
EGGs
.
function safe
Lyptus
Transfer(address _to, uint256 _amount) internal {
function safe
Egg
Transfer(address _to, uint256 _amount) internal {
uint256
lyptusBal
=
lyptus
.balanceOf(address(this));
uint256
eggBal
=
egg
.balanceOf(address(this));
if (_amount >
lyptusBal
) {
if (_amount >
eggBal
) {
lyptus
.transfer(_to,
lyptusBal
);
egg
.transfer(_to,
eggBal
);
} else {
} else {
복사
복사됨
복사
복사됨
lyptus
.transfer(_to, _amount);
egg
.transfer(_to, _amount);
}
}
}
}
// Update dev address by the previous dev.
// Update dev address by the previous dev.
function dev(address _devaddr) public {
function dev(address _devaddr) public {
require(msg.sender == devaddr, "dev: wut?");
require(msg.sender == devaddr, "dev: wut?");
devaddr = _devaddr;
devaddr = _devaddr;
}
}
function setFeeAddress(address _feeAddress) public{
function setFeeAddress(address _feeAddress) public{
require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN");
require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN");
feeAddress = _feeAddress;
feeAddress = _feeAddress;
}
}
//Pancake has to add hidden dummy pools inorder to alter the emission, here we make it simple and transparent to all.
//Pancake has to add hidden dummy pools inorder to alter the emission, here we make it simple and transparent to all.
복사
복사됨
복사
복사됨
function updateEmissionRate(uint256 _
lyptusPerBlock
) public onlyOwner {
function updateEmissionRate(uint256 _
eggPerBlock
) public onlyOwner {
massUpdatePools();
massUpdatePools();
복사
복사됨
복사
복사됨
lyptusPerBlock
= _
lyptusPerBlock
;
eggPerBlock
= _
eggPerBlock
;
}
}
}
}
저장된 비교 결과
원본
파일 열기
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; // .----------------. .----------------. .----------------. .----------------. .----------------. // | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. | // | | ___ ____ | || | ____ | || | __ | || | _____ | || | __ | | // | | |_ ||_ _| | || | .' `. | || | / \ | || | |_ _| | || | / \ | | // | | | |_/ / | || | / .--. \ | || | / /\ \ | || | | | | || | / /\ \ | | // | | | __'. | || | | | | | | || | / ____ \ | || | | | _ | || | / ____ \ | | // | | _| | \ \_ | || | \ `--' / | || | _/ / \ \_ | || | _| |__/ | | || | _/ / \ \_ | | // | | |____||____| | || | `.____.' | || ||____| |____|| || | |________| | || ||____| |____|| | // | | | || | | || | | || | | || | | | // | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' | // '----------------' '----------------' '----------------' '----------------' '----------------' import "./SafeMath.sol"; import "./IBEP20.sol"; import "./SafeBEP20.sol"; import "./Ownable.sol"; import "./LYPTUSToken.sol"; // MasterChef is the master of Lyptus. He can make Lyptus and he is a fair guy. // // Note that it's ownable and the owner wields tremendous power. The ownership // will be transferred to a governance smart contract once LYPTUS is sufficiently // distributed and the community can show to govern itself. // // Have fun reading it. Hopefully it's bug-free. God bless. contract MasterChef is Ownable { 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. // // We do some fancy math here. Basically, any point in time, the amount of LYPTUSs // entitled to a user but is pending to be distributed is: // // pending reward = (user.amount * pool.accLyptusPerShare) - user.rewardDebt // // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens: // 1. The pool's `accLyptusPerShare` (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. LYPTUSs to distribute per block. uint256 lastRewardBlock; // Last block number that LYPTUSs distribution occurs. uint256 accLyptusPerShare; // Accumulated LYPTUSs per share, times 1e12. See below. uint16 depositFeeBP; // Deposit fee in basis points } // The LYPTUS TOKEN! LyptusToken public lyptus; // Dev address. address public devaddr; // LYPTUS tokens created per block. uint256 public lyptusPerBlock; // Bonus muliplier for early lyptus makers. uint256 public constant BONUS_MULTIPLIER = 1; // Deposit Fee address address public feeAddress; // 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 LYPTUS mining starts. uint256 public startBlock; 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); constructor( LyptusToken _lyptus, address _devaddr, address _feeAddress, uint256 _lyptusPerBlock, uint256 _startBlock ) public { lyptus = _lyptus; devaddr = _devaddr; feeAddress = _feeAddress; lyptusPerBlock = _lyptusPerBlock; startBlock = _startBlock; } 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, bool _withUpdate) public onlyOwner { require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points"); if (_withUpdate) { massUpdatePools(); } uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock; totalAllocPoint = totalAllocPoint.add(_allocPoint); poolInfo.push(PoolInfo({ lpToken: _lpToken, allocPoint: _allocPoint, lastRewardBlock: lastRewardBlock, accLyptusPerShare: 0, depositFeeBP: _depositFeeBP })); } // Update the given pool's LYPTUS allocation point and deposit fee. Can only be called by the owner. function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, bool _withUpdate) public onlyOwner { require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points"); if (_withUpdate) { massUpdatePools(); } totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint); poolInfo[_pid].allocPoint = _allocPoint; poolInfo[_pid].depositFeeBP = _depositFeeBP; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) { return _to.sub(_from).mul(BONUS_MULTIPLIER); } // View function to see pending LYPTUSs on frontend. function pendingLyptus(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accLyptusPerShare = pool.accLyptusPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.number > pool.lastRewardBlock && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 lyptusReward = multiplier.mul(lyptusPerBlock).mul(pool.allocPoint).div(totalAllocPoint); accLyptusPerShare = accLyptusPerShare.add(lyptusReward.mul(1e12).div(lpSupply)); } return user.amount.mul(accLyptusPerShare).div(1e12).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.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 lyptusReward = multiplier.mul(lyptusPerBlock).mul(pool.allocPoint).div(totalAllocPoint); lyptus.mint(devaddr, lyptusReward.div(10)); lyptus.mint(address(this), lyptusReward); pool.accLyptusPerShare = pool.accLyptusPerShare.add(lyptusReward.mul(1e12).div(lpSupply)); pool.lastRewardBlock = block.number; } // Deposit LP tokens to MasterChef for LYPTUS allocation. function deposit(uint256 _pid, uint256 _amount) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); if (user.amount > 0) { uint256 pending = user.amount.mul(pool.accLyptusPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { safeLyptusTransfer(msg.sender, pending); } } 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.accLyptusPerShare).div(1e12); emit Deposit(msg.sender, _pid, _amount); } // Withdraw LP tokens from MasterChef. function withdraw(uint256 _pid, uint256 _amount) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); uint256 pending = user.amount.mul(pool.accLyptusPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { safeLyptusTransfer(msg.sender, pending); } if(_amount > 0) { user.amount = user.amount.sub(_amount); pool.lpToken.safeTransfer(address(msg.sender), _amount); } user.rewardDebt = user.amount.mul(pool.accLyptusPerShare).div(1e12); emit Withdraw(msg.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.lpToken.safeTransfer(address(msg.sender), amount); emit EmergencyWithdraw(msg.sender, _pid, amount); } // Safe lyptus transfer function, just in case if rounding error causes pool to not have enough LYPTUSs. function safeLyptusTransfer(address _to, uint256 _amount) internal { uint256 lyptusBal = lyptus.balanceOf(address(this)); if (_amount > lyptusBal) { lyptus.transfer(_to, lyptusBal); } else { lyptus.transfer(_to, _amount); } } // Update dev address by the previous dev. function dev(address _devaddr) public { require(msg.sender == devaddr, "dev: wut?"); devaddr = _devaddr; } function setFeeAddress(address _feeAddress) public{ require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN"); feeAddress = _feeAddress; } //Pancake has to add hidden dummy pools inorder to alter the emission, here we make it simple and transparent to all. function updateEmissionRate(uint256 _lyptusPerBlock) public onlyOwner { massUpdatePools(); lyptusPerBlock = _lyptusPerBlock; } }
수정본
파일 열기
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "@openzeppelin/contracts/math/SafeMath.sol"; import "./libs/IBEP20.sol"; import "./libs/SafeBEP20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./EggToken.sol"; // MasterChef is the master of Egg. He can make Egg and he is a fair guy. // // Note that it's ownable and the owner wields tremendous power. The ownership // will be transferred to a governance smart contract once EGG is sufficiently // distributed and the community can show to govern itself. // // Have fun reading it. Hopefully it's bug-free. God bless. contract MasterChef is Ownable { 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. // // We do some fancy math here. Basically, any point in time, the amount of EGGs // entitled to a user but is pending to be distributed is: // // pending reward = (user.amount * pool.accEggPerShare) - user.rewardDebt // // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens: // 1. The pool's `accEggPerShare` (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. EGGs to distribute per block. uint256 lastRewardBlock; // Last block number that EGGs distribution occurs. uint256 accEggPerShare; // Accumulated EGGs per share, times 1e12. See below. uint16 depositFeeBP; // Deposit fee in basis points } // The EGG TOKEN! EggToken public egg; // Dev address. address public devaddr; // EGG tokens created per block. uint256 public eggPerBlock; // Bonus muliplier for early egg makers. uint256 public constant BONUS_MULTIPLIER = 1; // Deposit Fee address address public feeAddress; // 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 EGG mining starts. uint256 public startBlock; 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); constructor( EggToken _egg, address _devaddr, address _feeAddress, uint256 _eggPerBlock, uint256 _startBlock ) public { egg = _egg; devaddr = _devaddr; feeAddress = _feeAddress; eggPerBlock = _eggPerBlock; startBlock = _startBlock; } 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, bool _withUpdate) public onlyOwner { require(_depositFeeBP <= 10000, "add: invalid deposit fee basis points"); if (_withUpdate) { massUpdatePools(); } uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock; totalAllocPoint = totalAllocPoint.add(_allocPoint); poolInfo.push(PoolInfo({ lpToken: _lpToken, allocPoint: _allocPoint, lastRewardBlock: lastRewardBlock, accEggPerShare: 0, depositFeeBP: _depositFeeBP })); } // Update the given pool's EGG allocation point and deposit fee. Can only be called by the owner. function set(uint256 _pid, uint256 _allocPoint, uint16 _depositFeeBP, bool _withUpdate) public onlyOwner { require(_depositFeeBP <= 10000, "set: invalid deposit fee basis points"); if (_withUpdate) { massUpdatePools(); } totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint); poolInfo[_pid].allocPoint = _allocPoint; poolInfo[_pid].depositFeeBP = _depositFeeBP; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) { return _to.sub(_from).mul(BONUS_MULTIPLIER); } // View function to see pending EGGs on frontend. function pendingEgg(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accEggPerShare = pool.accEggPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.number > pool.lastRewardBlock && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number); uint256 eggReward = multiplier.mul(eggPerBlock).mul(pool.allocPoint).div(totalAllocPoint); accEggPerShare = accEggPerShare.add(eggReward.mul(1e12).div(lpSupply)); } return user.amount.mul(accEggPerShare).div(1e12).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.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 eggReward = multiplier.mul(eggPerBlock).mul(pool.allocPoint).div(totalAllocPoint); egg.mint(devaddr, eggReward.div(10)); egg.mint(address(this), eggReward); pool.accEggPerShare = pool.accEggPerShare.add(eggReward.mul(1e12).div(lpSupply)); pool.lastRewardBlock = block.number; } // Deposit LP tokens to MasterChef for EGG allocation. function deposit(uint256 _pid, uint256 _amount) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); if (user.amount > 0) { uint256 pending = user.amount.mul(pool.accEggPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { safeEggTransfer(msg.sender, pending); } } 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.accEggPerShare).div(1e12); emit Deposit(msg.sender, _pid, _amount); } // Withdraw LP tokens from MasterChef. function withdraw(uint256 _pid, uint256 _amount) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); uint256 pending = user.amount.mul(pool.accEggPerShare).div(1e12).sub(user.rewardDebt); if(pending > 0) { safeEggTransfer(msg.sender, pending); } if(_amount > 0) { user.amount = user.amount.sub(_amount); pool.lpToken.safeTransfer(address(msg.sender), _amount); } user.rewardDebt = user.amount.mul(pool.accEggPerShare).div(1e12); emit Withdraw(msg.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.lpToken.safeTransfer(address(msg.sender), amount); emit EmergencyWithdraw(msg.sender, _pid, amount); } // Safe egg transfer function, just in case if rounding error causes pool to not have enough EGGs. function safeEggTransfer(address _to, uint256 _amount) internal { uint256 eggBal = egg.balanceOf(address(this)); if (_amount > eggBal) { egg.transfer(_to, eggBal); } else { egg.transfer(_to, _amount); } } // Update dev address by the previous dev. function dev(address _devaddr) public { require(msg.sender == devaddr, "dev: wut?"); devaddr = _devaddr; } function setFeeAddress(address _feeAddress) public{ require(msg.sender == feeAddress, "setFeeAddress: FORBIDDEN"); feeAddress = _feeAddress; } //Pancake has to add hidden dummy pools inorder to alter the emission, here we make it simple and transparent to all. function updateEmissionRate(uint256 _eggPerBlock) public onlyOwner { massUpdatePools(); eggPerBlock = _eggPerBlock; } }
비교하기