This is a proof of concept of the bug I found in Uniswap's SwapRouter
. Read the blog post for more details:
https://jeiwan.net/posts/public-bug-report-uniswap-swaprouter/
- Ensure that you have Foundry installed.
- Run
forge install
to install the deps (forge-std
). - Set the
ETH_RPC_URL
env var to an Ethereum Mainnet RPC endpoint (e.g. use Alchemy). - Run:
$ forge test --mc UniswapV3ETHRefundExploitTest
- Alice wants to sell 1 ETH and buy some UNI. However, Alice wants her trade to be executed before the price X is reached.
- Alice calls the
exactInputSingle
function ofSwapRouter
, sets thesqrtPriceLimitX96
argument to the price X, and sends 1 ETH along with the transaction. - The router executes the swap via the ETH-UNI pool. The swap gets interrupted when the price X is reached.
- Before reaching the price X, only 0.7 ETH of Alice were consumed to convert them to 100 UNI.
- Alice receives 100 UNI while spending 1 ETH, the router contract keeps holding the remaining 0.3 ETH.
- A MEV bot withdraws the 0.3 ETH by calling the
refundETH
function.