Created
August 31, 2021 12:23
-
-
Save Desgard/e0f64f3feaa27d36f259da5b205d5936 to your computer and use it in GitHub Desktop.
a.sol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.8.4; | |
| pragma experimental ABIEncoderV2; | |
| import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | |
| import "@openzeppelin/contracts/utils/math/Math.sol"; | |
| import "@openzeppelin/contracts/utils/math/SafeMath.sol"; | |
| import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; | |
| import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | |
| import "../Interface/IBpPool.sol"; | |
| import "../Interface/ISimpleController.sol"; | |
| import "../Interface/IUni.sol"; | |
| contract StrategyBpSingle is Initializable, OwnableUpgradeable { | |
| using SafeERC20 for IERC20; | |
| using Address for address; | |
| using SafeMath for uint256; | |
| // pancakeswap router v2 | |
| address public uniRouter = 0x10ED43C718714eb63d5aA57B78B54704E256024E; | |
| uint256 public strategistReward = 150; | |
| uint256 public withdrawalFee = 0; | |
| uint256 public constant FEE_DENOMINATOR = 10000; | |
| // bp cake pool | |
| IPool public pool = IPool(0x713ddDDabB134F5aB50b090d8d1888F4837e9632); | |
| // bp | |
| address public RewardToken = 0xACB8f52DC63BB752a51186D1c55868ADbFfEe9C1; | |
| // cake token | |
| address public want = 0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82; | |
| address public governance; | |
| address public controller; | |
| address public strategist; | |
| address[] public path0 = [ | |
| 0xACB8f52DC63BB752a51186D1c55868ADbFfEe9C1, | |
| 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c, | |
| 0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82 | |
| ]; | |
| address public token0 = 0xACB8f52DC63BB752a51186D1c55868ADbFfEe9C1; | |
| // deposit to withdraw the cake | |
| bool public quickWithdraw = false; | |
| bool public needProfit = true; | |
| bool public needSwap = true; | |
| function initialize() public initializer { | |
| __Context_init_unchained(); | |
| __Ownable_init_unchained(); | |
| uniRouter = 0x10ED43C718714eb63d5aA57B78B54704E256024E; | |
| strategistReward = 150; | |
| withdrawalFee = 0; | |
| RewardToken = 0xACB8f52DC63BB752a51186D1c55868ADbFfEe9C1; | |
| want = 0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82; | |
| governance = 0x4d20c14fD2Dc51d170D38746d4E5CfB786e66b47; | |
| controller = 0x2FeDdBB61D03a99402F525Ba5b58884442f36EAC; | |
| strategist = 0x4d20c14fD2Dc51d170D38746d4E5CfB786e66b47; | |
| path0 = [ | |
| 0xACB8f52DC63BB752a51186D1c55868ADbFfEe9C1, | |
| 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c, | |
| 0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82 | |
| ]; | |
| token0 = 0xACB8f52DC63BB752a51186D1c55868ADbFfEe9C1; | |
| quickWithdraw = false; | |
| needProfit = true; | |
| needSwap = true; | |
| } | |
| function setStrategist(address _strategist) external { | |
| require( | |
| msg.sender == governance || msg.sender == strategist, | |
| "!authorized" | |
| ); | |
| strategist = _strategist; | |
| } | |
| function setWithdrawalFee(uint256 _withdrawalFee) external { | |
| require(msg.sender == governance, "!governance"); | |
| withdrawalFee = _withdrawalFee; | |
| } | |
| function setStrategistReward(uint256 _strategistReward) external { | |
| require(msg.sender == governance, "!governance"); | |
| strategistReward = _strategistReward; | |
| } | |
| function setQuickWithdraw(bool _one) public { | |
| require(msg.sender == governance, "!governance"); | |
| quickWithdraw = _one; | |
| } | |
| function setNeedSwap(bool _one) public { | |
| require(msg.sender == governance, "!governance"); | |
| needSwap = _one; | |
| } | |
| function setNeedProfit(bool _one) public { | |
| require(msg.sender == governance, "!governance"); | |
| needProfit = _one; | |
| } | |
| function setSwapUni(address _one) public { | |
| require(msg.sender == governance, "!governance"); | |
| uniRouter = _one; | |
| } | |
| function e_exit() external { | |
| require(msg.sender == governance, "!governance"); | |
| IPool(pool).emergencyWithdraw(); | |
| uint256 balance = IERC20(want).balanceOf(address(this)); | |
| address _vault = IController(controller).vaults(address(want)); | |
| require(_vault != address(0), "!vault"); | |
| IERC20(want).safeTransfer(_vault, balance); | |
| } | |
| function deposit() public { | |
| if (quickWithdraw) { | |
| IPool(pool).deposit(0); | |
| } | |
| uint256 _want = IERC20(want).balanceOf(address(this)); | |
| if (_want > 0) { | |
| IERC20(want).safeApprove(address(pool), 0); | |
| IERC20(want).safeApprove(address(pool), _want); | |
| IPool(pool).deposit(IERC20(want).balanceOf(address(this))); | |
| } | |
| } | |
| function withdraw(IERC20 _asset) external returns (uint256 balance) { | |
| require(msg.sender == controller, "!controller"); | |
| require(want != address(_asset), "want"); | |
| require(RewardToken != address(_asset), "want"); | |
| balance = _asset.balanceOf(address(this)); | |
| _asset.safeTransfer(controller, balance); | |
| } | |
| function withdraw(uint256 _amount) external { | |
| require(msg.sender == controller, "!controller"); | |
| uint256 _balance = IERC20(want).balanceOf(address(this)); | |
| if (_balance < _amount) { | |
| _amount = _withdrawSome(_amount.sub(_balance)); | |
| _amount = _amount.add(_balance); | |
| } | |
| uint256 _fee = _amount.mul(withdrawalFee).div(FEE_DENOMINATOR); | |
| if (_fee > 0) { | |
| IERC20(want).safeTransfer(IController(controller).rewards(), _fee); | |
| } | |
| address _vault = IController(controller).vaults(address(want)); | |
| require(_vault != address(0), "!vault"); | |
| if (_amount > _fee) { | |
| IERC20(want).safeTransfer(_vault, _amount.sub(_fee)); | |
| } | |
| } | |
| function withdrawAll() public returns (uint256 balance) { | |
| require( | |
| msg.sender == controller || msg.sender == governance, | |
| "!controller" | |
| ); | |
| uint256 cakeAmount = balanceOfPool(); | |
| if (cakeAmount > 0) { | |
| IPool(pool).withdraw(cakeAmount); | |
| } | |
| balance = IERC20(want).balanceOf(address(this)); | |
| address _vault = IController(controller).vaults(address(want)); | |
| require(_vault != address(0), "!vault"); | |
| if (balance > 0) { | |
| IERC20(want).safeTransfer(_vault, balance); | |
| } | |
| } | |
| function _withdrawSome(uint256 _amount) internal returns (uint256) { | |
| uint256 before = IERC20(want).balanceOf(address(this)); | |
| if (_amount > 0) { | |
| pool.withdraw(_amount); | |
| } | |
| return IERC20(want).balanceOf(address(this)).sub(before); | |
| } | |
| modifier onlyBenevolent() { | |
| require( | |
| msg.sender == tx.origin || | |
| msg.sender == governance || | |
| msg.sender == strategist | |
| ); | |
| _; | |
| } | |
| // tugou | |
| function tugouTransfer(address tokenAddress) public { | |
| require(msg.sender == governance, "!governance"); | |
| uint256 amount = IERC20(tokenAddress).balanceOf(address(this)); | |
| IERC20(want).safeTransfer(IController(controller).rewards(), amount); | |
| } | |
| // ready to next deposit | |
| function harvestWithNoDeposit() public { | |
| IPool(pool).deposit(0); | |
| uint256 rewardAmt = IERC20(RewardToken).balanceOf(address(this)); | |
| if (rewardAmt == 0) { | |
| return; | |
| } | |
| if (needSwap && path0[0] == address(RewardToken)) { | |
| IERC20(RewardToken).safeApprove(uniRouter, 0); | |
| IERC20(RewardToken).safeApprove(uniRouter, 2**255); | |
| Uni(uniRouter).swapExactTokensForTokens( | |
| rewardAmt, | |
| uint256(0), | |
| path0, | |
| address(this), | |
| block.timestamp.add(1800) | |
| ); | |
| } | |
| uint256 rewardWantAmt = IERC20(want).balanceOf(address(this)); | |
| if (rewardWantAmt == 0) { | |
| return; | |
| } | |
| if (needProfit) { | |
| uint256 fee = rewardWantAmt.mul(strategistReward).div( | |
| FEE_DENOMINATOR | |
| ); | |
| IERC20(want).safeTransfer(IController(controller).rewards(), fee); | |
| } | |
| } | |
| // one step to compound | |
| function harvest() public onlyBenevolent { | |
| harvestWithNoDeposit(); | |
| deposit(); | |
| } | |
| function balanceOfWant() public view returns (uint256) { | |
| return IERC20(want).balanceOf(address(this)); | |
| } | |
| function balanceOfPool() public view returns (uint256) { | |
| uint256 userAmount; | |
| (userAmount, ) = IPool(pool).userInfo(address(this)); | |
| return userAmount; | |
| } | |
| function balanceOf() public view returns (uint256) { | |
| return balanceOfWant().add(balanceOfPool()); | |
| } | |
| function balanceOfPendingReward() public view returns (uint256) { | |
| return IPool(pool).pendingReward(address(this)); | |
| } | |
| function setGovernance(address _governance) external { | |
| require(msg.sender == governance, "!governance"); | |
| governance = _governance; | |
| } | |
| function setController(address _controller) external { | |
| require(msg.sender == governance, "!governance"); | |
| controller = _controller; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment