Why does Uniswap use Q notation versus the uint256 ratio price? A price in uniswap is always in token1/token0. Which token is which depends on the hex value assigned by the contract address when it's created.

(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);

So for example the WETH-USDC pool on ethereum the addresses are

> (WETH) 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 > (USDC) 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 

So WETH is token 1.

The best documentation I've found on the topic is in this article https://blog.uniswap.org/uniswap-v3-math-primer which states

Q notation specifies the parameters of the binary fixed point number format, which allows variables to remain integers, but function similarly to floating point numbers. Variables that must be as precise as possible in Uniswap v3 are represented with a maximum of 256 bits and account both for overflow and potential rounding issues. By using Q notation, the protocol can ensure that granular decimal precision is not lost.

My thoughts

The only upside I see, assuming that ratios have to be calculated in token1/token0 at some point and don't risk overflows as a result, is that when you store this variable which is a uinit160 (sqrtPriceX96) in a struct it takes less space and thus uses less gas than the full uint256.

And if you're not using the struct you're not gaining much of anything by using a smaller value, in fact you may even be spending more gas as seen from this stack post

"The EVM works with 256bit/32byte words (debatable design decision). Every operation is based on these base units. If your data is smaller, further operations are needed to downscale from 256 bits to 8 bits, hence why you see increased costs."

Why does uint8 cost more gas than uint256?

If someone can confirm that's the case it would be very helpful.

  • Are you comparing the usage of uint160 vs uint256 in this specific case or the usage of Q notation? uint160 as you mentioned would be beneficial for the packing of struct. Q notation allows for higher precision.
    – Maanas O T
    Apr 28, 2023 at 3:17
  • I became curious about this because I'm computing twap with uniswap on chain. I'm allowing a specified amount of slippage from that twap to consider a trade valid. So for example I'm pulling twap and converting to the lowest decimal uint256 form because that's the only form that I can mult by say 98/100. I can't do that on sqrtPriceX96 for obvious reasons. So I'm curious as to why the ratio isn't just stored like that to begin with versus this alternative approach or if the gas savings is the only reason. If they're represented with max 256 bits why not use that to begin with.
    – Nat
    Apr 28, 2023 at 10:38

1 Answer 1


Uniswap utilizes a fixed-point number representation(Q-notation) to achieve a higher precision.

sqrtX96 means that the variable has been multiplied by 2**96 to guarantee 96 bits of precision during the computation.

Multiplying a variable by 2**96 is equivalent to shifting its bits to the left by 96 bits. During the computation, the variable now have 96 more bits with express its value. The added 96 bits will be lost in the end when the variable is divided by 2**96(shifting right 96 bits), but the added precision has been reflected to the final value.

If uint256 is used instead, some amount of precision will be lost on every step of the computation. This is because in Solidity division rounds towards zero. While the computation with fixed-point number also loses some precision, it's 96 bits more precise when compared to that of uint256.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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