contract Strategy is CurveVoterProxy {
    using SafeERC20 for IERC20;
    using Address for address;
    using SafeMath for uint256;

    address public constant pnt = address(0x89Ab32156e46F46D02ade3FEcbe5Fc4243B9AAeD);

    constructor(address _vault) public CurveVoterProxy(_vault) {
        dex = sushiswap;
        curve = address(0x11F419AdAbbFF8d595E7d5b223eee3863Bb3902C);
        gauge = address(0xd7d147c6Bb90A718c3De8C0568F9B560C79fa416);
        keepCRV = 1000;
    }

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

            IERC20(crv).safeApprove(dex, 0);
            IERC20(crv).safeApprove(dex, _crv);

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

            Uni(dex).swapExactTokensForTokens(_crv, uint256(0), path, address(this), now);
        }
        IVoterProxy(proxy).claimRewards(gauge, pnt);
        uint256 _pnt = IERC20(pnt).balanceOf(address(this));
        if (_pnt > 0) {
            IERC20(pnt).safeApprove(uniswap, 0);
            IERC20(pnt).safeApprove(uniswap, _pnt);

            address[] memory path = new address[](3);
            path[0] = pnt;
            path[1] = weth;
            path[2] = wbtc;

            Uni(uniswap).swapExactTokensForTokens(_pnt, uint256(0), path, address(this), now);
        }
        uint256 _wbtc = IERC20(wbtc).balanceOf(address(this));
        if (_wbtc > 0) {
            IERC20(wbtc).safeApprove(curve, 0);
            IERC20(wbtc).safeApprove(curve, _wbtc);
            ICurveFi(curve).add_liquidity([0, 0, _wbtc, 0], 0);
        }
        _profit = want.balanceOf(address(this)).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[](2);
        protected[0] = crv;
        protected[1] = pnt;
        return protected;
    }
}
function protectedTokens()
        internal
        view
        override
        returns (address[] memory)
    {
        address[] memory protected = new address[](2);
        protected[0] = crv;
        protected[1] = pnt;
        return protected;
    }
// NOTE: Can override `tendTrigger` and `harvestTrigger` if necessary