Automated Market Makers (AMMs) like Uniswap provide many essential services to the DeFi ecosystem including on-chain price feeds. These price oracles are used by lending, derivatives, stable coins, and other applications. Unfortunately, it is possible to manipulate these price feeds which resulted in several multi-million dollar hacks.
In the next challenge, we will develop one such exploit against an overly trusting lending pool. Here is the description:
There's a huge lending pool borrowing Damn Valuable Tokens (DVTs), where you first need to deposit twice the borrow amount in ETH as collateral. The pool currently has 10000 DVTs in liquidity.There's a DVT market opened in an Uniswap v1 exchange, currently with 10 ETH and 10 DVT in liquidity.Starting with 100 ETH and 100 DVTs in balance, you must steal as many tokens as possible from the lending pool. And at the end of the attack, your ETH balance shouldn't have decreased.
Let’s start with the
puppet.challenge.js test file to observe how the challenge is set up:
In the snippet above, we initialize a new Uniswap factory and deploy DVL/ETH Liquidity Pool (LP). Next we deploy the target lending pool and pass it the address of the LP. Let’s take a look at the source for the lending pool to see how it uses the Uniswap pair:
The key element here is the
computeOraclePrice() function which calculates the current exchange rate by calculating the ETH to DVL ratio in the pool.
The price calculation does not take into the account that it may be possible to purchase a significant portion of ETH in the pool to significantly drop the price of DVL available for lending. Let’s experiment with this scenario and see just how much we can borrow with the following exploit script which tracks attacker, Uniswap, and lending pool accounts as well as the oracle price: