function harvest(uint256 minOutCurve) external onlyRole(STRATEGIST_ROLE) {
    convexConfig.baseRewardPool.getReward(address(this), true);

    //Prevent `Stack too deep` errors
    {
        DexConfig memory dex = dexConfig;
        IERC20[] memory rewardTokens = strategyConfig.rewardTokens;
        IERC20 _weth = weth;
        for (uint256 i = 0; i < rewardTokens.length; i++) {
            uint256 balance = rewardTokens[i].balanceOf(address(this));

            if (balance > 0)
                //minOut is not needed here, we already have it on the Curve deposit
                _swapUniswapV2(
                    dex.uniswapV2,
                    rewardTokens[i],
                    _weth,
                    balance,
                    0
                );
        }

        uint256 wethBalance = _weth.balanceOf(address(this));
        require(wethBalance > 0, "NOOP");
        ...
 function _swapUniswapV2(
    IUniswapV2Router router,
    IERC20 tokenIn,
    IERC20 tokenOut,
    uint256 amountIn,
    uint256 minOut
) internal {
    tokenIn.safeIncreaseAllowance(address(router), amountIn);

    address[] memory path = new address[](2);
    path[0] = address(tokenIn);
    path[1] = address(tokenOut);

    router.swapExactTokensForTokens(
        amountIn,
        minOut,
        path,
        address(this),
        block.timestamp
    );
}
