From 04306252713dcb96c8d70f8febb7f57077a3ddcf Mon Sep 17 00:00:00 2001 From: Noah Zinsmeister Date: Mon, 20 Mar 2023 15:27:07 -0400 Subject: [PATCH] get working with latest core commit --- .gitignore | 1 - .gitmodules | 3 + contracts/hooks/BaseHook.sol | 57 +++--- contracts/hooks/GeomeanOracle.sol | 67 +++---- contracts/hooks/LimitOrderHook.sol | 165 ++++++++++++------ contracts/test/MockContract.sol | 2 +- contracts/test/MockTimeGeomeanOracle.sol | 6 +- contracts/test/PoolModifyPositionTest.sol | 4 +- contracts/test/TestERC20.sol | 4 +- foundry.toml | 2 +- hardhat.config.ts | 2 +- lib/forge-std | 1 + package.json | 2 +- remappings.txt | 2 + test/GeomeanOracle.spec.ts | 20 +-- test/LimitOrderHook.spec.ts | 40 ++--- .../__snapshots__/LimitOrderHook.spec.ts.snap | 6 +- test/shared/utilities.ts | 12 +- yarn.lock | 4 +- 19 files changed, 237 insertions(+), 163 deletions(-) create mode 100644 .gitmodules create mode 160000 lib/forge-std create mode 100644 remappings.txt diff --git a/.gitignore b/.gitignore index 13730d59..a40ed1fa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ node_modules/ typechain/ cache/ foundry-out/ -lib/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..888d42dc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/contracts/hooks/BaseHook.sol b/contracts/hooks/BaseHook.sol index 3661b280..39aa8e95 100644 --- a/contracts/hooks/BaseHook.sol +++ b/contracts/hooks/BaseHook.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.13; +pragma solidity =0.8.19; -import {IPoolManager} from "@uniswap/core-next/contracts/interfaces/IPoolManager.sol"; -import {IHooks} from "@uniswap/core-next/contracts/interfaces/IHooks.sol"; +import {IPoolManager} from '@uniswap/core-next/contracts/interfaces/IPoolManager.sol'; +import {IHooks} from '@uniswap/core-next/contracts/interfaces/IHooks.sol'; abstract contract BaseHook is IHooks { error NotPoolManager(); @@ -47,23 +47,28 @@ abstract contract BaseHook is IHooks { } } - function beforeInitialize(address, IPoolManager.PoolKey calldata, uint160) external virtual returns (bytes4) { + function beforeInitialize( + address, + IPoolManager.PoolKey calldata, + uint160 + ) external virtual returns (bytes4) { revert HookNotImplemented(); } - function afterInitialize(address, IPoolManager.PoolKey calldata, uint160, int24) - external - virtual - returns (bytes4) - { + function afterInitialize( + address, + IPoolManager.PoolKey calldata, + uint160, + int24 + ) external virtual returns (bytes4) { revert HookNotImplemented(); } - function beforeModifyPosition(address, IPoolManager.PoolKey calldata, IPoolManager.ModifyPositionParams calldata) - external - virtual - returns (bytes4) - { + function beforeModifyPosition( + address, + IPoolManager.PoolKey calldata, + IPoolManager.ModifyPositionParams calldata + ) external virtual returns (bytes4) { revert HookNotImplemented(); } @@ -76,11 +81,11 @@ abstract contract BaseHook is IHooks { revert HookNotImplemented(); } - function beforeSwap(address, IPoolManager.PoolKey calldata, IPoolManager.SwapParams calldata) - external - virtual - returns (bytes4) - { + function beforeSwap( + address, + IPoolManager.PoolKey calldata, + IPoolManager.SwapParams calldata + ) external virtual returns (bytes4) { revert HookNotImplemented(); } @@ -93,11 +98,21 @@ abstract contract BaseHook is IHooks { revert HookNotImplemented(); } - function beforeDonate(address, IPoolManager.PoolKey calldata, uint256, uint256) external virtual returns (bytes4) { + function beforeDonate( + address, + IPoolManager.PoolKey calldata, + uint256, + uint256 + ) external virtual returns (bytes4) { revert HookNotImplemented(); } - function afterDonate(address, IPoolManager.PoolKey calldata, uint256, uint256) external virtual returns (bytes4) { + function afterDonate( + address, + IPoolManager.PoolKey calldata, + uint256, + uint256 + ) external virtual returns (bytes4) { revert HookNotImplemented(); } } diff --git a/contracts/hooks/GeomeanOracle.sol b/contracts/hooks/GeomeanOracle.sol index b951dd8b..9a7b016c 100644 --- a/contracts/hooks/GeomeanOracle.sol +++ b/contracts/hooks/GeomeanOracle.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.13; +pragma solidity =0.8.19; -import {IPoolManager} from "@uniswap/core-next/contracts/interfaces/IPoolManager.sol"; -import {PoolId} from "@uniswap/core-next/contracts/libraries/PoolId.sol"; -import {Hooks} from "@uniswap/core-next/contracts/libraries/Hooks.sol"; -import {TickMath} from "@uniswap/core-next/contracts/libraries/TickMath.sol"; -import {Oracle} from "@uniswap/core-next/contracts/libraries/Oracle.sol"; -import {BaseHook} from "./BaseHook.sol"; +import {IPoolManager} from '@uniswap/core-next/contracts/interfaces/IPoolManager.sol'; +import {PoolId} from '@uniswap/core-next/contracts/libraries/PoolId.sol'; +import {Hooks} from '@uniswap/core-next/contracts/libraries/Hooks.sol'; +import {TickMath} from '@uniswap/core-next/contracts/libraries/TickMath.sol'; +import {Oracle} from '@uniswap/core-next/contracts/libraries/Oracle.sol'; +import {BaseHook} from './BaseHook.sol'; /// @notice A hook for a pool that allows a Uniswap pool to act as an oracle. Pools that use this hook must have full range /// tick spacing and liquidity is always permanently locked in these pools. This is the suggested configuration @@ -73,13 +73,11 @@ contract GeomeanOracle is BaseHook { ); } - function beforeInitialize(address, IPoolManager.PoolKey calldata key, uint160) - external - view - override - poolManagerOnly - returns (bytes4) - { + function beforeInitialize( + address, + IPoolManager.PoolKey calldata key, + uint160 + ) external view override poolManagerOnly returns (bytes4) { // This is to limit the fragmentation of pools using this oracle hook. In other words, // there may only be one pool per pair of tokens that use this hook. The tick spacing is set to the maximum // because we only allow max range liquidity in this pool. @@ -87,12 +85,12 @@ contract GeomeanOracle is BaseHook { return GeomeanOracle.beforeInitialize.selector; } - function afterInitialize(address, IPoolManager.PoolKey calldata key, uint160, int24) - external - override - poolManagerOnly - returns (bytes4) - { + function afterInitialize( + address, + IPoolManager.PoolKey calldata key, + uint160, + int24 + ) external override poolManagerOnly returns (bytes4) { bytes32 id = key.toId(); (states[id].cardinality, states[id].cardinalityNext) = observations[id].initialize(_blockTimestamp()); return GeomeanOracle.afterInitialize.selector; @@ -101,12 +99,17 @@ contract GeomeanOracle is BaseHook { /// @dev Called before any action that potentially modifies pool price or liquidity, such as swap or modify position function _updatePool(IPoolManager.PoolKey calldata key) private { bytes32 id = key.toId(); - (, int24 tick,) = poolManager.getSlot0(id); + (, int24 tick, ) = poolManager.getSlot0(id); uint128 liquidity = poolManager.getLiquidity(id); (states[id].index, states[id].cardinality) = observations[id].write( - states[id].index, _blockTimestamp(), tick, liquidity, states[id].cardinality, states[id].cardinalityNext + states[id].index, + _blockTimestamp(), + tick, + liquidity, + states[id].cardinality, + states[id].cardinalityNext ); } @@ -118,19 +121,18 @@ contract GeomeanOracle is BaseHook { if (params.liquidityDelta < 0) revert OraclePoolMustLockLiquidity(); int24 maxTickSpacing = poolManager.MAX_TICK_SPACING(); if ( - params.tickLower != TickMath.minUsableTick(maxTickSpacing) - || params.tickUpper != TickMath.maxUsableTick(maxTickSpacing) + params.tickLower != TickMath.minUsableTick(maxTickSpacing) || + params.tickUpper != TickMath.maxUsableTick(maxTickSpacing) ) revert OraclePositionsMustBeFullRange(); _updatePool(key); return GeomeanOracle.beforeModifyPosition.selector; } - function beforeSwap(address, IPoolManager.PoolKey calldata key, IPoolManager.SwapParams calldata) - external - override - poolManagerOnly - returns (bytes4) - { + function beforeSwap( + address, + IPoolManager.PoolKey calldata key, + IPoolManager.SwapParams calldata + ) external override poolManagerOnly returns (bytes4) { _updatePool(key); return GeomeanOracle.beforeSwap.selector; } @@ -145,11 +147,12 @@ contract GeomeanOracle is BaseHook { ObservationState memory state = states[id]; - (, int24 tick,) = poolManager.getSlot0(id); + (, int24 tick, ) = poolManager.getSlot0(id); uint128 liquidity = poolManager.getLiquidity(id); - return observations[id].observe(_blockTimestamp(), secondsAgos, tick, state.index, liquidity, state.cardinality); + return + observations[id].observe(_blockTimestamp(), secondsAgos, tick, state.index, liquidity, state.cardinality); } /// @notice Increase the cardinality target for the given pool diff --git a/contracts/hooks/LimitOrderHook.sol b/contracts/hooks/LimitOrderHook.sol index 94a249cd..24a66942 100644 --- a/contracts/hooks/LimitOrderHook.sol +++ b/contracts/hooks/LimitOrderHook.sol @@ -1,14 +1,15 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.13; - -import {IPoolManager} from "@uniswap/core-next/contracts/interfaces/IPoolManager.sol"; -import {PoolId} from "@uniswap/core-next/contracts/libraries/PoolId.sol"; -import {Hooks} from "@uniswap/core-next/contracts/libraries/Hooks.sol"; -import {FullMath} from "@uniswap/core-next/contracts/libraries/FullMath.sol"; -import {SafeCast} from "@uniswap/core-next/contracts/libraries/SafeCast.sol"; -import {IERC20Minimal} from "@uniswap/core-next/contracts/interfaces/external/IERC20Minimal.sol"; -import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; -import {BaseHook} from "./BaseHook.sol"; +pragma solidity =0.8.19; + +import {IPoolManager} from '@uniswap/core-next/contracts/interfaces/IPoolManager.sol'; +import {PoolId} from '@uniswap/core-next/contracts/libraries/PoolId.sol'; +import {Hooks} from '@uniswap/core-next/contracts/libraries/Hooks.sol'; +import {FullMath} from '@uniswap/core-next/contracts/libraries/FullMath.sol'; +import {SafeCast} from '@uniswap/core-next/contracts/libraries/SafeCast.sol'; +import {IERC20Minimal} from '@uniswap/core-next/contracts/interfaces/external/IERC20Minimal.sol'; +import {IERC1155Receiver} from '@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol'; +import {BaseHook} from './BaseHook.sol'; +import {Currency, CurrencyLibrary} from '@uniswap/core-next/contracts/libraries/CurrencyLibrary.sol'; type Epoch is uint232; @@ -28,6 +29,7 @@ contract LimitOrderHook is BaseHook { using SafeCast for uint256; using EpochLibrary for Epoch; using PoolId for IPoolManager.PoolKey; + using CurrencyLibrary for Currency; error ZeroLiquidity(); error InRange(); @@ -65,8 +67,8 @@ contract LimitOrderHook is BaseHook { struct EpochInfo { bool filled; - IERC20Minimal token0; - IERC20Minimal token1; + Currency currency0; + Currency currency1; uint256 token0Total; uint256 token1Total; uint128 liquidityTotal; @@ -100,11 +102,20 @@ contract LimitOrderHook is BaseHook { tickLowerLasts[poolId] = tickLower; } - function getEpoch(IPoolManager.PoolKey memory key, int24 tickLower, bool zeroForOne) public view returns (Epoch) { + function getEpoch( + IPoolManager.PoolKey memory key, + int24 tickLower, + bool zeroForOne + ) public view returns (Epoch) { return epochs[keccak256(abi.encode(key, tickLower, zeroForOne))]; } - function setEpoch(IPoolManager.PoolKey memory key, int24 tickLower, bool zeroForOne, Epoch epoch) private { + function setEpoch( + IPoolManager.PoolKey memory key, + int24 tickLower, + bool zeroForOne, + Epoch epoch + ) private { epochs[keccak256(abi.encode(key, tickLower, zeroForOne))] = epoch; } @@ -113,7 +124,7 @@ contract LimitOrderHook is BaseHook { } function getTick(bytes32 poolId) private view returns (int24 tick) { - (, tick,) = poolManager.getSlot0(poolId); + (, tick, ) = poolManager.getSlot0(poolId); } function getTickLower(int24 tick, int24 tickSpacing) private pure returns (int24) { @@ -122,12 +133,12 @@ contract LimitOrderHook is BaseHook { return compressed * tickSpacing; } - function afterInitialize(address, IPoolManager.PoolKey calldata key, uint160, int24 tick) - external - override - poolManagerOnly - returns (bytes4) - { + function afterInitialize( + address, + IPoolManager.PoolKey calldata key, + uint160, + int24 tick + ) external override poolManagerOnly returns (bytes4) { setTickLowerLast(key.toId(), getTickLower(tick, key.tickSpacing)); return LimitOrderHook.afterInitialize.selector; } @@ -176,7 +187,11 @@ contract LimitOrderHook is BaseHook { function _getCrossedTicks(bytes32 poolId, int24 tickSpacing) internal view - returns (int24 tickLower, int24 lower, int24 upper) + returns ( + int24 tickLower, + int24 lower, + int24 upper + ) { tickLower = getTickLower(getTick(poolId), tickSpacing); int24 tickLowerLast = getTickLowerLast(poolId); @@ -190,11 +205,11 @@ contract LimitOrderHook is BaseHook { } } - function lockAcquiredFill(IPoolManager.PoolKey calldata key, int24 tickLower, int256 liquidityDelta) - external - selfOnly - returns (uint256 amount0, uint256 amount1) - { + function lockAcquiredFill( + IPoolManager.PoolKey calldata key, + int24 tickLower, + int256 liquidityDelta + ) external selfOnly returns (uint256 amount0, uint256 amount1) { IPoolManager.BalanceDelta memory delta = poolManager.modifyPosition( key, IPoolManager.ModifyPositionParams({ @@ -204,14 +219,16 @@ contract LimitOrderHook is BaseHook { }) ); - if (delta.amount0 < 0) poolManager.mint(key.token0, address(this), amount0 = uint256(-delta.amount0)); - if (delta.amount1 < 0) poolManager.mint(key.token1, address(this), amount1 = uint256(-delta.amount1)); + if (delta.amount0 < 0) poolManager.mint(key.currency0, address(this), amount0 = uint256(-delta.amount0)); + if (delta.amount1 < 0) poolManager.mint(key.currency1, address(this), amount1 = uint256(-delta.amount1)); } - function place(IPoolManager.PoolKey calldata key, int24 tickLower, bool zeroForOne, uint128 liquidity) - external - onlyValidPools(key.hooks) - { + function place( + IPoolManager.PoolKey calldata key, + int24 tickLower, + bool zeroForOne, + uint128 liquidity + ) external onlyValidPools(key.hooks) { if (liquidity == 0) revert ZeroLiquidity(); poolManager.lock( @@ -229,8 +246,8 @@ contract LimitOrderHook is BaseHook { epochNext = epoch.unsafeIncrement(); } epochInfo = epochInfos[epoch]; - epochInfo.token0 = key.token0; - epochInfo.token1 = key.token1; + epochInfo.currency0 = key.currency0; + epochInfo.currency1 = key.currency1; } else { epochInfo = epochInfos[epoch]; } @@ -263,21 +280,31 @@ contract LimitOrderHook is BaseHook { if (delta.amount1 != 0) revert InRange(); if (!zeroForOne) revert CrossedRange(); // TODO use safeTransferFrom - key.token0.transferFrom(owner, address(poolManager), uint256(delta.amount0)); - poolManager.settle(key.token0); + IERC20Minimal(Currency.unwrap(key.currency0)).transferFrom( + owner, + address(poolManager), + uint256(delta.amount0) + ); + poolManager.settle(key.currency0); } else { if (delta.amount0 != 0) revert InRange(); if (zeroForOne) revert CrossedRange(); // TODO use safeTransferFrom - key.token1.transferFrom(owner, address(poolManager), uint256(delta.amount1)); - poolManager.settle(key.token1); + IERC20Minimal(Currency.unwrap(key.currency1)).transferFrom( + owner, + address(poolManager), + uint256(delta.amount1) + ); + poolManager.settle(key.currency1); } } - function kill(IPoolManager.PoolKey calldata key, int24 tickLower, bool zeroForOne, address to) - external - returns (uint256 amount0, uint256 amount1) - { + function kill( + IPoolManager.PoolKey calldata key, + int24 tickLower, + bool zeroForOne, + address to + ) external returns (uint256 amount0, uint256 amount1) { Epoch epoch = getEpoch(key, tickLower, zeroForOne); EpochInfo storage epochInfo = epochInfos[epoch]; @@ -315,7 +342,16 @@ contract LimitOrderHook is BaseHook { int256 liquidityDelta, address to, bool removingAllLiquidity - ) external selfOnly returns (uint256 amount0, uint256 amount1, uint256 amount0Fee, uint256 amount1Fee) { + ) + external + selfOnly + returns ( + uint256 amount0, + uint256 amount1, + uint256 amount0Fee, + uint256 amount1Fee + ) + { int24 tickUpper = tickLower + key.tickSpacing; // because `modifyPosition` includes not just principal value but also fees, we cannot allocate @@ -324,14 +360,15 @@ contract LimitOrderHook is BaseHook { // to prevent this, we allocate all fee revenue to remaining limit order placers, unless this is the last order. if (!removingAllLiquidity) { IPoolManager.BalanceDelta memory deltaFee = poolManager.modifyPosition( - key, IPoolManager.ModifyPositionParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: 0}) + key, + IPoolManager.ModifyPositionParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: 0}) ); if (deltaFee.amount0 < 0) { - poolManager.mint(key.token0, address(this), amount0Fee = uint256(-deltaFee.amount0)); + poolManager.mint(key.currency0, address(this), amount0Fee = uint256(-deltaFee.amount0)); } if (deltaFee.amount1 < 0) { - poolManager.mint(key.token1, address(this), amount1Fee = uint256(-deltaFee.amount1)); + poolManager.mint(key.currency1, address(this), amount1Fee = uint256(-deltaFee.amount1)); } } @@ -344,8 +381,8 @@ contract LimitOrderHook is BaseHook { }) ); - if (delta.amount0 < 0) poolManager.take(key.token0, to, amount0 = uint256(-delta.amount0)); - if (delta.amount1 < 0) poolManager.take(key.token1, to, amount1 = uint256(-delta.amount1)); + if (delta.amount0 < 0) poolManager.take(key.currency0, to, amount0 = uint256(-delta.amount0)); + if (delta.amount1 < 0) poolManager.take(key.currency1, to, amount1 = uint256(-delta.amount1)); } function withdraw(Epoch epoch, address to) external returns (uint256 amount0, uint256 amount1) { @@ -369,34 +406,48 @@ contract LimitOrderHook is BaseHook { epochInfo.liquidityTotal = liquidityTotal - liquidity; poolManager.lock( - abi.encodeCall(this.lockAcquiredWithdraw, (epochInfo.token0, epochInfo.token1, amount0, amount1, to)) + abi.encodeCall(this.lockAcquiredWithdraw, (epochInfo.currency0, epochInfo.currency1, amount0, amount1, to)) ); emit Withdraw(msg.sender, epoch, liquidity); } function lockAcquiredWithdraw( - IERC20Minimal token0, - IERC20Minimal token1, + Currency currency0, + Currency currency1, uint256 token0Amount, uint256 token1Amount, address to ) external selfOnly { if (token0Amount > 0) { poolManager.safeTransferFrom( - address(this), address(poolManager), uint256(uint160(address(token0))), token0Amount, "" + address(this), + address(poolManager), + uint256(uint160(Currency.unwrap(currency0))), + token0Amount, + '' ); - poolManager.take(token0, to, token0Amount); + poolManager.take(currency0, to, token0Amount); } if (token1Amount > 0) { poolManager.safeTransferFrom( - address(this), address(poolManager), uint256(uint160(address(token1))), token1Amount, "" + address(this), + address(poolManager), + uint256(uint160(Currency.unwrap(currency1))), + token1Amount, + '' ); - poolManager.take(token1, to, token1Amount); + poolManager.take(currency1, to, token1Amount); } } - function onERC1155Received(address, address, uint256, uint256, bytes calldata) external view returns (bytes4) { + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) external view returns (bytes4) { if (msg.sender != address(poolManager)) revert NotPoolManagerToken(); return IERC1155Receiver.onERC1155Received.selector; } diff --git a/contracts/test/MockContract.sol b/contracts/test/MockContract.sol index 12922cf9..69f3e41d 100644 --- a/contracts/test/MockContract.sol +++ b/contracts/test/MockContract.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.13; +pragma solidity =0.8.19; contract MockContract { mapping(bytes32 => uint256) public calls; diff --git a/contracts/test/MockTimeGeomeanOracle.sol b/contracts/test/MockTimeGeomeanOracle.sol index 0fa86e7f..57036ef8 100644 --- a/contracts/test/MockTimeGeomeanOracle.sol +++ b/contracts/test/MockTimeGeomeanOracle.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.13; +pragma solidity =0.8.19; -import {IPoolManager} from "@uniswap/core-next/contracts/interfaces/IPoolManager.sol"; -import {GeomeanOracle} from "../hooks/GeomeanOracle.sol"; +import {IPoolManager} from '@uniswap/core-next/contracts/interfaces/IPoolManager.sol'; +import {GeomeanOracle} from '../hooks/GeomeanOracle.sol'; contract MockTimeGeomeanOracle is GeomeanOracle { uint32 public time; diff --git a/contracts/test/PoolModifyPositionTest.sol b/contracts/test/PoolModifyPositionTest.sol index 2b6c2c39..65245263 100644 --- a/contracts/test/PoolModifyPositionTest.sol +++ b/contracts/test/PoolModifyPositionTest.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.13; +pragma solidity =0.8.19; -import {PoolModifyPositionTest} from "@uniswap/core-next/contracts/test/PoolModifyPositionTest.sol"; +import {PoolModifyPositionTest} from '@uniswap/core-next/contracts/test/PoolModifyPositionTest.sol'; diff --git a/contracts/test/TestERC20.sol b/contracts/test/TestERC20.sol index 38c53447..a409ebf4 100644 --- a/contracts/test/TestERC20.sol +++ b/contracts/test/TestERC20.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity =0.8.13; +pragma solidity =0.8.19; -import {TestERC20} from "@uniswap/core-next/contracts/test/TestERC20.sol"; +import {TestERC20} from '@uniswap/core-next/contracts/test/TestERC20.sol'; diff --git a/foundry.toml b/foundry.toml index 2edffb62..d980f50a 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ [profile.default] src = 'contracts' out = 'foundry-out' -solc_version = '0.8.13' +solc_version = '0.8.19' optimizer_runs = 800 [profile.ci] diff --git a/hardhat.config.ts b/hardhat.config.ts index 5f2ea5e1..e29c1ca2 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -42,7 +42,7 @@ export default { metadata: { // do not include the metadata hash, since this is machine dependent // and we want all generated code to be deterministic - // https://docs.soliditylang.org/en/v0.8.13/metadata.html + // https://docs.soliditylang.org/en/v0.8.19/metadata.html bytecodeHash: 'none', }, }, diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 00000000..2b58ecbc --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 2b58ecbcf3dfde7a75959dc7b4eb3d0670278de6 diff --git a/package.json b/package.json index 8edfb997..9a375fd5 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@openzeppelin/contracts": "4.4.2", - "@uniswap/core-next": "git+ssh://git@github.com:Uniswap/core-next.git#50d7873b95218df47bc747d1218a97a29fad494e" + "@uniswap/core-next": "git+ssh://git@github.com:Uniswap/core-next.git#0f5add180ebb5e67f7b6a6c14bc3f1b067dec935" }, "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.2", diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 00000000..352f4c21 --- /dev/null +++ b/remappings.txt @@ -0,0 +1,2 @@ +@uniswap/=node_modules/@uniswap/ +forge-std/=lib/forge-std/src/ diff --git a/test/GeomeanOracle.spec.ts b/test/GeomeanOracle.spec.ts index e617af85..1daca5e8 100644 --- a/test/GeomeanOracle.spec.ts +++ b/test/GeomeanOracle.spec.ts @@ -1,11 +1,11 @@ import { abi as V4_POOL_MANAGER_ABI, - bytecode as V4_POOL_MANAGER_BYTECODE, + bytecode as V4_POOL_MANAGER_BYTECODE } from '@uniswap/core-next/artifacts/contracts/PoolManager.sol/PoolManager.json' import { createFixtureLoader } from 'ethereum-waffle' import { Wallet } from 'ethers' import hre, { ethers, waffle } from 'hardhat' -import { MockTimeGeomeanOracle, IPoolManager, PoolModifyPositionTest, TestERC20 } from '../typechain' +import { IPoolManager, MockTimeGeomeanOracle, PoolModifyPositionTest, TestERC20 } from '../typechain' import { MAX_TICK_SPACING } from './shared/constants' import { expect } from './shared/expect' import { tokensFixture } from './shared/fixtures' @@ -99,8 +99,8 @@ describe('GeomeanOracle', () => { }) let poolKey: { - token0: string - token1: string + currency0: string + currency1: string fee: number tickSpacing: number hooks: string @@ -114,8 +114,8 @@ describe('GeomeanOracle', () => { modifyPositionTest, } = await loadFixture(fixture)) poolKey = { - token0: token0.address, - token1: token1.address, + currency0: token0.address, + currency1: token1.address, fee: 0, hooks: oracle.address, tickSpacing: MAX_TICK_SPACING, @@ -146,8 +146,8 @@ describe('GeomeanOracle', () => { await expect( poolManager.initialize( { - token0: token0.address, - token1: token1.address, + currency0: token0.address, + currency1: token1.address, fee: 1, hooks: oracle.address, tickSpacing: MAX_TICK_SPACING, @@ -161,8 +161,8 @@ describe('GeomeanOracle', () => { await expect( poolManager.initialize( { - token0: token0.address, - token1: token1.address, + currency0: token0.address, + currency1: token1.address, fee: 0, hooks: oracle.address, tickSpacing: 60, diff --git a/test/LimitOrderHook.spec.ts b/test/LimitOrderHook.spec.ts index e4bfc93b..f83ba7a4 100644 --- a/test/LimitOrderHook.spec.ts +++ b/test/LimitOrderHook.spec.ts @@ -1,31 +1,31 @@ -import snapshotGasCost from '@uniswap/snapshot-gas-cost'; import { abi as V4_POOL_MANAGER_ABI, - bytecode as V4_POOL_MANAGER_BYTECODE, -} from '@uniswap/core-next/artifacts/contracts/PoolManager.sol/PoolManager.json' + bytecode as V4_POOL_MANAGER_BYTECODE +} from '@uniswap/core-next/artifacts/contracts/PoolManager.sol/PoolManager.json'; import { abi as POOL_SWAP_TEST_ABI, - bytecode as POOL_SWAP_TEST_BYTECODE, -} from '@uniswap/core-next/artifacts/contracts/test/PoolSwapTest.sol/PoolSwapTest.json' + bytecode as POOL_SWAP_TEST_BYTECODE +} from '@uniswap/core-next/artifacts/contracts/test/PoolSwapTest.sol/PoolSwapTest.json'; import { abi as TICK_MATH_TEST_ABI, - bytecode as TICK_MATH_TEST_BYTECODE, -} from '@uniswap/core-next/artifacts/contracts/test/TickMathTest.sol/TickMathTest.json' -import { PoolManager, PoolSwapTest, TickMathTest } from '@uniswap/core-next/typechain' -import { Wallet } from 'ethers' -import hre, { ethers, waffle } from 'hardhat' -import { LimitOrderHook, TestERC20 } from '../typechain' -import { expect } from './shared/expect' -import { tokensFixture } from './shared/fixtures' -import { encodeSqrtPriceX96, expandTo18Decimals, FeeAmount, getWalletForDeployingHookMask, getPoolId } from './shared/utilities' + bytecode as TICK_MATH_TEST_BYTECODE +} from '@uniswap/core-next/artifacts/contracts/test/TickMathTest.sol/TickMathTest.json'; +import { PoolManager, PoolSwapTest, TickMathTest } from '@uniswap/core-next/typechain'; +import snapshotGasCost from '@uniswap/snapshot-gas-cost'; +import { Wallet } from 'ethers'; +import hre, { ethers, waffle } from 'hardhat'; +import { LimitOrderHook, TestERC20 } from '../typechain'; +import { expect } from './shared/expect'; +import { tokensFixture } from './shared/fixtures'; +import { encodeSqrtPriceX96, expandTo18Decimals, FeeAmount, getPoolId, getWalletForDeployingHookMask } from './shared/utilities'; const { constants } = ethers const createFixtureLoader = waffle.createFixtureLoader interface PoolKey { - token0: string - token1: string + currency0: string + currency1: string fee: FeeAmount tickSpacing: number hooks: string @@ -137,8 +137,8 @@ describe('LimitOrderHooks', () => { beforeEach('initialize pool with limit order hook', async () => { await manager.initialize( (key = { - token0: tokens.token0.address, - token1: tokens.token1.address, + currency0: tokens.token0.address, + currency1: tokens.token1.address, fee: FeeAmount.MEDIUM, tickSpacing: 60, hooks: limitOrderHook.address, @@ -293,8 +293,8 @@ describe('LimitOrderHooks', () => { const epochInfo = await limitOrderHook.epochInfos(1) expect(epochInfo.filled).to.be.false - expect(epochInfo.token0).to.eq(key.token0) - expect(epochInfo.token1).to.eq(key.token1) + expect(epochInfo.currency0).to.eq(key.currency0) + expect(epochInfo.currency1).to.eq(key.currency1) expect(epochInfo.token0Total).to.eq(0) expect(epochInfo.token1Total).to.eq(0) expect(epochInfo.liquidityTotal).to.eq(liquidity * 2) diff --git a/test/__snapshots__/LimitOrderHook.spec.ts.snap b/test/__snapshots__/LimitOrderHook.spec.ts.snap index d5bfc93e..4f975cb4 100644 --- a/test/__snapshots__/LimitOrderHook.spec.ts.snap +++ b/test/__snapshots__/LimitOrderHook.spec.ts.snap @@ -3,15 +3,15 @@ exports[`LimitOrderHooks #afterSwap gas cost 1`] = ` Object { "calldataByteLength": 324, - "gasUsed": 506798, + "gasUsed": 444058, } `; exports[`LimitOrderHooks #kill gas cost 1`] = ` Object { "calldataByteLength": 260, - "gasUsed": 210040, + "gasUsed": 188109, } `; -exports[`LimitOrderHooks bytecode size 1`] = `13098`; +exports[`LimitOrderHooks bytecode size 1`] = `12536`; diff --git a/test/shared/utilities.ts b/test/shared/utilities.ts index 2c4d9535..c2598940 100644 --- a/test/shared/utilities.ts +++ b/test/shared/utilities.ts @@ -45,14 +45,14 @@ export function getPositionKey(address: string, lowerTick: number, upperTick: nu } export function getPoolId({ - token0, - token1, + currency0, + currency1, fee, tickSpacing, hooks, }: { - token0: string | Contract - token1: string | Contract + currency0: string | Contract + currency1: string | Contract fee: number tickSpacing: number hooks: string | Contract @@ -61,8 +61,8 @@ export function getPoolId({ utils.defaultAbiCoder.encode( ['address', 'address', 'uint24', 'int24', 'address'], [ - typeof token0 === 'string' ? token0 : token0.address, - typeof token1 === 'string' ? token1 : token1.address, + typeof currency0 === 'string' ? currency0 : currency0.address, + typeof currency1 === 'string' ? currency1 : currency1.address, fee, tickSpacing, typeof hooks === 'string' ? hooks : hooks.address, diff --git a/yarn.lock b/yarn.lock index 8fadad77..799b9bd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1253,9 +1253,9 @@ resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== -"@uniswap/core-next@git+ssh://git@github.com:Uniswap/core-next.git#50d7873b95218df47bc747d1218a97a29fad494e": +"@uniswap/core-next@git+ssh://git@github.com:Uniswap/core-next.git#0f5add180ebb5e67f7b6a6c14bc3f1b067dec935": version "1.0.0" - resolved "git+ssh://git@github.com:Uniswap/core-next.git#50d7873b95218df47bc747d1218a97a29fad494e" + resolved "git+ssh://git@github.com:Uniswap/core-next.git#0f5add180ebb5e67f7b6a6c14bc3f1b067dec935" dependencies: "@openzeppelin/contracts" "4.4.2"