MEDIUM severity: The vulnerability in the DODO RouterProxy's externalSwap function lies in its handling of native ETH. The vulnerability in the DODO RouterProxy's externalSwap function lies in its handling of native ETH trades and WETH trades. Specifically, when the fromToken is set to the native ETH address, the function does not properly account for the wrapping and unwrapping of ETH to WETH.\n\nThe issue arises w...

Vulnerable code:
```\nfunction externalSwap(\n    address fromToken,\n    address toToken,\n    address approveTarget,\n    address swapTarget,\n    uint256 fromTokenAmount,\n    uint256 minReturnAmount,\n    bytes memory feeData,\n    bytes memory callDataConcat,\n    uint256 deadLine\n) external payable judgeExpired(deadLine) returns (uint256 receiveAmount) {\n    require(isWhiteListedContract[swapTarget], "DODORouteProxy: Not Whitelist Contract");\n    require(isApproveWhiteListedContract[approveTarget], "DODORouteProxy: Not Whitelist Appprove Contract");\n\n    // transfer in fromToken\n    if (fromToken!= _ETH_ADDRESS_) {\n        // approve if needed\n        if (approveTarget!= address(0)) {\n            IERC20(fromToken).universalApproveMax(approveTarget, fromTokenAmount);\n        }\n\n        IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(\n            fromToken,\n            msg.sender,\n            address(this),\n            fromTokenAmount\n        );\n    }\n\n    // swap\n    uint256 toTokenOriginBalance;\n    if (toToken!= _ETH_ADDRESS_) {\n        toTokenOriginBalance = IERC20(toToken).universalBalanceOf(address(this));\n    } else {\n        toTokenOriginBalance = IERC20(_WETH_).universalBalanceOf(address(this));\n    }\n```\n```\nif (toToken!= _ETH_ADDRESS_) {\n    toTokenOriginBalance = IERC20(toToken).balanceOf(address(this));\n} else {\n    toTokenOriginBalance = IERC20(_WETH_).balanceOf(address(this));\n}\n```\n```\n(bool success, bytes memory result) = swapTarget.call{\n    value: fromToken == _ETH_ADDRESS_? fromTokenAmount : 0\n}(callDataConcat);\n```\n```\nif (toToken!= _ETH_ADDRESS_) {\n    receiveAmount = IERC20(toToken).universalBalanceOf(address(this)) - (\n        toTokenOriginBalance\n    );\n} else {\n    receiveAmount = IERC20(_WETH_).universalBalanceOf(address(this)) - (\n        toTokenOriginBalance\n    );\n}\n```\n```\nfunction swapOnUniswapV2Fork(\n    address tokenIn,\n    uint256 amountIn,\n    uint256 amountOutMin,\n    address weth,\n    uint256[] calldata pools\n)\n    external\n    payable\n{\n    _swap(\n        tokenIn,\n        amountIn,\n        amountOutMin,\n        weth,\n        pools\n    );\n}\n```\n```\nfunction _swap(\n    address tokenIn,\n    uint256 amountIn,\n    uint256 amountOutMin,\n    address weth,\n    uint256[] memory pools\n) private\nreturns (uint256 tokensBought)\n{\n    uint256 pairs = pools.length;\n\n    require(pairs!= 0, "At least one pool required");\n\n    bool tokensBoughtEth;\n\n    if (tokenIn == ETH_IDENTIFIER) {\n        require(amountIn == msg.value, "Incorrect msg.value");\n        IWETH(weth).deposit{value: msg.value}();\n        require(IWETH(weth).transfer(address(pools[0]), msg.value));\n    } else {\n        require(msg.value == 0, "Incorrect msg.value");\n        transferTokens(tokenIn, msg.sender, address(pools[0]), amountIn);\n        tokensBoughtEth = weth!= address(0);\n    }\n\n    tokensBought = amountIn;\n\n    for (uint256 i = 0; i < pairs; ++i) {\n        uint256 p = pools[i];\n        address pool = address(p);\n        bool direction = p & DIRECTION_FLAG == 0;\n\n        tokensBought = NewUniswapV2Lib.getAmountOut(tokensBought, pool, direction, p + FEE_OFFSET);\n        (uint256 amount0Out, uint256 amount1Out) = direction\n           ? (uint256(0), tokensBought) : (tokensBought, uint256(0));\n        IUniswapV2Pair(pool).swap(\n            amount0Out,\n            amount1Out,\n            i + 1 == pairs\n               ? (tokensBoughtEth? address(this) : msg.sender)\n                : address(pools[i + 1]),\n            ""\n        );\n    }\n\n    if (tokensBoughtEth) {\n        IWETH(weth).withdraw(tokensBought);\n        TransferHelper.safeTransferETH(msg.sender, tokensBought);\n    }\n\n    require(tokensBought >= amountOutMin, "UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT");\n}\n```\n```\nif (tokensBoughtEth) {\n    IWETH(weth).withdraw(tokensBought);\n    TransferHelper.safeTransferETH(msg.sender, tokensBought);\n}\n```