abstract contract StrategyMirFarmBase is StrategyStakingRewardsBase {
    // Token addresses
    address public mir = 0x09a3EcAFa817268f77BE1283176B946C4ff2E608;

    // UST/<token1> pair
    address public token1;
    address public token0 = 0xa47c8bf37f92aBed4A126BDA807A7b7498661acD;

    // How much MIR tokens to keep?
    uint256 public keepMIR = 0;
    uint256 public constant keepMIRMax = 10000;

    constructor(
        address _token1,
        address _rewards,
        address _lp,
        address _governance,
        address _strategist,
        address _controller,
        address _timelock
    )
        public
        StrategyStakingRewardsBase(
            _rewards,
            _lp,
            _governance,
            _strategist,
            _controller,
            _timelock
        )
    {
        token1 = _token1;
    }

    // **** Setters ****

    function setKeepMIR(uint256 _keepMIR) external {
        require(msg.sender == timelock, "!timelock");
        keepMIR = _keepMIR;
    }

    // **** State Mutations ****
	
    function _convertWantToBuyback(uint256 _lpAmount) internal override returns (address, uint256){
        require(_lpAmount > 0, '!_lpAmount');		

        IERC20(want).safeApprove(univ2Router2, 0);
        IERC20(want).safeApprove(univ2Router2, _lpAmount);
		
        UniswapRouterV2(univ2Router2).removeLiquidity(
            token0,
            token1,
            _lpAmount,
            0,
            0,
            address(this),
            now + 60
        );	        

        // Swap token1 for UST
        uint256 _token1 = IERC20(token1).balanceOf(address(this));	
        if (_token1 > 0) {
            _swapUniswap(token1, token0, _token1);
        }
        uint256 _ust = IERC20(token0).balanceOf(address(this));	
        return (token0, _ust);
    }

    function harvest() public override onlyBenevolent {
        // Anyone can harvest it at any given time.
        // I understand the possibility of being frontrun
        // But ETH is a dark forest, and I wanna see how this plays out
        // i.e. will be be heavily frontrunned?
        //      if so, a new strategy will be deployed.

        // Collects MIR tokens
        IStakingRewards(rewards).getReward();
        uint256 _mir = IERC20(mir).balanceOf(address(this));
        if (_mir > 0) {
            // in case some mir is locked up for future gov
            uint256 _keepMIR = _mir.mul(keepMIR).div(keepMIRMax);
            if(_keepMIR > 0){
               IERC20(mir).safeTransfer(IController(controller).treasury(), _keepMIR);		
            }		
        }

        // Swap half MIR for UST
        _mir = IERC20(mir).balanceOf(address(this));
        if (_mir > 0) {
            _swapUniswap(mir, token0, _mir.div(2));
        }

        // Swap rest MIR for token1
        _mir = IERC20(mir).balanceOf(address(this));
        if (_mir > 0 && mir != token1) {
            _swapUniswap(mir, token1, _mir);
        }

        // Adds in liquidity for UST/MIR
        uint256 _ust = IERC20(token0).balanceOf(address(this));
        uint256 _token1 = IERC20(token1).balanceOf(address(this));
        if (_ust > 0 && _token1 > 0) {
            IERC20(token0).safeApprove(univ2Router2, 0);
            IERC20(token0).safeApprove(univ2Router2, _ust);

            IERC20(token1).safeApprove(univ2Router2, 0);
            IERC20(token1).safeApprove(univ2Router2, _token1);

            UniswapRouterV2(univ2Router2).addLiquidity(
                token0,
                token1,
                _ust,
                _token1,
                0,
                0,
                address(this),
                now + 60
            );
        }

        // We want to get back UNI LP tokens
        uint256 _want = IERC20(want).balanceOf(address(this));
        uint256 _buybackLpAmount = _want.mul(performanceFee).div(performanceMax);
        if (_want > 0) {
            if(buybackEnabled == true && _buybackLpAmount > 0){
                (address _buybackPrinciple, uint256 _buybackAmount) = _convertWantToBuyback(_buybackLpAmount);
                buybackAndNotify(_buybackPrinciple, _buybackAmount);
            }else{
                // Performance fee
                IERC20(want).safeTransfer(IController(controller).treasury(), _want.mul(performanceFee).div(performanceMax));			
            }
            deposit();
        }
    }
}
function setKeepMIR(uint256 _keepMIR) external {
    require(msg.sender == timelock, "!timelock");
    keepMIR = _keepMIR;
}

// **** Setters ****