Skip to content

Commit

Permalink
Incorporate new optimizations (#16)
Browse files Browse the repository at this point in the history
* Optimize `getNextSqrtPriceFromAmount0RoundingUp`

* Refactor

* Refactor and optimize `TickMath`

* Update README and version

* Refactor and optimize `SwapMath`

* Consistent license

* Update version and dependencies

* Update .gas-snapshot

* Polish `TickBitmap`

* Add comments and reference

* Update src/TickBitmap.sol

Co-authored-by: while1 <gaohan137@gmail.com>

* Resolve review comments

* Remove duplicate

---------

Co-authored-by: while1 <gaohan137@gmail.com>
  • Loading branch information
shuhuiluo and gaohan137 authored Jun 28, 2023
1 parent 6dd701e commit f5d0bfb
Show file tree
Hide file tree
Showing 15 changed files with 3,117 additions and 3,002 deletions.
57 changes: 29 additions & 28 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BitMathTest:testFuzz_LSB(uint256) (runs: 65536, μ: 14926, ~: 14924)
BitMathTest:testFuzz_LSB(uint256) (runs: 65536, μ: 14923, ~: 14921)
BitMathTest:testFuzz_MSB(uint256) (runs: 65536, μ: 14798, ~: 14822)
BitMathTest:testGas_LSB() (gas: 211488)
BitMathTest:testGas_LSB() (gas: 210723)
BitMathTest:testGas_LSB_Og() (gas: 303324)
BitMathTest:testGas_MSB() (gas: 229272)
BitMathTest:testGas_MSB_Og() (gas: 286673)
Expand Down Expand Up @@ -63,45 +63,46 @@ PoolCallerTest:test_Slot0() (gas: 13245)
PoolCallerTest:test_SqrtPriceX96AndTick() (gas: 9731)
PoolCallerTest:test_Swap() (gas: 322383)
PoolCallerTest:test_TickSpacing() (gas: 8242)
SqrtPriceMathTest:testFuzz_GetAmount0Delta(uint160,uint160,int128) (runs: 65536, μ: 12876, ~: 12589)
SqrtPriceMathTest:testFuzz_GetAmount0Delta(uint160,uint160,uint128,bool) (runs: 65536, μ: 12550, ~: 12262)
SqrtPriceMathTest:testFuzz_GetAmount0Delta(uint160,uint160,int128) (runs: 65536, μ: 12877, ~: 12598)
SqrtPriceMathTest:testFuzz_GetAmount0Delta(uint160,uint160,uint128,bool) (runs: 65536, μ: 12552, ~: 12262)
SqrtPriceMathTest:testFuzz_GetAmount1Delta(uint160,uint160,int128) (runs: 65536, μ: 12483, ~: 12405)
SqrtPriceMathTest:testFuzz_GetAmount1Delta(uint160,uint160,uint128,bool) (runs: 65536, μ: 12498, ~: 12432)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromAmount0RoundingUp(uint160,uint128,uint256,bool) (runs: 65536, μ: 16972, ~: 17536)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromAmount1RoundingDown(uint160,uint128,uint256,bool) (runs: 65536, μ: 19491, ~: 20148)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromInput(uint160,uint128,uint256,bool) (runs: 65536, μ: 13293, ~: 12479)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromOutput(uint160,uint128,uint256,bool) (runs: 65536, μ: 13854, ~: 14333)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromAmount0RoundingUp(uint160,uint128,uint256,bool) (runs: 65536, μ: 16963, ~: 17522)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromAmount1RoundingDown(uint160,uint128,uint256,bool) (runs: 65536, μ: 19498, ~: 20148)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromInput(uint160,uint128,uint256,bool) (runs: 65536, μ: 13295, ~: 12479)
SqrtPriceMathTest:testFuzz_GetNextSqrtPriceFromOutput(uint160,uint128,uint256,bool) (runs: 65536, μ: 13847, ~: 14333)
SqrtPriceMathTest:testGas_GetAmount0Delta() (gas: 266947)
SqrtPriceMathTest:testGas_GetAmount0Delta_Og() (gas: 285432)
SqrtPriceMathTest:testGas_GetAmount1Delta() (gas: 219187)
SqrtPriceMathTest:testGas_GetAmount1Delta_Og() (gas: 273563)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromInput() (gas: 238690)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromInput_Og() (gas: 248813)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromOutput() (gas: 222831)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromOutput() (gas: 221981)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromOutput_Og() (gas: 229995)
SwapMathTest:testFuzz_ComputeSwapStep(uint160,uint160,uint128,int256,uint24) (runs: 65536, μ: 22502, ~: 22582)
SwapMathTest:testFuzz_ComputeSwapStepExactIn(uint160,uint160,uint128,uint256,uint24) (runs: 65536, μ: 23662, ~: 23680)
SwapMathTest:testFuzz_ComputeSwapStepExactOut(uint160,uint160,uint128,uint256,uint24) (runs: 65536, μ: 22998, ~: 22891)
SwapMathTest:testGas_ComputeSwapStep() (gas: 430173)
SwapMathTest:testGas_ComputeSwapStepExactIn() (gas: 404912)
SwapMathTest:testFuzz_ComputeSwapStep(uint160,uint160,uint128,int256,uint24) (runs: 65536, μ: 22165, ~: 22284)
SwapMathTest:testFuzz_ComputeSwapStepExactIn(uint160,uint160,uint128,uint256,uint24) (runs: 65536, μ: 23660, ~: 23677)
SwapMathTest:testFuzz_ComputeSwapStepExactOut(uint160,uint160,uint128,uint256,uint24) (runs: 65536, μ: 22994, ~: 22888)
SwapMathTest:testGas_ComputeSwapStep() (gas: 395439)
SwapMathTest:testGas_ComputeSwapStepExactIn() (gas: 404612)
SwapMathTest:testGas_ComputeSwapStepExactIn_Og() (gas: 520633)
SwapMathTest:testGas_ComputeSwapStepExactOut() (gas: 380584)
SwapMathTest:testGas_ComputeSwapStepExactOut_Og() (gas: 515145)
SwapMathTest:testGas_ComputeSwapStep_Og() (gas: 531437)
TickBitmapTest:testFuzz_Compress(int24,int24) (runs: 65536, μ: 8388, ~: 8448)
TickBitmapTest:testFuzz_FlipTick(int24) (runs: 65536, μ: 61598, ~: 61603)
TickBitmapTest:testFuzz_NextInitializedTickWithinOneWord(int24,uint8,bool) (runs: 65536, μ: 68031, ~: 68105)
TickBitmapTest:testGas_NextInitializedTickWithinOneWord() (gas: 6798501)
TickBitmapTest:testGas_NextInitializedTickWithinOneWord_Og() (gas: 7061998)
TickBitmapTest:test_NextInitializedTickWithinOneWord_GT() (gas: 204667)
TickBitmapTest:test_NextInitializedTickWithinOneWord_LTE() (gas: 216873)
TickBitmapTest:test_NextInitializedTick_GT() (gas: 359197)
TickBitmapTest:testFuzz_Compress(int24,int24) (runs: 65536, μ: 8410, ~: 8470)
TickBitmapTest:testFuzz_FlipTick(int24) (runs: 65536, μ: 61621, ~: 61625)
TickBitmapTest:testFuzz_NextInitializedTickWithinOneWord(int24,uint8,bool) (runs: 65536, μ: 68049, ~: 68124)
TickBitmapTest:testFuzz_Position(int24) (runs: 65536, μ: 492, ~: 492)
TickBitmapTest:testGas_NextInitializedTickWithinOneWord() (gas: 6795963)
TickBitmapTest:testGas_NextInitializedTickWithinOneWord_Og() (gas: 7062020)
TickBitmapTest:test_NextInitializedTickWithinOneWord_GT() (gas: 203665)
TickBitmapTest:test_NextInitializedTickWithinOneWord_LTE() (gas: 216895)
TickBitmapTest:test_NextInitializedTick_GT() (gas: 357171)
TickBitmapTest:test_NextInitializedTick_LTE() (gas: 409484)
TickMathTest:testFuzz_GetSqrtRatioAtTick(int24) (runs: 65536, μ: 16630, ~: 16910)
TickMathTest:testFuzz_GetTickAtSqrtRatio(uint160) (runs: 65536, μ: 13244, ~: 13256)
TickMathTest:testGas_GetSqrtRatioAtTick() (gas: 147560)
TickMathTest:testFuzz_GetSqrtRatioAtTick(int24) (runs: 65536, μ: 16567, ~: 16847)
TickMathTest:testFuzz_GetTickAtSqrtRatio(uint160) (runs: 65536, μ: 13177, ~: 13193)
TickMathTest:testGas_GetSqrtRatioAtTick() (gas: 148160)
TickMathTest:testGas_GetSqrtRatioAtTick_Og() (gas: 168533)
TickMathTest:testGas_GetTickAtSqrtRatio() (gas: 260917)
TickMathTest:testGas_GetTickAtSqrtRatio() (gas: 255519)
TickMathTest:testGas_GetTickAtSqrtRatio_Og() (gas: 307781)
TickMathTest:testRevert_GetSqrtRatioAtTick() (gas: 10455)
TickMathTest:testRevert_GetTickAtSqrtRatio() (gas: 10555)
TickMathTest:testRevert_GetSqrtRatioAtTick() (gas: 10467)
TickMathTest:testRevert_GetTickAtSqrtRatio() (gas: 10531)
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
[![Test](https://github.com/Aperture-Finance/uni-v3-lib/actions/workflows/test.yml/badge.svg)](https://github.com/Aperture-Finance/uni-v3-lib/actions/workflows/test.yml)
[![npm version](https://img.shields.io/npm/v/@aperture_finance/uni-v3-lib/latest.svg)](https://www.npmjs.com/package/@aperture_finance/uni-v3-lib/v/latest)

The `uni-v3-lib` by Aperture Finance is a suite of Solidity libraries that have been imported and rewritten from
Uniswap's [v3-core](https://github.com/Uniswap/v3-core) and [v3-periphery](https://github.com/Uniswap/v3-periphery)
repositories. The goal of this project is to provide external integrators with a set of libraries that are crucial for
interaction with the Uniswap V3 protocol.
The `uni-v3-lib` by Aperture Finance consists of a suite of Solidity libraries that have been imported and rewritten
from Uniswap's [v3-core](https://github.com/Uniswap/v3-core) and [v3-periphery](https://github.com/Uniswap/v3-periphery)
repositories. This project aims to equip external integrators with a set of libraries crucial for interaction with the
Uniswap V3 protocol.

## Overview

Expand All @@ -29,12 +29,12 @@ heuristics and techniques are documented by extensive annotations in the source
| SqrtPriceMath | testGas_GetAmount0Delta | 285432 | 266947 | 6.47% |
| SqrtPriceMath | testGas_GetAmount1Delta | 273563 | 219187 | 19.88% |
| SwapMath | testGas_ComputeSwapStep | 531437 | 430173 | 19.03% |
| TickMath | testGas_GetSqrtRatioAtTick | 168533 | 147560 | 12.45% |
| TickMath | testGas_GetTickAtSqrtRatio | 307781 | 260917 | 15.24% |
| TickMath | testGas_GetSqrtRatioAtTick | 168533 | 148160 | 12.09% |
| TickMath | testGas_GetTickAtSqrtRatio | 307781 | 255519 | 16.98% |

The gas measured is the total gas used by the test transaction, including the gas used to call the test wrapper
*The gas measured is the total gas used by the test transaction, including the gas used to call the test wrapper
contract. The actual percentage difference in gas for the internal library functions is higher than the numbers shown
above.
above.*

## Libraries

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@aperture_finance/uni-v3-lib",
"description": "A suite of Solidity libraries that have been imported and rewritten from Uniswap's v3-core and v3-periphery",
"version": "1.0.3",
"version": "1.1.0",
"author": "Aperture Finance",
"homepage": "https://aperture.finance/",
"license": "GPL-2.0-or-later",
Expand Down Expand Up @@ -32,14 +32,14 @@
"prettier:fix": "prettier -w {src,test}/**/*.sol"
},
"dependencies": {
"@openzeppelin/contracts": "^4.9.0",
"@openzeppelin/contracts": "^4.9.2",
"@uniswap/v3-core": "^1.0.1",
"@uniswap/v3-periphery": "^1.4.3",
"solady": "^0.0.101"
},
"devDependencies": {
"@nomicfoundation/hardhat-foundry": "^1.0.1",
"hardhat": "^2.14.1",
"hardhat": "^2.15.0",
"prettier": "^2.8.8",
"prettier-plugin-solidity": "^1.1.3",
"ts-node": "^10.9.1",
Expand Down
12 changes: 10 additions & 2 deletions src/BitMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ library BitMath {
/// @return r the index of the most significant bit
function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
assembly {
// r = x >= 2**128 ? 128 : 0
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
// r += (x >> r) >= 2**64 ? 64 : 0
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
// r += (x >> r) >= 2**32 ? 32 : 0
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))

// For the remaining 32 bits, use a De Bruijn lookup.
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
x := shr(r, x)
x := or(x, shr(1, x))
x := or(x, shr(2, x))
Expand All @@ -46,14 +50,18 @@ library BitMath {
/// @return r the index of the least significant bit
function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
assembly {
// Isolate the least significant bit.
x := and(x, add(not(x), 1))
// Isolate the least significant bit, x = x & -x = x & (~x + 1)
x := and(x, sub(0, x))

// r = x >= 2**128 ? 128 : 0
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
// r += (x >> r) >= 2**64 ? 64 : 0
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
// r += (x >> r) >= 2**32 ? 32 : 0
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))

// For the remaining 32 bits, use a De Bruijn lookup.
// https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
r := or(
r,
byte(
Expand Down
2 changes: 1 addition & 1 deletion src/NPMCaller.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
Expand Down
2 changes: 1 addition & 1 deletion src/PoolCaller.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-License-Identifier: GPL-2.0-or-later
// User defined value types are introduced in Solidity v0.8.8.
// https://blog.soliditylang.org/2021/09/27/user-defined-value-types/
pragma solidity >=0.8.8;
Expand Down
Loading

0 comments on commit f5d0bfb

Please sign in to comment.