DEV Community

MY ZT
MY ZT

Posted on β€’ Edited on

Uniswap V3 notes

uniswap-v3.md

Intro

Image description

concentrated liquidity

Image description

concentrated liquidity is to add liquidity for a certain price ranges.

  • The concentrated liquidity provision is similar to the "pending order", when the market price enters the user-set range, the liquidity will be automatically swapped.
  • This mechanism allows LP to use capital more efficiently while "trading passively".

position = liquidity concentrated in a price range

The way that the price is stored inside Uniswap V3 is by this formula:

Image description

liquidity price graph

Image description

This graph represents the liquidity at each price, and at each price, liquidity is calculated by stacking up all of the position that overlaps with the price.

Image description

To the left of the current price, all of the liquidity is in Token Y(USDC), And to the right of the current price,liquidity is all in token X.

Image description

If the price range you set does not include the current price, you can only add one token

V3 Contracts

Image description

Now this Swap Router02 Contract has been upgraded to another
contract inside the repository Uniswap Router. This Uniswap Router Contract is a more comprehensive contract that will allow you to swap between Uniswap V2, V3, and some NFTs.

When call the function in V3pool, the caller must also be a smart contract.

Spot Price

Because there may be multiple positions in different price ranges, you cannot just simply take the amount of token Y and the amount of token X in the contract to figure out what the spot price is.

in uniswap V3 opposite of V2, it no longer keeps track of the amount of reserves, Instead, it keeps track of the current price, and from the current price, if we know the liquidity and the price ranges, then we can calculate the amount of tokens that must be locked in those price range.

price and tick

Use one of sartPricex96 and tick can calculate the spot price.

IUniswapV3Pool.Slot0 memory slot0 = pool.slot0();
// 1 / P = X / Y = USDC / WETH
//               = price of WETH in terms of USDC

// P has 1e18 / 1e6 = 1e12 decimals
// 1 / P has 1e6 / 1e18 = 1e-12 decimals

// sqrtPriceX96 * sqrtPriceX96 might overflow
// So use FullMath.mulDiv to do uint256 * uint256 / uint256 without overflow

// price = sqrt(P) * Q96 * sqrt(P) * Q96 / Q96
price = FullMath.mulDiv(slot0.sqrtPriceX96, slot0.sqrtPriceX96, Q96);
// 1 / price = 1 / (P * Q96)
price = 1e12 * 1e18 * Q96 / price;
Enter fullscreen mode Exit fullscreen mode

Math

Image description

equation for x and y from liquidity and price.

curve of real reserves

Image description

Q1: what is the +/- dx or dy after price change?

    /// @return amount0 Amount of currency0 required to cover a position of size liquidity between the two passed prices
    function getAmount0Delta(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity,
        bool roundUp
    ) internal pure returns (uint256 amount0)

    /// @return amount1 Amount of currency1 required to cover a position of size liquidity between the two passed prices
    function getAmount1Delta(
        uint160 sqrtRatioAX96,
        uint160 sqrtRatioBX96,
        uint128 liquidity,
        bool roundUp
    ) internal pure returns (uint256 amount1)
Enter fullscreen mode Exit fullscreen mode

Price Delta

Image description

Q2: what is the price change after +/- dx or dy?

    /// @notice Gets the next sqrt price given an input amount of currency0 or currency1
    /// @dev Throws if price or liquidity are 0, or if the next price is out of bounds
    /// @param sqrtPX96 The starting price, i.e., before accounting for the input amount
    /// @param liquidity The amount of usable liquidity
    /// @param amountIn How much of currency0, or currency1, is being swapped in
    /// @param zeroForOne Whether the amount in is currency0 or currency1
    /// @return sqrtQX96 The price after adding the input amount to currency0 or currency1
    function getNextSqrtPriceFromInput(
        uint160 sqrtPX96,
        uint128 liquidity,
        uint256 amountIn,
        bool zeroForOne
    ) internal pure returns (uint160 sqrtQX96)

    function getNextSqrtPriceFromOutput(
        uint160 sqrtPX96,
        uint128 liquidity,
        uint256 amountOut,
        bool zeroForOne
    ) internal pure returns (uint160 sqrtQX96)
Enter fullscreen mode Exit fullscreen mode

Image description

Q3: what is the liquidity after +/- dx or dy?

liquidity net

Image description

The pink number is the liquidity net.

To this current liquidity 13, we add [(+1)*(-10)] -> [direction*liquidity net] So the active liquidity when the current tick crosses over this tick(-10), must be equal to three.

This was an example of how liquidity nets that are stored at the ticks keep track of the current liquidity. Every time the current tick crosses over one of these ticks, it will either add or minus some liquidity net to update the current liquidity.

Swap fee

Tick Bitmap

when you do a trade how does uniswap find the next position?

it finds the next position is by recording the position stick lower and tick upper in a mapping called tick bitmap.

tick bitmap

Image description

tick bitmap is a mapping(From int16 to uint256) that stores the ticks that define the liquidity position.

tick

a tick basically is an int24 that splits into int16(key) and uint8(value).

How to get tick from bitmap

access the key fill up the first 16 bits access the index and then fill up the last 8 Bits.

flip a tick

Image description

How to get Next tick

Image description

Top comments (0)

πŸ‘‹ Kindness is contagious

Please consider leaving a ❀️ or a kind comment on this post if it was useful to you!

Thanks!