Background on Oracle Attacks

Some of the largest hacks in the DeFi space are due to oracle attacks, which is when price feeds are manipulated (typically via flash loans) allowing for arbitrage opportunities. Popular examples of these attacks include Pancake Bunny, Yearn, and Harvest Finance. Below is a snippet from the Harvest page linked above which shows how the attack worked:

  1. Swap 11.4m USDC to USDT -> USDT price up
  2. Deposit 60.6m USDT into Vault
  3. Exchange 11.4m USDT to USDC -> USDT price down
  4. Withdraw 61.1m USDT from Vault -> 0.5m profit
The attacker was able to withdraw more USDT at step 4 because of the changed USDT price. As the price of USDT was lower during the time of the withdrawal, their shares represent more USDT from the Vault pool. This translated to around a 24 million dollar windfall at the expense of the Harvest vaults.

This article will describe in depth a slower oracle attack that occurred over a few days with a new AMM called Integral: the steps to create the opportunity and what the Integral team did to prevent the attacks. The whistles and bells of each oracle attack are unique, but the premise is the same: have a deep understanding of the oracle(s) to manipulate the price feeds and arbitrage the underlying.

Integral

Integral is a new AMM, which tries to improve on existing decentralized exchanges by combining parts of a centralized order book (from Binance) while using other Dexs as an oracle. The objective of Integral is to create more liquidity for the popular trading pairs with less slippage on block trades than both Uniswap and Binance. It accomplishes this claim by using a 5 minute Uniswap TWAP to get a base execution price and then skews the liquidity in the pool based on Binance order book depth. The exact details are beyond the scope of this article, but for all intensive purposes Integral prices are close to Uniswap v2 pool prices, however instead of a 30 basis point fee there is a 10 basis point fee for non-stable coin pairs and 2 basis point fee for stable coins and all trades take at least 5 minutes per trip On May 31st, Integral launched their stable coin pools and after substantially increasing the liquidity mining rewards, got around 10-20 million in their three stable pools $USDC-$USDT, $DAI-$USDT, and $DAI-$USDC.

Uniswap and Curve

While Uniswap V2 is a decent oracle for the non-stable coin pairs, it is a terrible oracle for stable coin pairs. Due to the constant-product formula for Uniswap, small amounts (relative to the pool size) of orders will cause large sized moves relative to other AMMs like Curve. The Curve Whitepaper does a good job of explaining the math behind the advantages and disadvantages of the constant-product formula and how they improve of it.

There is a pool which has coins X and Y with a fair value of $1 and in the pool there initially is 5 X coins and 5 Y coins. Here is basic walk through of the Uniswap price (assuming no fees) when there is a .1 X trade into the above pool and we get 0.098 Y out of the pool, which leaves the pool with 5.1 X and 4.902 Y. Given that it is a 50-50 pool, we get 5.1X = 4.902Y, and Y is around 1.04 X, a 4% change to the original 1:1 ratio for a 2% trade into the original pool.

\begin{align} x*y &= k\\ (x + \Delta x)(y - \Delta y) &= k\\ (5 + .1)(5 + \Delta y) &= 25\\ \Delta y &= 5-\frac{25}{5.1}\\ \Delta y &\approx -0.098\\ \text{where} & \\ x &= \text{Number of X tokens} \\ y &= \text{Number of y tokens} \\ \Delta x &= \text{Number of x tokens exchanged in pool} \\ \Delta y &= \text{Number of y tokens returned} \\ \end{align}

The details of the various AMM formulas will be covered in a different post, but for a more practical understanding, below is a plot from the paper comparing constant-price (also known as constant-sum) to Uniswap's constant-product, and finally to Curve which uses a hybrid approach. Going off the above pool which starts with 5 X coins and 5 Y coins, in the constant price variant the price of X and Y will always be $1, so when there is 9 X coins and 1 Y coin the price of each coin does not change. This is not true with the Uniswap version or the Curve version, as the Uniswap formula is most sensitive to price fluctuations, while the Curve version is in between the two.

Pelican

The Attack

Basically this oracle attack works because Uniswap V2 is a bad oracle for stable coins and stable coin liquidity providers wanted yield for their stables so they aped in without thinking of repercussions. If Uniswap V3 or curve were used as oracles instead, this attack would not work. Below is a complete trade setup with the relevant transactions:

  1. Swap small amount of DAI on DAI-USDT UniV2 -> USDT price up, Dai price down
  2. Swap large amount of USDT in DAI-USDT Integral
  3. Reswap USDT to DAI USDT to DAI on Curve, Uni V3
  4. Repeat
Using DAI-USDT as an example, an adversarial actor would take a small loss on the DAI-USDT Uni V2 pool and trade a much larger size on Integral to recoup the loss and book a profit. To complete the loop, either Uni V3, Curve, or other methods for cheap stablecoin swaps could be used. It is worth noting that this is different from the Harvest Finance attack above because flash loans cannot be used due to the 5 minute delay on Integral. There needs to be a substantial startup capital cost in order to churn a profit after gas fees.

In early June, there was about 20 million in DAI-USDC, 15 million in DAI-USDT, and 100 million in USDC-USDT (in the Uniswap V2 pools), so the easiest prices to manipulate would be DAI-USDC and DAI-USDT. A key to note is that the price of the stablecoin pools on Uni cannot be too much more than 30 bps (which is the Uniswap fee), because if they are off from other exchanges by more, arbitrageurs will do dex to dex arbs and move the spreads in line1. Fee wise it initially cost 2 bps for the integral pools and 4 bps on curve to swap back and the entire loop cost around 100 dollars in gas during this period, so profits were a little under 20 bps per trip. Due to the 5 minute oracle delay and transaction times, each trip took around 10 minutes.

The Response

Liquidity providers realized that they were slowly losing their stablecoins and started to complain on the discord.2 After a day the team issued an announcement on discord stating that they were aware of the problem and that they increased the trading fee from 2 bps to 4 bps. It is easy to see why this increase was inadequate as the edge was greater than the 2 bps fee increase and the attacked continued on. A day later, the team reraised the fee to 15 bps and then limited the trade size of the pools a few days after that effectively ending this oracle attack.

  1. Also aggregators like Matcha and 1inch route to the stable coin pools for random shitcoin trades a often times the stable coin pools are an intermediate step.
  2. Join Integral discord with this link

Published

Category

Crypto

Tags

Contact