I am trying to compute a Uniswap v3 pool prize.

I can get the square root price of Q64.96 number as uint160 (e.g., 1234217676608908277512433764 - value of DAI/ETH pool (price at that time around 1 ETH for 4090 DAI)).

This can be retrieved via IUniswapV3PoolState.slot0()

As the function docstring says: "sqrtPriceX96 The current price of the pool as a sqrt(token1/token0) Q64.96 value"

How can I convert this number to uint256?

The calculated price should suggest the value of 1 ETH for 4090 DAI

Is there any other way of getting the Uniswap V3 pair price?

The answer would preferably be in solidity, but other answers are also acceptable.

Unsuccessful attempt

I tried squaring the number 1234217676608908277512433764 and then shifting it by 96, but the result was 1.922666416729829e+25 which doesn't seem too be correct.

(1234217676608908277512433764^2) >> 96 = 1.922666416729829e+25

    function getPrice(address tokenIn, address tokenOut)
        returns (uint256 price)
        IUniswapV3Pool pool = IUniswapV3Pool(factory.getPool(tokenIn, tokenOut, FEE);
        (uint160 sqrtPriceX96,,,,,,) =  pool.slot0();
        return uint(sqrtPriceX96).mul(uint(sqrtPriceX96)).mul(1e18) >> (96 * 2);

Returns spot price with 1e18 precision. Be careful to use spot price because it is a subject for a flash loan attacks. Either use TWAP price or check that price hasn't move much before using spot price. Also, I haven't tested this code for precision loss and upper/lower boundaries. Because Uniswap v3 use Q64.96 notion for decimals but it doesn't seem that practical. The output of the function is a number with e18 precision. It depends which decimal lib you use in your project.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.