Skip to content

Instantly share code, notes, and snippets.

@Desgard
Created August 31, 2021 12:23
Show Gist options
  • Select an option

  • Save Desgard/e0f64f3feaa27d36f259da5b205d5936 to your computer and use it in GitHub Desktop.

Select an option

Save Desgard/e0f64f3feaa27d36f259da5b205d5936 to your computer and use it in GitHub Desktop.
a.sol
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