Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize TickMath bounds check in assembly #669

Merged
merged 5 commits into from
May 21, 2024

Conversation

shuhuiluo
Copy link
Contributor

@shuhuiluo shuhuiluo commented May 18, 2024

Factored out of #273.

Related Issue

Which issue does this pull request resolve?

Description of changes

A trick to perform bounds check on fixed bounds has been introduced in TickMath. A new constant

MAX_SQRT_PRICE_MINUS_MIN_SQRT_PRICE_MINUS_ONE = MAX_SQRT_PRICE - MIN_SQRT_PRICE - 1;

was also introduced to facilitate the check. In getTickAtSqrtPrice, it is required that MIN_SQRT_PRICE <= sqrtPriceX96 < MAX_SQRT_PRICE.

  • If sqrtPriceX96 < MIN_SQRT_PRICE, sqrtPriceX96 - MIN_SQRT_PRICE underflows so sqrtPriceX96 - MIN_SQRT_PRICE > MAX_SQRT_PRICE_MINUS_MIN_SQRT_PRICE_MINUS_ONE is true.
  • If sqrtPriceX96 >= MAX_SQRT_PRICE, sqrtPriceX96 - MIN_SQRT_PRICE > MAX_SQRT_PRICE_MINUS_MIN_SQRT_PRICE_MINUS_ONE is also true.

Therefore, the bounds check reduces to

gt(sub(sqrtPriceX96, MIN_SQRT_PRICE), MAX_SQRT_PRICE_MINUS_MIN_SQRT_PRICE_MINUS_ONE)

A new constant, MAX_SQRT_PRICE_MINUS_MIN_SQRT_PRICE_MINUS_ONE, is introduced for efficient bounds checking. The getTickAtSqrtPrice function is further optimized by using assembly-level operations for checking boundary conditions, which enhances the overall performance. It keeps the price within the specified bounds and throws an "InvalidSqrtPrice" error if the price is out of range.
Updated the MAX_TICK constant value from `-MIN_TICK` to `887272` in TickMath.sol. Enhanced safety check within `getSqrtPriceAtTick` function, replacing previous condition with an assembly block to add memory-safe verification. The new check reverts with `InvalidTick()` if the absolute value of `tick` exceeds `MAX_TICK`.
This commit adds fuzz tests in the `TickMath` test suite to verify that an exception is thrown when exceeding the allowed tick and square root price ranges. The test cases are designed to provide random values that exceed the range of values that the functions `getSqrtPriceAtTick` and `getTickAtSqrtPrice` can operate on without errors.
@hensha256 hensha256 merged commit c32b28b into Uniswap:main May 21, 2024
5 of 6 checks passed
@shuhuiluo shuhuiluo deleted the get-tick-at-sqrt-price-0 branch May 21, 2024 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants