contract StrategyCurveUSDPv1 is StrategyCurveBase {
    // Curve stuff
    address public usdp_wrapped_pool = 0x3c8cAee4E09296800f8D29A68Fa3837e2dae4940;
    address public usdp_pool = 0x42d7025938bEc20B69cBae5A77421082407f053A;
    address public usdp_gauge = 0x055be5DDB7A925BfEF3417FC157f53CA77cA7222;
    address public usdp_crv = 0x7Eb40E450b9655f4B3cC4259BCC731c63ff55ae6;
    address public three_pool = 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7;

    constructor(
        address _governance,
        address _strategist,
        address _controller,
        address _timelock
    )
    public
    StrategyCurveBase(
        usdp_wrapped_pool,
        usdp_gauge,
        usdp_crv,
        _governance,
        _strategist,
        _controller,
        _timelock
    )
    {
        IERC20(usdc).safeApprove(usdp_wrapped_pool, uint256(-1));
        IERC20(usdp_crv).safeApprove(usdp_wrapped_pool, uint256(-1));
    }

    // **** Views ****

    function getMostPremium()
    public
    override
    view
    returns (address, uint256)
    {
        return (usdc, 2);
    }

    function getName() external override pure returns (string memory) {
        return "StrategyCurveUSDPv1";
    }

    // **** State Mutations ****

    function _convertWantToBuyback(uint256 _lpAmount) internal override returns (address, uint256){
        (address to, uint256 toIndex) = getMostPremium();
        ICurveFi_3(curve).remove_liquidity_one_coin(_lpAmount, int128(toIndex), 0);
        uint256 _to = IERC20(to).balanceOf(address(this));
        return (to, _to);
    }

    function harvest() public onlyBenevolent override {
        // 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.

        // stablecoin we want to convert to
        (address to, uint256 toIndex) = getMostPremium();

        // Collects crv tokens
        // Don't bother voting in v1
        ICurveMintr(mintr).mint(gauge);
        uint256 _crv = IERC20(crv).balanceOf(address(this));
        if (_crv > 0) {
            // x% is sent back to the rewards holder
            // to be used to lock up in as veCRV in a future date
            uint256 _keepCRV = _crv.mul(keepCRV).div(keepCRVMax);
            if (_keepCRV > 0) {
                IERC20(crv).safeTransfer(
                    IController(controller).treasury(),
                    _keepCRV
                );
            }
            _crv = _crv.sub(_keepCRV);
            _swapUniswap(crv, to, _crv);
        }

        // Adds liquidity to curve.fi's pool
        // to get back want (usdp3crv)
        uint256 _to = IERC20(to).balanceOf(address(this));
        uint256 _buybackAmount = _to.mul(performanceFee).div(performanceMax);
        if (_to > 0) {
            if (buybackEnabled == true && _to > 0) {
                _to = _to.mul(performanceMax.sub(performanceFee)).div(performanceMax);
            }

            uint256[4] memory liquidity;
            liquidity[toIndex] = _to;
            ICurveFi_4(curve).add_liquidity(liquidity, 0);
        }

        uint256 _want = IERC20(want).balanceOf(address(this));
        if (buybackEnabled == true && _buybackAmount > 0) {
            buybackAndNotify(to, _buybackAmount);
        } else {
            // We want to get back usdp3crv
            if (_want > 0) {
                // Performance Fees goes to treasury
                IERC20(want).safeTransfer(IController(controller).treasury(), _want.mul(performanceFee).div(performanceMax));
            }
        }

        // re-invest to compounding profit
        if (_want > 0) {
            lastHarvestBlock = block.number;
            lastHarvestInWant = IERC20(want).balanceOf(address(this));
            deposit();
        }
    }
}
function _convertWantToBuyback(uint256 _lpAmount) internal override returns (address, uint256){
    (address to, uint256 toIndex) = getMostPremium();
    ICurveFi_3(curve).remove_liquidity_one_coin(_lpAmount, int128(toIndex), 0);
    uint256 _to = IERC20(to).balanceOf(address(this));
    return (to, _to);
}

// **** State Mutations ****