Open github-actions[bot] opened 2 years ago
In our api, we require toToken is WETH when contructing callData. We will add some notes here. Thanks for noticing
Even tough the API is requiring WETH we still think it's a valid issue as the contract has a payable modifier.
We will add this check: require(msg.value == fromTokenAmount, "invalid ETH amount"); As the fromToken is ETH, we won't deposit it into routeProxy, we will transfer the ETH amount directly.
comments are added at the start of the function.
Fixes are done as mentioned in, We will add this check: require(msg.value == fromTokenAmount, "invalid ETH amount");
ctf_sec
medium
Issue when handling native ETH trade and WETH trade in DODO RouterProxy#externalSwap
Summary
Lack of logic to wrap the native ETH to WETH in function externalSwap
Vulnerability Detail
The function exeternalSwap can handle external swaps with 0x, 1inch and paraswap or other external resources.
note the code above, if the fromToken is set to _ETH_ADDRESS, indicating the user wants to trade with native ETH pair. the function does has payable modifier and user can send ETH along when calling this function.
However, the toTokenOriginBalance is check the only WETH balance instead of ETH balance.
Then we do the swap:
If the fromToken is _ETH_ADDRESS, we send the user supplied fromTokenAmount without verifying that the fromTokenAmount.
Finally, we use the before and after balance to get the amount with received.
We are checking the WETH amount instead of ETH amount again.
The issue is that some trades may settle the trade in native ETH, for example
https://developers.paraswap.network/smart-contracts
we can look into the Paraswap contract
https://etherscan.io/address/0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57#writeProxyContract
If we click the implementation contract and see the method swapOnUniswapV2Fork
https://etherscan.io/address/0x4ff0dec5f9a763aa1e5c2a962aa6f4edfee4f9ea#code
Code line 927 - 944, which calls the function
which calls:
as can clearly see, the code first receive ETH, wrap ETH to WETH, then instead end, unwrap the WETH to ETH and the send the ETH back to complete the trade.
In DODORouterProxy.sol#ExternalSwap however, we are using WETH balance before and after to check the received amount,
but if we call swapOnUniswapV2Fork on Paraswap router, the balance change for WETH would be 0
because as we see above, the method on paraswap side wrap ETH to WETH but in the end unwrap WETH and send ETH back.
There is also a lack of a method to wrap the ETH to WETH before the trade. making the ETH-related order not tradeable.
Impact
A lot of method that does not use WETH to settle the trade will not be callable.
Code Snippet
https://github.com/sherlock-audit/2022-11-dodo/blob/main/contracts/SmartRoute/DODORouteProxy.sol#L158-L230
Tool used
Manual Review
Recommendation
We recommend the project change from
If we want to use WETH to do the balance check, we can help the user wrap the ETH to WETH by calling before do the balance check.
If we want to use WETH as the reference to trade, we also need to approve external contract to spend our WETH.
We can add
We also need to verify the fromTokenAmount for
we can add the check: