From 91b3b202c05c94c0b21a775ea10588f4828c4c94 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 23 Jun 2024 14:18:38 +0400 Subject: [PATCH 1/2] unchecked slot0 interface --- .../IUniswapV3PoolSlot0Unchecked.sol | 18 +++++++++++++++++ contracts/libraries/QuoterMath.sol | 18 ++--------------- script/Quoter.s.sol | 20 +++++++++---------- 3 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol diff --git a/contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol b/contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol new file mode 100644 index 0000000..296e1a5 --- /dev/null +++ b/contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.7.6; +pragma abicoder v2; + +interface IUniswapV3PoolSlot0Unchecked { + function slot0() + external + view + returns ( + uint160 sqrtPriceX96, + int24 tick, + uint256 observationIndex, + uint256 observationCardinality, + uint256 observationCardinalityNext, + uint256 feeProtocol, + bool unlocked + ); +} diff --git a/contracts/libraries/QuoterMath.sol b/contracts/libraries/QuoterMath.sol index 2e9f831..553ce86 100644 --- a/contracts/libraries/QuoterMath.sol +++ b/contracts/libraries/QuoterMath.sol @@ -3,6 +3,7 @@ pragma solidity ^0.7.6; pragma abicoder v2; import {IUniswapV3Pool} from "v3-core/contracts/interfaces/IUniswapV3Pool.sol"; +import {IUniswapV3PoolSlot0Unchecked} from "../interfaces/IUniswapV3PoolSlot0Unchecked.sol"; import {IQuoter} from "../interfaces/IQuoter.sol"; import {SwapMath} from "v3-core/contracts/libraries/SwapMath.sol"; import {FullMath} from "v3-core/contracts/libraries/FullMath.sol"; @@ -39,27 +40,12 @@ library QuoterMath { } function fillSlot0(IUniswapV3Pool pool) private view returns (Slot0 memory slot0) { - (slot0.sqrtPriceX96, slot0.tick,,,,,) = pool.slot0(); + (slot0.sqrtPriceX96, slot0.tick,,,,,) = IUniswapV3PoolSlot0Unchecked(address(pool)).slot0(); slot0.tickSpacing = pool.tickSpacing(); return slot0; } - struct SwapCache { - // the protocol fee for the input token - uint8 feeProtocol; - // liquidity at the beginning of the swap - uint128 liquidityStart; - // the timestamp of the current block - uint32 blockTimestamp; - // the current value of the tick accumulator, computed only if we cross an initialized tick - int56 tickCumulative; - // the current value of seconds per liquidity accumulator, computed only if we cross an initialized tick - uint160 secondsPerLiquidityCumulativeX128; - // whether we've computed and cached the above two accumulators - bool computedLatestObservation; - } - // the top level state of the swap, the results of which are recorded in storage at the end struct SwapState { // the amount remaining to be swapped in/out of the input/output asset diff --git a/script/Quoter.s.sol b/script/Quoter.s.sol index 270f482..c3cc740 100644 --- a/script/Quoter.s.sol +++ b/script/Quoter.s.sol @@ -24,34 +24,34 @@ contract MyScript is Script { // base chain if (chainId == uint256(8453)) { return 0x33128a8fC17869897dcE68Ed026d694621f6FDfD; - // celo chain + // celo chain } else if (chainId == uint256(42220)) { return 0xAfE208a311B21f13EF87E33A90049fC17A7acDEc; - // bsc chain + // bsc chain } else if (chainId == uint256(56)) { return 0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7; - // optimism sepolia chain + // optimism sepolia chain } else if (chainId == uint256(11155420)) { return 0x8CE191193D15ea94e11d327b4c7ad8bbE520f6aF; - // arbitrum sepolia chain + // arbitrum sepolia chain } else if (chainId == uint256(421614)) { return 0x248AB79Bbb9bC29bB72f7Cd42F17e054Fc40188e; - // sepolia chain + // sepolia chain } else if (chainId == uint256(11155111)) { return 0x0227628f3F023bb0B980b67D528571c95c6DaC1c; - // avalanche chain + // avalanche chain } else if (chainId == uint256(43114)) { return 0x740b1c1de25031C31FF4fC9A62f554A55cdC1baD; - // zora chain + // zora chain } else if (chainId == uint256(7777777)) { return 0x7145F8aeef1f6510E92164038E1B6F8cB2c42Cbb; - // zora sepolia chain + // zora sepolia chain } else if (chainId == uint256(999999999)) { return 0x4324A677D74764f46f33ED447964252441aA8Db6; - // rookstock chain + // rookstock chain } else if (chainId == uint256(30)) { return 0xaF37EC98A00FD63689CF3060BF3B6784E00caD82; - // blast chain + // blast chain } else if (chainId == uint256(81457)) { return 0x792edAdE80af5fC680d96a2eD80A44247D2Cf6Fd; } else { From 674110b0e02ac260ffd997fe0ec65e67a3421742 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 23 Jun 2024 14:42:04 +0400 Subject: [PATCH 2/2] docs --- contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol b/contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol index 296e1a5..7e4d1d0 100644 --- a/contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol +++ b/contracts/interfaces/IUniswapV3PoolSlot0Unchecked.sol @@ -3,6 +3,11 @@ pragma solidity ^0.7.6; pragma abicoder v2; interface IUniswapV3PoolSlot0Unchecked { + /// Identical to IUniswapV3PoolState.slot0, but with `uint256` values for + /// all the return values that the quoter doesn't need to decode. This + /// prevents Solidity from doing overflow checks that can revert otherwise + /// compliant pools, if they return values that are too large for the + /// canonical slot0 function. function slot0() external view