Diff
checker
Text
Text
Images
Documents
Excel
Folders
Legal
Enterprise
Desktop
Pricing
Sign in
Download Diffchecker Desktop
Compare text
Find the difference between two text files
Tools
History
Real-time editor
Hide whitespace changes
Hide unchanged lines
Disable line wrap
Layout
Split
Unified
Diff precision
Smart
Word
Char
Text styles
Change appearance
Syntax highlighting
Choose syntax
Ignore
Transform text
Go to first change
Edit input
Diffchecker Desktop
The most secure way to run Diffchecker. Get the Diffchecker Desktop app: your diffs never leave your computer!
Get Desktop
BunnyMinterV2.sol
Created
5 years ago
Diff never expires
Clear
Export
Share
Explain
88 removals
Lines
Total
Removed
Characters
Total
Removed
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
313 lines
Copy
24 additions
Lines
Total
Added
Characters
Total
Added
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
251 lines
Copy
// 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";
Copy
Copied
Copy
Copied
import "../
dashboard/calculator/
PriceCalculator
BSC
.sol";
import "../
interfaces/I
PriceCalculator
.sol";
import "../zap/ZapBSC.sol";
import "../zap/ZapBSC.sol";
Copy
Copied
Copy
Copied
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;
Copy
Copied
Copy
Copied
address public constant BUNNY_BNB = 0x7Bb89460599Dbf32ee3Aa50798BBcEae2A5F7f6a;
address public constant BUNNY_POOL = 0xCADc8CB26c8C7cB46500E61171b5F27e9bd7889D;
address public constant BUNNY_POOL = 0xCADc8CB26c8C7cB46500E61171b5F27e9bd7889D;
Copy
Copied
Copy
Copied
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;
Copy
Copied
Copy
Copied
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 ========== */
Copy
Copied
Copy
Copied
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;
}
}
Copy
Copied
Copy
Copied
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);
}
Copy
Copied
Copy
Copied
(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 ========== */
Copy
Copied
Copy
Copied
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);
}
}
}
}
Copy
Copied
Copy
Copied
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);
Copy
Copied
Copy
Copied
IStakingRewards(BUNNY_POOL).stakeTo(
bunnyForDev
, DEPLOYER
);
tokenBUNNY.transfer(TREASURY,
bunnyForDev
);
}
}
}
}
Copy
Copied
Copy
Copied
Saved diffs
Original text
Open file
// 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); } }
Changed text
Open file
// 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); } }
Find difference