Uniswap v3

Deploying idle collateral to stable-stable pairs on Uni v3 with FRAX

The key innovation of Uniswap v3's AMM algorithm allowing for LPs to deploy liquidity between specific price ranges allows for stablecoin-to-stablecoin pairs (e.g. FRAX-USDC) to accrue extremely deep liquidity within a tight peg. Compared to Uniswap v2, range orders in Uniswap v3 concentrate the liquidity instead of spreading out over an infinite price range.

Taken from the Uniswap v3 whitepaper

The Uniswap v3 Liquidity AMO puts FRAX and collateral to work by providing liquidity to other stablecoins against FRAX. Since the AMO is able enter any position on Uni v3 and mint FRAX against it, it allows for expansion to any other stablecoin and later volatile collateral on Uni v3. Additionally, the function collectFees() can be periodically called to allocate AMO profits to market operations of excess collateral.

AMO Specs

  1. Decollateralize - Deposits idle collateral and newly minted FRAX into the a Uni v3 pair.

  2. Market operations - Accrues Uni v3 transaction fees and swaps between collateral types.

  3. Recollateralize - Withdraws from the Uni v3 pairs, burns FRAX and returns USDC to increase CR.

  4. FXS1559 - Daily transaction fees accrued over the CR.


A diagram showing range-order virtualized reserves using the constant-product invariant

All prices exist as ratios between one entity and another. Conventially, we select a currency as the shared unit-of-account in the denominator (e.g. USD) to compare prices for everyday goods and services. In Uniswap, prices are defined by the ratio of the amounts of reserves of xx to reserves of yy in the pool.

Uniswap v3's range-order mechanic fits into the existing xy=kx*y = k constant-product market-making invariant (CPMM) by "virtualizing" the reserves at a specific price point, or tick. Through specifying which ticks a liquidity position is bounded by, range-orders are created that follow the constant-product invariant without having to spread the liquidity across the entire range(0,)(0, \infty)for a specific asset.

A price in Uniswap v3 is defined by the value 1.0001 to the tick value ii. The boundaries for the prices of ticks can be represented by the algebraic group G={giiZ,g=1.0001}G = \{ g^i \mid i \in \mathbb{Z}, g = 1.0001\}. This mechanism allows for easy conversion of integers to price boundaries, and has the convenience of discretiating each tick-price-boundary as one basis point (0.01%) in price from another.

Defining price in terms of ticks

Virtual reserves are tracked by tracking the liquidity and tick bounds of each position. Crossing a tick boundary, the liquidity LL available for that tick may change to reflect positions entering and leaving their respective price ranges. Within the tick boundaries, swaps change the price P\sqrt{P} according to the virtual reserves, i.e. it acts like the constant-product (xy=k x*y=k) invariant. The virtual reserves x and y can be calculated from the liquidity and price:

L: Liquidity; P: Price; x, y: reserves of X and Y

Note that the actual implementation uses a square root of the price, since it saves a square-root operation from calculating intra-tick swaps, and thus helps prevent rounding errors.

Converting price to square root of ticks

Liquidity can be thought of as a virtual kk in the xy=kx*y=k CPMM, while ΔY\Delta Y corresponds to amount of asset YY and ΔP\Delta\sqrt P represents the intra-tick price slippage.

Describing the relationship between liquidity, price, and the amount of one asset swapped

Since LL is fixed for intra-tick swaps, ΔX\Delta X and ΔY\Delta Y can be calculated from the liquidity and square root of the price. When crossing over a tick, the swap must only slip until the P\sqrt P boundary, and then re-adjust the liquidity available for the next tick.

Liquidity AMO

The Uniswap v3 Liquidity AMO (stable-stable) contract is deployed at: 0x3814307b86b54b1d8e7B2Ac34662De9125F8f4E6