In TickMath.sol of v3-core codebase, getSqrtRatioAtTick(int24 tick) implements \sqrt{1.0001}^n with binary fixed point arithmetics in Q128 and down casts to Q96.

With a lookup table of Q128 entries \sqrt{1.0001^-1}^{0b1}, \sqrt{1.0001^-1}^{0b10}, ..., the input tick is split into several terms multiplied together. The negative exponent is chosen to avoid overflow and the reciprocal is taken in the end for positive inputs.

My Question

I have trouble reproducing the exact constants of \sqrt{1/1.0001}^n defined in the contract. What I've tried is to precompute in IEEE-754 doubles and convert them back to Q128 in python, as in:

>>> int(1/math.sqrt(1.0001) * 2**128)
>>> 0xfffcb933bd6fad37aa2d162d1a594001

As you can see the result deviates the hexadecimal value 0xfffcb933bd6fad37aa2d162d1a594001 provided in TickMath.sol for n=1. My guess is it's due to precision loss and there must be some numerical methods to derive those exact values.

Hope to get some guidances here. Thank you.

  • 2
    It's a good question, I'm not sure if anyone outside Uniswap knows exactly where the constants came from. There is a version of getSqrtRatioAtTick in the Panoptic repository that apparently has accurate value, in the comments: github.com/panoptic-labs/panoptic-v1-core/blob/main/contracts/…
    – kfx
    Commented Mar 28 at 11:50
  • @kfx Thanks for the info!
    – scad
    Commented Mar 28 at 12:36


Your Answer

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

Browse other questions tagged or ask your own question.