contract Strategy is CurveVoterProxy {
    address public constant usdt = address(0xdAC17F958D2ee523a2206206994597C13D831ec7);
    address public constant eurt = address(0xC581b735A1688071A1746c968e0798D642EDE491);

    constructor(address _vault) public CurveVoterProxy(_vault) {
        curve = address(0xFD5dB7463a3aB53fD211b4af195c5BCCC1A03890);
        gauge = address(0xe8060Ad8971450E624d5289A10017dD30F5dA85F);
        keepCRV = 1000;

        _approveBasic();

        dex = new address[](1);
        dex[0] = sushiswap; // crv
        _approveDex();
    }

    // >>> approve the target token on curve
    function _approveBasic() internal override {
        IERC20(eurt).safeApprove(curve, 0);
        IERC20(eurt).safeApprove(curve, type(uint256).max);
    }

    // >>> approve other rewards on dex
    function _approveDex() internal override {
        super._approveDex();
        IERC20(usdt).safeApprove(uniswapv3, 0);
        IERC20(usdt).safeApprove(uniswapv3, type(uint256).max);
    }

    function prepareReturn(uint256 _debtOutstanding)
        internal
        override
        returns (
            uint256 _profit,
            uint256 _loss,
            uint256 _debtPayment
        )
    {
        uint before = balanceOfWant();
        IVoterProxy(proxy).harvest(gauge);
        uint256 _crv = IERC20(crv).balanceOf(address(this));
        if (_crv > 0) {
            _crv = _adjustCRV(_crv);

            address[] memory path = new address[](3);
            path[0] = crv;
            path[1] = weth;
            path[2] = usdt;

            Uni(dex[0]).swapExactTokensForTokens(_crv, uint256(0), path, address(this), now);
        }
        uint256 _usdt = IERC20(usdt).balanceOf(address(this));
        if (_usdt > 0) {
            UniV3(uniswapv3).exactInput(UniV3.ExactInputParams(
                abi.encodePacked(
                    usdt, 
                    uint24(500), 
                    eurt
                ),
                address(this),
                now,
                _usdt,
                uint256(0)
            ));
        }
        uint256 _eurt = IERC20(eurt).balanceOf(address(this));
        if (_eurt > 0) {
            ICurveFi(curve).add_liquidity([_eurt, 0], 0);
        }
        _profit = balanceOfWant().sub(before);

        uint _total = estimatedTotalAssets();
        uint _debt = vault.strategies(address(this)).totalDebt;
        if(_total < _debt) {
            _loss = _debt - _total;
            _profit = 0;
        }

        if (_debtOutstanding > 0) {
            _withdrawSome(_debtOutstanding);
            _debtPayment = Math.min(_debtOutstanding, balanceOfWant().sub(_profit));
        }
    }

    // NOTE: Can override `tendTrigger` and `harvestTrigger` if necessary

    function protectedTokens()
        internal
        view
        override
        returns (address[] memory)
    {
        address[] memory protected = new address[](1);
        protected[0] = crv;
        return protected;
    }
}
function _approveBasic() internal override {
    IERC20(eurt).safeApprove(curve, 0);
    IERC20(eurt).safeApprove(curve, type(uint256).max);
}

// >>> approve the target token on curve