Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
실시간 편집
공백 변경 숨기기
변경 없는 행 숨기기
줄바꿈 비활성화
레이아웃
나란히 보기
합쳐 보기
비교 단위
스마트
단어
글자
텍스트 스타일
모양 변경
구문 강조
언어 선택
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
BunnyMinterV2.sol
생성일
5년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
88 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
313 행
복사
24 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
251 행
복사
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
pragma solidity ^0.6.12;
/*
/*
___ _ _
___ _ _
| _ )_ _ _ _ _ _ _ _ | | | |
| _ )_ _ _ _ _ _ _ _ | | | |
| _ \ || | ' \| ' \ || | |_| |_|
| _ \ || | ' \| ' \ || | |_| |_|
|___/\_,_|_||_|_||_\_, | (_) (_)
|___/\_,_|_||_|_||_\_, | (_) (_)
|__/
|__/
*
*
* MIT License
* MIT License
* ===========
* ===========
*
*
* Copyright (c) 2020 BunnyFinance
* Copyright (c) 2020 BunnyFinance
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/
*/
import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/BEP20.sol";
import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/BEP20.sol";
import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol";
import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol";
import "@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol";
import "@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol";
import "../interfaces/IBunnyMinterV2.sol";
import "../interfaces/IBunnyMinterV2.sol";
import "../interfaces/IStakingRewards.sol";
import "../interfaces/IStakingRewards.sol";
복사
복사됨
복사
복사됨
import "../
dashboard/calculator/
PriceCalculator
BSC
.sol";
import "../
interfaces/I
PriceCalculator
.sol";
import "../zap/ZapBSC.sol";
import "../zap/ZapBSC.sol";
복사
복사됨
복사
복사됨
import "../library/SafeToken.sol";
contract BunnyMinterV2 is IBunnyMinterV2, OwnableUpgradeable {
contract BunnyMinterV2 is IBunnyMinterV2, OwnableUpgradeable {
using SafeMath for uint;
using SafeMath for uint;
using SafeBEP20 for IBEP20;
using SafeBEP20 for IBEP20;
/* ========== CONSTANTS ============= */
/* ========== CONSTANTS ============= */
address public constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
address public constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
address public constant BUNNY = 0xC9849E6fdB743d08fAeE3E34dd2D1bc69EA11a51;
address public constant BUNNY = 0xC9849E6fdB743d08fAeE3E34dd2D1bc69EA11a51;
복사
복사됨
복사
복사됨
address public constant BUNNY_BNB = 0x7Bb89460599Dbf32ee3Aa50798BBcEae2A5F7f6a;
address public constant BUNNY_POOL = 0xCADc8CB26c8C7cB46500E61171b5F27e9bd7889D;
address public constant BUNNY_POOL = 0xCADc8CB26c8C7cB46500E61171b5F27e9bd7889D;
복사
복사됨
복사
복사됨
address public constant
DEPLOYER
=
0xe87f02606911223C2Cf200398FFAF353f60801F7
;
address public constant
TREASURY
=
0x0989091F27708Bc92ea4cA60073e03592B94C0eE
;
address private constant TIMELOCK = 0x85c9162A51E03078bdCd08D4232Bab13ed414cC3;
address private constant TIMELOCK = 0x85c9162A51E03078bdCd08D4232Bab13ed414cC3;
address private constant DEAD = 0x000000000000000000000000000000000000dEaD;
address private constant DEAD = 0x000000000000000000000000000000000000dEaD;
uint public constant FEE_MAX = 10000;
uint public constant FEE_MAX = 10000;
복사
복사됨
복사
복사됨
ZapBSC public constant zapBSC = ZapBSC(0xCBEC8e7AB969F6Eb873Df63d04b4eAFC353574b1);
I
PriceCalculator
public constant priceCalculator =
I
PriceCalculator
(0xF5BF8A9249e3cc4cB684E3f23db9669323d4FB7d);
ZapBSC public constant zapBSCV2 = ZapBSC(0xdC2bBB0D33E0e7Dea9F5b98F46EDBaC823586a0C);
PriceCalculator
BSC
public constant priceCalculator =
PriceCalculator
BSC(0x542c06a5dc3f27e0fbDc9FB7BC6748f26d54dDb0); // should be V1 address
IPancakeRouter02 private constant routerV1 = IPancakeRouter02(0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F);
IPancakeRouter02 private constant routerV2 = IPancakeRouter02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
/* ========== STATE VARIABLES ========== */
/* ========== STATE VARIABLES ========== */
address public bunnyChef;
address public bunnyChef;
mapping(address => bool) private _minters;
mapping(address => bool) private _minters;
address public _deprecated_helper; // deprecated
address public _deprecated_helper; // deprecated
uint public PERFORMANCE_FEE;
uint public PERFORMANCE_FEE;
uint public override WITHDRAWAL_FEE_FREE_PERIOD;
uint public override WITHDRAWAL_FEE_FREE_PERIOD;
uint public override WITHDRAWAL_FEE;
uint public override WITHDRAWAL_FEE;
uint public override bunnyPerProfitBNB;
uint public override bunnyPerProfitBNB;
uint public bunnyPerBunnyBNBFlip; // will be deprecated
uint public bunnyPerBunnyBNBFlip; // will be deprecated
/* ========== MODIFIERS ========== */
/* ========== MODIFIERS ========== */
modifier onlyMinter {
modifier onlyMinter {
require(isMinter(msg.sender) == true, "BunnyMinterV2: caller is not the minter");
require(isMinter(msg.sender) == true, "BunnyMinterV2: caller is not the minter");
_;
_;
}
}
modifier onlyBunnyChef {
modifier onlyBunnyChef {
require(msg.sender == bunnyChef, "BunnyMinterV2: caller not the bunny chef");
require(msg.sender == bunnyChef, "BunnyMinterV2: caller not the bunny chef");
_;
_;
}
}
receive() external payable {}
receive() external payable {}
/* ========== INITIALIZER ========== */
/* ========== INITIALIZER ========== */
function initialize() external initializer {
function initialize() external initializer {
WITHDRAWAL_FEE_FREE_PERIOD = 3 days;
WITHDRAWAL_FEE_FREE_PERIOD = 3 days;
WITHDRAWAL_FEE = 50;
WITHDRAWAL_FEE = 50;
PERFORMANCE_FEE = 3000;
PERFORMANCE_FEE = 3000;
bunnyPerProfitBNB = 5e18;
bunnyPerProfitBNB = 5e18;
bunnyPerBunnyBNBFlip = 6e18;
bunnyPerBunnyBNBFlip = 6e18;
IBEP20(BUNNY).approve(BUNNY_POOL, uint(- 1));
IBEP20(BUNNY).approve(BUNNY_POOL, uint(- 1));
}
}
/* ========== RESTRICTED FUNCTIONS ========== */
/* ========== RESTRICTED FUNCTIONS ========== */
function transferBunnyOwner(address _owner) external onlyOwner {
function transferBunnyOwner(address _owner) external onlyOwner {
Ownable(BUNNY).transferOwnership(_owner);
Ownable(BUNNY).transferOwnership(_owner);
}
}
function setWithdrawalFee(uint _fee) external onlyOwner {
function setWithdrawalFee(uint _fee) external onlyOwner {
require(_fee < 500, "wrong fee");
require(_fee < 500, "wrong fee");
// less 5%
// less 5%
WITHDRAWAL_FEE = _fee;
WITHDRAWAL_FEE = _fee;
}
}
function setPerformanceFee(uint _fee) external onlyOwner {
function setPerformanceFee(uint _fee) external onlyOwner {
require(_fee < 5000, "wrong fee");
require(_fee < 5000, "wrong fee");
PERFORMANCE_FEE = _fee;
PERFORMANCE_FEE = _fee;
}
}
function setWithdrawalFeeFreePeriod(uint _period) external onlyOwner {
function setWithdrawalFeeFreePeriod(uint _period) external onlyOwner {
WITHDRAWAL_FEE_FREE_PERIOD = _period;
WITHDRAWAL_FEE_FREE_PERIOD = _period;
}
}
function setMinter(address minter, bool canMint) external override onlyOwner {
function setMinter(address minter, bool canMint) external override onlyOwner {
if (canMint) {
if (canMint) {
_minters[minter] = canMint;
_minters[minter] = canMint;
} else {
} else {
delete _minters[minter];
delete _minters[minter];
}
}
}
}
function setBunnyPerProfitBNB(uint _ratio) external onlyOwner {
function setBunnyPerProfitBNB(uint _ratio) external onlyOwner {
bunnyPerProfitBNB = _ratio;
bunnyPerProfitBNB = _ratio;
}
}
function setBunnyPerBunnyBNBFlip(uint _bunnyPerBunnyBNBFlip) external onlyOwner {
function setBunnyPerBunnyBNBFlip(uint _bunnyPerBunnyBNBFlip) external onlyOwner {
bunnyPerBunnyBNBFlip = _bunnyPerBunnyBNBFlip;
bunnyPerBunnyBNBFlip = _bunnyPerBunnyBNBFlip;
}
}
function setBunnyChef(address _bunnyChef) external onlyOwner {
function setBunnyChef(address _bunnyChef) external onlyOwner {
require(bunnyChef == address(0), "BunnyMinterV2: setBunnyChef only once");
require(bunnyChef == address(0), "BunnyMinterV2: setBunnyChef only once");
bunnyChef = _bunnyChef;
bunnyChef = _bunnyChef;
}
}
/* ========== VIEWS ========== */
/* ========== VIEWS ========== */
function isMinter(address account) public view override returns (bool) {
function isMinter(address account) public view override returns (bool) {
if (IBEP20(BUNNY).getOwner() != address(this)) {
if (IBEP20(BUNNY).getOwner() != address(this)) {
return false;
return false;
}
}
return _minters[account];
return _minters[account];
}
}
function amountBunnyToMint(uint bnbProfit) public view override returns (uint) {
function amountBunnyToMint(uint bnbProfit) public view override returns (uint) {
return bnbProfit.mul(bunnyPerProfitBNB).div(1e18);
return bnbProfit.mul(bunnyPerProfitBNB).div(1e18);
}
}
function amountBunnyToMintForBunnyBNB(uint amount, uint duration) public view override returns (uint) {
function amountBunnyToMintForBunnyBNB(uint amount, uint duration) public view override returns (uint) {
return amount.mul(bunnyPerBunnyBNBFlip).mul(duration).div(365 days).div(1e18);
return amount.mul(bunnyPerBunnyBNBFlip).mul(duration).div(365 days).div(1e18);
}
}
function withdrawalFee(uint amount, uint depositedAt) external view override returns (uint) {
function withdrawalFee(uint amount, uint depositedAt) external view override returns (uint) {
if (depositedAt.add(WITHDRAWAL_FEE_FREE_PERIOD) > block.timestamp) {
if (depositedAt.add(WITHDRAWAL_FEE_FREE_PERIOD) > block.timestamp) {
return amount.mul(WITHDRAWAL_FEE).div(FEE_MAX);
return amount.mul(WITHDRAWAL_FEE).div(FEE_MAX);
}
}
return 0;
return 0;
}
}
function performanceFee(uint profit) public view override returns (uint) {
function performanceFee(uint profit) public view override returns (uint) {
return profit.mul(PERFORMANCE_FEE).div(FEE_MAX);
return profit.mul(PERFORMANCE_FEE).div(FEE_MAX);
}
}
/* ========== V1 FUNCTIONS ========== */
/* ========== V1 FUNCTIONS ========== */
복사
복사됨
복사
복사됨
function mintFor(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint)
external
payable override onlyMinter {
function mintFor(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint)
public
payable override onlyMinter {
uint feeSum = _performanceFee.add(_withdrawalFee);
uint feeSum = _performanceFee.add(_withdrawalFee);
_transferAsset(asset, feeSum);
_transferAsset(asset, feeSum);
if (asset == BUNNY) {
if (asset == BUNNY) {
IBEP20(BUNNY).safeTransfer(DEAD, feeSum);
IBEP20(BUNNY).safeTransfer(DEAD, feeSum);
return;
return;
}
}
복사
복사됨
복사
복사됨
uint bunnyBNBAmount = _zapAssetsToBunnyBNB(asset
, feeSum
, false
);
if (asset == address(0)) { // means BNB
if (bunnyBNBAmount == 0) return;
SafeToken.safeTransferETH(TREASURY
, feeSum
);
} else {
IBEP20(
BUNNY_BNB
).safeTransfer(
BUNNY_POOL, bunnyBNBAmount
);
IBEP20(
asset
).safeTransfer(
TREASURY, feeSum
);
IStakingRewards(BUNNY_POOL).notifyRewardAmount(bunnyBNBAmount);
}
복사
복사됨
복사
복사됨
(uint
valueInBNB,
) = priceCalculator.valueOfAsset(
BUNNY_BNB, bunnyBNBAmount);
(uint
contribution,
) = priceCalculator.valueOfAsset(
asset,
_performanceFee)
;
uint contribution = valueInBNB.mul(
_performanceFee)
.div(feeSum)
;
uint mintBunny = amountBunnyToMint(contribution);
uint mintBunny = amountBunnyToMint(contribution);
if (mintBunny == 0) return;
if (mintBunny == 0) return;
_mint(mintBunny, to);
_mint(mintBunny, to);
}
}
/* ========== PancakeSwap V2 FUNCTIONS ========== */
/* ========== PancakeSwap V2 FUNCTIONS ========== */
복사
복사됨
복사
복사됨
function mintForV2(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint
) external payable override onlyMinter {
function mintForV2(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint
timestamp
) external payable override onlyMinter {
uint feeSum = _performanceFee.add(
_withdrawalFee
);
mintFor(asset,
_withdrawalFee
, _performanceFee, to, timestamp
);
_transferAsset(asset, feeSum);
if (asset == BUNNY) {
IBEP20(BUNNY).safeTransfer(DEAD, feeSum);
return;
}
uint bunnyBNBAmount = _zapAssetsToBunnyBNB(asset, feeSum, true);
if (bunnyBNBAmount == 0) return;
IBEP20(BUNNY_BNB).safeTransfer(BUNNY_POOL, bunnyBNBAmount);
IStakingRewards(BUNNY_POOL).notifyRewardAmount(bunnyBNBAmount);
(uint valueInBNB,) = priceCalculator.valueOfAsset(BUNNY_BNB, bunnyBNBAmount);
uint contribution = valueInBNB.mul(_performanceFee).div(feeSum);
uint mintBunny = amountBunnyToMint(contribution);
if (mintBunny == 0) return;
_mint(mintBunny, to
);
}
}
/* ========== BunnyChef FUNCTIONS ========== */
/* ========== BunnyChef FUNCTIONS ========== */
function mint(uint amount) external override onlyBunnyChef {
function mint(uint amount) external override onlyBunnyChef {
if (amount == 0) return;
if (amount == 0) return;
_mint(amount, address(this));
_mint(amount, address(this));
}
}
function safeBunnyTransfer(address _to, uint _amount) external override onlyBunnyChef {
function safeBunnyTransfer(address _to, uint _amount) external override onlyBunnyChef {
if (_amount == 0) return;
if (_amount == 0) return;
uint bal = IBEP20(BUNNY).balanceOf(address(this));
uint bal = IBEP20(BUNNY).balanceOf(address(this));
if (_amount <= bal) {
if (_amount <= bal) {
IBEP20(BUNNY).safeTransfer(_to, _amount);
IBEP20(BUNNY).safeTransfer(_to, _amount);
} else {
} else {
IBEP20(BUNNY).safeTransfer(_to, bal);
IBEP20(BUNNY).safeTransfer(_to, bal);
}
}
}
}
// @dev should be called when determining mint in governance. Bunny is transferred to the timelock contract.
// @dev should be called when determining mint in governance. Bunny is transferred to the timelock contract.
function mintGov(uint amount) external override onlyOwner {
function mintGov(uint amount) external override onlyOwner {
if (amount == 0) return;
if (amount == 0) return;
_mint(amount, TIMELOCK);
_mint(amount, TIMELOCK);
}
}
/* ========== PRIVATE FUNCTIONS ========== */
/* ========== PRIVATE FUNCTIONS ========== */
function _transferAsset(address asset, uint amount) private {
function _transferAsset(address asset, uint amount) private {
if (asset == address(0)) {
if (asset == address(0)) {
// case) transferred BNB
// case) transferred BNB
require(msg.value >= amount);
require(msg.value >= amount);
} else {
} else {
IBEP20(asset).safeTransferFrom(msg.sender, address(this), amount);
IBEP20(asset).safeTransferFrom(msg.sender, address(this), amount);
}
}
}
}
복사
복사됨
복사
복사됨
function _zapAssetsToBunnyBNB(address asset, uint amount, bool fromV2) private returns (uint bunnyBNBAmount) {
uint _initBunnyBNBAmount = IBEP20(BUNNY_BNB).balanceOf(address(this));
if (asset == address(0)) {
zapBSC.zapIn{ value : amount }(BUNNY_BNB);
}
else if (keccak256(abi.encodePacked(IPancakePair(asset).symbol())) == keccak256("Cake-LP")) {
IPancakeRouter02 router = fromV2 ? routerV2 : routerV1;
if (IBEP20(asset).allowance(address(this), address(router)) == 0) {
IBEP20(asset).safeApprove(address(router), uint(- 1));
}
IPancakePair pair = IPancakePair(asset);
address token0 = pair.token0();
address token1 = pair.token1();
(uint amountToken0, uint amountToken1) = router.removeLiquidity(token0, token1, amount, 0, 0, address(this), block.timestamp);
if (IBEP20(token0).allowance(address(this), address(zapBSC)) == 0) {
IBEP20(token0).safeApprove(address(zapBSC), uint(- 1));
}
if (IBEP20(token1).allowance(address(this), address(zapBSC)) == 0) {
IBEP20(token1).safeApprove(address(zapBSC), uint(- 1));
}
zapBSC.zapInToken(token0, amountToken0, BUNNY_BNB);
zapBSC.zapInToken(token1, amountToken1, BUNNY_BNB);
}
else {
if (IBEP20(asset).allowance(address(this), address(zapBSC)) == 0) {
IBEP20(asset).safeApprove(address(zapBSC), uint(- 1));
}
zapBSC.zapInToken(asset, amount, BUNNY_BNB);
}
bunnyBNBAmount = IBEP20(BUNNY_BNB).balanceOf(address(this)).sub(_initBunnyBNBAmount);
}
function _mint(uint amount, address to) private {
function _mint(uint amount, address to) private {
BEP20 tokenBUNNY = BEP20(BUNNY);
BEP20 tokenBUNNY = BEP20(BUNNY);
tokenBUNNY.mint(amount);
tokenBUNNY.mint(amount);
if (to != address(this)) {
if (to != address(this)) {
tokenBUNNY.transfer(to, amount);
tokenBUNNY.transfer(to, amount);
}
}
uint bunnyForDev = amount.mul(15).div(100);
uint bunnyForDev = amount.mul(15).div(100);
tokenBUNNY.mint(bunnyForDev);
tokenBUNNY.mint(bunnyForDev);
복사
복사됨
복사
복사됨
IStakingRewards(BUNNY_POOL).stakeTo(
bunnyForDev
, DEPLOYER
);
tokenBUNNY.transfer(TREASURY,
bunnyForDev
);
}
}
}
}
복사
복사됨
복사
복사됨
저장된 비교 결과
원본
파일 열기
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; /* ___ _ _ | _ )_ _ _ _ _ _ _ _ | | | | | _ \ || | ' \| ' \ || | |_| |_| |___/\_,_|_||_|_||_\_, | (_) (_) |__/ * * MIT License * =========== * * Copyright (c) 2020 BunnyFinance * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/BEP20.sol"; import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol"; import "@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol"; import "../interfaces/IBunnyMinterV2.sol"; import "../interfaces/IStakingRewards.sol"; import "../dashboard/calculator/PriceCalculatorBSC.sol"; import "../zap/ZapBSC.sol"; contract BunnyMinterV2 is IBunnyMinterV2, OwnableUpgradeable { using SafeMath for uint; using SafeBEP20 for IBEP20; /* ========== CONSTANTS ============= */ address public constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c; address public constant BUNNY = 0xC9849E6fdB743d08fAeE3E34dd2D1bc69EA11a51; address public constant BUNNY_BNB = 0x7Bb89460599Dbf32ee3Aa50798BBcEae2A5F7f6a; address public constant BUNNY_POOL = 0xCADc8CB26c8C7cB46500E61171b5F27e9bd7889D; address public constant DEPLOYER = 0xe87f02606911223C2Cf200398FFAF353f60801F7; address private constant TIMELOCK = 0x85c9162A51E03078bdCd08D4232Bab13ed414cC3; address private constant DEAD = 0x000000000000000000000000000000000000dEaD; uint public constant FEE_MAX = 10000; ZapBSC public constant zapBSC = ZapBSC(0xCBEC8e7AB969F6Eb873Df63d04b4eAFC353574b1); ZapBSC public constant zapBSCV2 = ZapBSC(0xdC2bBB0D33E0e7Dea9F5b98F46EDBaC823586a0C); PriceCalculatorBSC public constant priceCalculator = PriceCalculatorBSC(0x542c06a5dc3f27e0fbDc9FB7BC6748f26d54dDb0); // should be V1 address IPancakeRouter02 private constant routerV1 = IPancakeRouter02(0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F); IPancakeRouter02 private constant routerV2 = IPancakeRouter02(0x10ED43C718714eb63d5aA57B78B54704E256024E); /* ========== STATE VARIABLES ========== */ address public bunnyChef; mapping(address => bool) private _minters; address public _deprecated_helper; // deprecated uint public PERFORMANCE_FEE; uint public override WITHDRAWAL_FEE_FREE_PERIOD; uint public override WITHDRAWAL_FEE; uint public override bunnyPerProfitBNB; uint public bunnyPerBunnyBNBFlip; // will be deprecated /* ========== MODIFIERS ========== */ modifier onlyMinter { require(isMinter(msg.sender) == true, "BunnyMinterV2: caller is not the minter"); _; } modifier onlyBunnyChef { require(msg.sender == bunnyChef, "BunnyMinterV2: caller not the bunny chef"); _; } receive() external payable {} /* ========== INITIALIZER ========== */ function initialize() external initializer { WITHDRAWAL_FEE_FREE_PERIOD = 3 days; WITHDRAWAL_FEE = 50; PERFORMANCE_FEE = 3000; bunnyPerProfitBNB = 5e18; bunnyPerBunnyBNBFlip = 6e18; IBEP20(BUNNY).approve(BUNNY_POOL, uint(- 1)); } /* ========== RESTRICTED FUNCTIONS ========== */ function transferBunnyOwner(address _owner) external onlyOwner { Ownable(BUNNY).transferOwnership(_owner); } function setWithdrawalFee(uint _fee) external onlyOwner { require(_fee < 500, "wrong fee"); // less 5% WITHDRAWAL_FEE = _fee; } function setPerformanceFee(uint _fee) external onlyOwner { require(_fee < 5000, "wrong fee"); PERFORMANCE_FEE = _fee; } function setWithdrawalFeeFreePeriod(uint _period) external onlyOwner { WITHDRAWAL_FEE_FREE_PERIOD = _period; } function setMinter(address minter, bool canMint) external override onlyOwner { if (canMint) { _minters[minter] = canMint; } else { delete _minters[minter]; } } function setBunnyPerProfitBNB(uint _ratio) external onlyOwner { bunnyPerProfitBNB = _ratio; } function setBunnyPerBunnyBNBFlip(uint _bunnyPerBunnyBNBFlip) external onlyOwner { bunnyPerBunnyBNBFlip = _bunnyPerBunnyBNBFlip; } function setBunnyChef(address _bunnyChef) external onlyOwner { require(bunnyChef == address(0), "BunnyMinterV2: setBunnyChef only once"); bunnyChef = _bunnyChef; } /* ========== VIEWS ========== */ function isMinter(address account) public view override returns (bool) { if (IBEP20(BUNNY).getOwner() != address(this)) { return false; } return _minters[account]; } function amountBunnyToMint(uint bnbProfit) public view override returns (uint) { return bnbProfit.mul(bunnyPerProfitBNB).div(1e18); } function amountBunnyToMintForBunnyBNB(uint amount, uint duration) public view override returns (uint) { return amount.mul(bunnyPerBunnyBNBFlip).mul(duration).div(365 days).div(1e18); } function withdrawalFee(uint amount, uint depositedAt) external view override returns (uint) { if (depositedAt.add(WITHDRAWAL_FEE_FREE_PERIOD) > block.timestamp) { return amount.mul(WITHDRAWAL_FEE).div(FEE_MAX); } return 0; } function performanceFee(uint profit) public view override returns (uint) { return profit.mul(PERFORMANCE_FEE).div(FEE_MAX); } /* ========== V1 FUNCTIONS ========== */ function mintFor(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint) external payable override onlyMinter { uint feeSum = _performanceFee.add(_withdrawalFee); _transferAsset(asset, feeSum); if (asset == BUNNY) { IBEP20(BUNNY).safeTransfer(DEAD, feeSum); return; } uint bunnyBNBAmount = _zapAssetsToBunnyBNB(asset, feeSum, false); if (bunnyBNBAmount == 0) return; IBEP20(BUNNY_BNB).safeTransfer(BUNNY_POOL, bunnyBNBAmount); IStakingRewards(BUNNY_POOL).notifyRewardAmount(bunnyBNBAmount); (uint valueInBNB,) = priceCalculator.valueOfAsset(BUNNY_BNB, bunnyBNBAmount); uint contribution = valueInBNB.mul(_performanceFee).div(feeSum); uint mintBunny = amountBunnyToMint(contribution); if (mintBunny == 0) return; _mint(mintBunny, to); } /* ========== PancakeSwap V2 FUNCTIONS ========== */ function mintForV2(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint) external payable override onlyMinter { uint feeSum = _performanceFee.add(_withdrawalFee); _transferAsset(asset, feeSum); if (asset == BUNNY) { IBEP20(BUNNY).safeTransfer(DEAD, feeSum); return; } uint bunnyBNBAmount = _zapAssetsToBunnyBNB(asset, feeSum, true); if (bunnyBNBAmount == 0) return; IBEP20(BUNNY_BNB).safeTransfer(BUNNY_POOL, bunnyBNBAmount); IStakingRewards(BUNNY_POOL).notifyRewardAmount(bunnyBNBAmount); (uint valueInBNB,) = priceCalculator.valueOfAsset(BUNNY_BNB, bunnyBNBAmount); uint contribution = valueInBNB.mul(_performanceFee).div(feeSum); uint mintBunny = amountBunnyToMint(contribution); if (mintBunny == 0) return; _mint(mintBunny, to); } /* ========== BunnyChef FUNCTIONS ========== */ function mint(uint amount) external override onlyBunnyChef { if (amount == 0) return; _mint(amount, address(this)); } function safeBunnyTransfer(address _to, uint _amount) external override onlyBunnyChef { if (_amount == 0) return; uint bal = IBEP20(BUNNY).balanceOf(address(this)); if (_amount <= bal) { IBEP20(BUNNY).safeTransfer(_to, _amount); } else { IBEP20(BUNNY).safeTransfer(_to, bal); } } // @dev should be called when determining mint in governance. Bunny is transferred to the timelock contract. function mintGov(uint amount) external override onlyOwner { if (amount == 0) return; _mint(amount, TIMELOCK); } /* ========== PRIVATE FUNCTIONS ========== */ function _transferAsset(address asset, uint amount) private { if (asset == address(0)) { // case) transferred BNB require(msg.value >= amount); } else { IBEP20(asset).safeTransferFrom(msg.sender, address(this), amount); } } function _zapAssetsToBunnyBNB(address asset, uint amount, bool fromV2) private returns (uint bunnyBNBAmount) { uint _initBunnyBNBAmount = IBEP20(BUNNY_BNB).balanceOf(address(this)); if (asset == address(0)) { zapBSC.zapIn{ value : amount }(BUNNY_BNB); } else if (keccak256(abi.encodePacked(IPancakePair(asset).symbol())) == keccak256("Cake-LP")) { IPancakeRouter02 router = fromV2 ? routerV2 : routerV1; if (IBEP20(asset).allowance(address(this), address(router)) == 0) { IBEP20(asset).safeApprove(address(router), uint(- 1)); } IPancakePair pair = IPancakePair(asset); address token0 = pair.token0(); address token1 = pair.token1(); (uint amountToken0, uint amountToken1) = router.removeLiquidity(token0, token1, amount, 0, 0, address(this), block.timestamp); if (IBEP20(token0).allowance(address(this), address(zapBSC)) == 0) { IBEP20(token0).safeApprove(address(zapBSC), uint(- 1)); } if (IBEP20(token1).allowance(address(this), address(zapBSC)) == 0) { IBEP20(token1).safeApprove(address(zapBSC), uint(- 1)); } zapBSC.zapInToken(token0, amountToken0, BUNNY_BNB); zapBSC.zapInToken(token1, amountToken1, BUNNY_BNB); } else { if (IBEP20(asset).allowance(address(this), address(zapBSC)) == 0) { IBEP20(asset).safeApprove(address(zapBSC), uint(- 1)); } zapBSC.zapInToken(asset, amount, BUNNY_BNB); } bunnyBNBAmount = IBEP20(BUNNY_BNB).balanceOf(address(this)).sub(_initBunnyBNBAmount); } function _mint(uint amount, address to) private { BEP20 tokenBUNNY = BEP20(BUNNY); tokenBUNNY.mint(amount); if (to != address(this)) { tokenBUNNY.transfer(to, amount); } uint bunnyForDev = amount.mul(15).div(100); tokenBUNNY.mint(bunnyForDev); IStakingRewards(BUNNY_POOL).stakeTo(bunnyForDev, DEPLOYER); } }
수정본
파일 열기
// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; /* ___ _ _ | _ )_ _ _ _ _ _ _ _ | | | | | _ \ || | ' \| ' \ || | |_| |_| |___/\_,_|_||_|_||_\_, | (_) (_) |__/ * * MIT License * =========== * * Copyright (c) 2020 BunnyFinance * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/BEP20.sol"; import "@pancakeswap/pancake-swap-lib/contracts/token/BEP20/SafeBEP20.sol"; import "@pancakeswap/pancake-swap-lib/contracts/math/SafeMath.sol"; import "../interfaces/IBunnyMinterV2.sol"; import "../interfaces/IStakingRewards.sol"; import "../interfaces/IPriceCalculator.sol"; import "../zap/ZapBSC.sol"; import "../library/SafeToken.sol"; contract BunnyMinterV2 is IBunnyMinterV2, OwnableUpgradeable { using SafeMath for uint; using SafeBEP20 for IBEP20; /* ========== CONSTANTS ============= */ address public constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c; address public constant BUNNY = 0xC9849E6fdB743d08fAeE3E34dd2D1bc69EA11a51; address public constant BUNNY_POOL = 0xCADc8CB26c8C7cB46500E61171b5F27e9bd7889D; address public constant TREASURY = 0x0989091F27708Bc92ea4cA60073e03592B94C0eE; address private constant TIMELOCK = 0x85c9162A51E03078bdCd08D4232Bab13ed414cC3; address private constant DEAD = 0x000000000000000000000000000000000000dEaD; uint public constant FEE_MAX = 10000; IPriceCalculator public constant priceCalculator = IPriceCalculator(0xF5BF8A9249e3cc4cB684E3f23db9669323d4FB7d); /* ========== STATE VARIABLES ========== */ address public bunnyChef; mapping(address => bool) private _minters; address public _deprecated_helper; // deprecated uint public PERFORMANCE_FEE; uint public override WITHDRAWAL_FEE_FREE_PERIOD; uint public override WITHDRAWAL_FEE; uint public override bunnyPerProfitBNB; uint public bunnyPerBunnyBNBFlip; // will be deprecated /* ========== MODIFIERS ========== */ modifier onlyMinter { require(isMinter(msg.sender) == true, "BunnyMinterV2: caller is not the minter"); _; } modifier onlyBunnyChef { require(msg.sender == bunnyChef, "BunnyMinterV2: caller not the bunny chef"); _; } receive() external payable {} /* ========== INITIALIZER ========== */ function initialize() external initializer { WITHDRAWAL_FEE_FREE_PERIOD = 3 days; WITHDRAWAL_FEE = 50; PERFORMANCE_FEE = 3000; bunnyPerProfitBNB = 5e18; bunnyPerBunnyBNBFlip = 6e18; IBEP20(BUNNY).approve(BUNNY_POOL, uint(- 1)); } /* ========== RESTRICTED FUNCTIONS ========== */ function transferBunnyOwner(address _owner) external onlyOwner { Ownable(BUNNY).transferOwnership(_owner); } function setWithdrawalFee(uint _fee) external onlyOwner { require(_fee < 500, "wrong fee"); // less 5% WITHDRAWAL_FEE = _fee; } function setPerformanceFee(uint _fee) external onlyOwner { require(_fee < 5000, "wrong fee"); PERFORMANCE_FEE = _fee; } function setWithdrawalFeeFreePeriod(uint _period) external onlyOwner { WITHDRAWAL_FEE_FREE_PERIOD = _period; } function setMinter(address minter, bool canMint) external override onlyOwner { if (canMint) { _minters[minter] = canMint; } else { delete _minters[minter]; } } function setBunnyPerProfitBNB(uint _ratio) external onlyOwner { bunnyPerProfitBNB = _ratio; } function setBunnyPerBunnyBNBFlip(uint _bunnyPerBunnyBNBFlip) external onlyOwner { bunnyPerBunnyBNBFlip = _bunnyPerBunnyBNBFlip; } function setBunnyChef(address _bunnyChef) external onlyOwner { require(bunnyChef == address(0), "BunnyMinterV2: setBunnyChef only once"); bunnyChef = _bunnyChef; } /* ========== VIEWS ========== */ function isMinter(address account) public view override returns (bool) { if (IBEP20(BUNNY).getOwner() != address(this)) { return false; } return _minters[account]; } function amountBunnyToMint(uint bnbProfit) public view override returns (uint) { return bnbProfit.mul(bunnyPerProfitBNB).div(1e18); } function amountBunnyToMintForBunnyBNB(uint amount, uint duration) public view override returns (uint) { return amount.mul(bunnyPerBunnyBNBFlip).mul(duration).div(365 days).div(1e18); } function withdrawalFee(uint amount, uint depositedAt) external view override returns (uint) { if (depositedAt.add(WITHDRAWAL_FEE_FREE_PERIOD) > block.timestamp) { return amount.mul(WITHDRAWAL_FEE).div(FEE_MAX); } return 0; } function performanceFee(uint profit) public view override returns (uint) { return profit.mul(PERFORMANCE_FEE).div(FEE_MAX); } /* ========== V1 FUNCTIONS ========== */ function mintFor(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint) public payable override onlyMinter { uint feeSum = _performanceFee.add(_withdrawalFee); _transferAsset(asset, feeSum); if (asset == BUNNY) { IBEP20(BUNNY).safeTransfer(DEAD, feeSum); return; } if (asset == address(0)) { // means BNB SafeToken.safeTransferETH(TREASURY, feeSum); } else { IBEP20(asset).safeTransfer(TREASURY, feeSum); } (uint contribution, ) = priceCalculator.valueOfAsset(asset, _performanceFee); uint mintBunny = amountBunnyToMint(contribution); if (mintBunny == 0) return; _mint(mintBunny, to); } /* ========== PancakeSwap V2 FUNCTIONS ========== */ function mintForV2(address asset, uint _withdrawalFee, uint _performanceFee, address to, uint timestamp) external payable override onlyMinter { mintFor(asset, _withdrawalFee, _performanceFee, to, timestamp); } /* ========== BunnyChef FUNCTIONS ========== */ function mint(uint amount) external override onlyBunnyChef { if (amount == 0) return; _mint(amount, address(this)); } function safeBunnyTransfer(address _to, uint _amount) external override onlyBunnyChef { if (_amount == 0) return; uint bal = IBEP20(BUNNY).balanceOf(address(this)); if (_amount <= bal) { IBEP20(BUNNY).safeTransfer(_to, _amount); } else { IBEP20(BUNNY).safeTransfer(_to, bal); } } // @dev should be called when determining mint in governance. Bunny is transferred to the timelock contract. function mintGov(uint amount) external override onlyOwner { if (amount == 0) return; _mint(amount, TIMELOCK); } /* ========== PRIVATE FUNCTIONS ========== */ function _transferAsset(address asset, uint amount) private { if (asset == address(0)) { // case) transferred BNB require(msg.value >= amount); } else { IBEP20(asset).safeTransferFrom(msg.sender, address(this), amount); } } function _mint(uint amount, address to) private { BEP20 tokenBUNNY = BEP20(BUNNY); tokenBUNNY.mint(amount); if (to != address(this)) { tokenBUNNY.transfer(to, amount); } uint bunnyForDev = amount.mul(15).div(100); tokenBUNNY.mint(bunnyForDev); tokenBUNNY.transfer(TREASURY, bunnyForDev); } }
비교하기