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

Incorporate new optimizations #16

Merged
merged 13 commits into from
Jun 28, 2023
53 changes: 27 additions & 26 deletions .gas-snapshot
Original file line number Diff line number Diff line change
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, μ: 61620, ~: 61625)
TickBitmapTest:testFuzz_NextInitializedTickWithinOneWord(int24,uint8,bool) (runs: 65536, μ: 68053, ~: 68127)
TickBitmapTest:testFuzz_Position(int24) (runs: 65536, μ: 492, ~: 492)
TickBitmapTest:testGas_NextInitializedTickWithinOneWord() (gas: 6798523)
TickBitmapTest:testGas_NextInitializedTickWithinOneWord_Og() (gas: 7062020)
TickBitmapTest:test_NextInitializedTickWithinOneWord_GT() (gas: 204689)
TickBitmapTest:test_NextInitializedTickWithinOneWord_LTE() (gas: 216895)
TickBitmapTest:test_NextInitializedTick_GT() (gas: 359219)
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)
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
[![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. The `uni-v3-lib` is currently in use by
Aperture's [liquidity position automation contract](https://github.com/Aperture-Finance/core-contracts), the audit
gaohan137 marked this conversation as resolved.
Show resolved Hide resolved
report of which can be
found [here](https://github.com/NaryaAI/publications/blob/1468e568712d5e2aa9b0ecde0a16d3f9f1d715ef/Aperture%20UniV3Automan%20Report.pdf).

## Overview

Expand All @@ -29,12 +32,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