Skip to content

prince2014/exploit-uniswap-v1

Repository files navigation

Exploiting an ERC777-token Uniswap Exchange

standard-readme compliant

Exploiting any Uniswap exchange that trades an ERC777 token by leveraging the reentrant microtrading attack vector

Table of Contents

Prerequisites

  1. Make sure you have vyper installed. if not, see https://vyper.readthedocs.io/en/stable/installing-vyper.html
  2. Install Ganache: https://www.trufflesuite.com/ganache, and make sure you have Ganache running on localhost:8545

Install

  1. Setup a Python virtual environment
$ pip3 install virtualenv
$ virtualenv -p python3 venv
  1. Activate virtual env & install Python dependencies (just Vyper)
$ source venv/bin/activate
$ pip install -r requirements.txt

If source venv/bin/activate does not work for you, try out with bash venv/bin/activate.

  1. Install NPM dependencies
$ npm install

If you see something like node-gyp rebuild error, try to run this:

pip install git+https://chromium.googlesource.com/external/gyp

If you see scrypt related errors, like recipe for target 'Release/obj.target/scrypt/src/node-boilerplate/scrypt_params_async.o' failed, try to run this:

npm install github:barrysteyn/node-scrypt#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb

Run

Once in the virtual environment (where Vyper must be installed), run

(venv)$ npm test

Exploit details

The proof of concept for the exploit is located in the test/uniswap.exploit.js file. It takes care of setting up the entire environment and running three test case scenarios.

The environment consists of:

The three test cases are:

  1. Legitimate trading with a single external sale: a user that holds tokens wants to operate on the exchange, to deposit tokens and receive ETH. This is done in a single transaction calling the tokenToEthSwapInput function. This is the regular use case for a Uniswap exchange.

  2. Legitimate trading with multiple external sales: same as case (1), but now the user submits multiple transactions instead of just 1. Therefore, this results in less profit than (1).

  3. Exploiting: the attacker deploys an attacker contract that will be in charge of operating in the exchange. The exploit is executed in a single transaction, reentering several times in the vulnerable function tokenToEthSwapInput by leveraging the ERC777 tokensToSend hook.

Why it works

By leveraging the tokensToSend hook, the attacker contract is called after receiving ETH (i.e. the exchange ETH balance has decreased) but before the token balance is modified (i.e. the exchange token balance has not decreased). As a consequence, reentering the vulnerable tokenToEthSwapInput will re-calculate the token-ETH exchage price, but this time with less ETH and same amount of tokens in reserves. Thus, the exchange will be buying the attacker tokens, paying in ETH, at a higher price than it should.

vulnerable code

Learning resources

Disclaimer

This is a proof-of-concept exploit of an already public, disclosed and acknowledged vulnerability in Uniswap related to reentrancy attacks. Were that not the case, under no circumstances this proof-of-concept exploit would have been made public. Should you find any 0-day vulnerability in these contracts, please report directly to Uniswap.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published