Oracle Manipulation 101 (Math edition)

This article is divided into two.

In the first part, we will present a quick refresher on how Uniswap works specifically tailored to the needs of computing manipulation costs. It'll explore how to move the spot price in an AMM to the desired target for Uniswap v2 and v3.

The second part will show how we obtained the results from the "Oracle Manipulation 101" article. To do so, we will present step-by-step an attack of a lending protocol in DeFi. This case can be later generalized to different types of markets.

You can follow along with the simulations provided in this colab.

Uniswap Math

There are many great resources on the topic of Uniswap. We will show some definitions and then present new results for price manipulation in Uniswap v3.

Full Range and Uniswap v2

Let's begin by looking at Uniswap v2 AMMs, equivalent to a Full Range position in Uniswap v3. Note that we'll confirm this below.

Basic equations

Two different tokens' balance forms each "pool". Users can add balance to these pools and later remove it. Let's call $x$ the balance of token A and $y$ the balance of token B. The following equation gives the relationship among these balances:

$x*y=L^2 \hspace{1cm}(1)$

where $L$ is called Liquidity. This $L$ is modified only when someone adds or removes the token balance and is constant otherwise.

https://i.imgur.com/zdwwOgV.png

Anyone can swap token A for token B or vice versa on this pool, modifying the balances $x$ and $y$ in the pool according to $(1)$. You can visualize this behaviour in the Figure (source).

We can compute the price of token A relative to token B at which anyone buys tokens from any AMM (not only constant product type) as

$P_{A/B}=-\frac{dy}{dx} \hspace{1cm}(2)$

The way to think about this formula is to picture a user selling a quantity $dx$ of token A to the pool. The pool reserve will increase $dx$ for token A while decreasing $-dy$ for token B. The ratio will yield the price at which the user sold their token A amount. This paper explains how Eq. $(2)$ and an invariant are all we need to build an AMM.

From $(1)$ we have $y=\frac{L^2}{x}$. Then

$P_{A/B}=-\frac{d}{dx}(\frac{L^2}{x})=\frac{L^2}{x^2} =\frac{y}{x} \hspace{1cm} (3)$

The price for Uniswap v2 pools can be computed as the ratio among the balances of the two tokens. So, for instance, if the WETH/USDC pool has $2$ WETH and $4000$ USDC, the price of WETH can be computed as $P_{WETH/USDC} = \frac{4000}{2}=2000$. This expression is, of course, symmetrical to the exchange of labelling, so to compute the price of USDC relative to WETH in the previous example, we invert the equation $(3)$: