From 847cf19bbafb53f0d8d25d3f78f00a3d77745fd6 Mon Sep 17 00:00:00 2001 From: Alice <34962750+hensha256@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:00:36 +0100 Subject: [PATCH] Bug: Require different currencies (#380) * Require different currencies * hardhat snapshots * Add new custom type function * remove extra paren --- .forge-snapshots/initialize.snap | 2 +- contracts/PoolManager.sol | 2 +- contracts/types/Currency.sol | 6 +++++- test/__snapshots__/PoolManager.gas.spec.ts.snap | 2 +- test/__snapshots__/PoolManager.spec.ts.snap | 2 +- test/foundry-tests/PoolManager.t.sol | 13 +++++++++++++ 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/.forge-snapshots/initialize.snap b/.forge-snapshots/initialize.snap index dd943dc86..3e292380f 100644 --- a/.forge-snapshots/initialize.snap +++ b/.forge-snapshots/initialize.snap @@ -1 +1 @@ -38126 \ No newline at end of file +38123 \ No newline at end of file diff --git a/contracts/PoolManager.sol b/contracts/PoolManager.sol index 359fbada1..6e6ab8db2 100644 --- a/contracts/PoolManager.sol +++ b/contracts/PoolManager.sol @@ -109,7 +109,7 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, ERC1155, IERC1155Rec // see TickBitmap.sol for overflow conditions that can arise from tick spacing being too large if (key.tickSpacing > MAX_TICK_SPACING) revert TickSpacingTooLarge(); if (key.tickSpacing < MIN_TICK_SPACING) revert TickSpacingTooSmall(); - if (key.currency0 > key.currency1) revert CurrenciesInitializedOutOfOrder(); + if (key.currency0 >= key.currency1) revert CurrenciesInitializedOutOfOrder(); if (!key.hooks.isValidHookAddress(key.fee)) revert Hooks.HookAddressNotValid(address(key.hooks)); if (key.hooks.shouldCallBeforeInitialize()) { diff --git a/contracts/types/Currency.sol b/contracts/types/Currency.sol index 9b28d2bca..5d04541c2 100644 --- a/contracts/types/Currency.sol +++ b/contracts/types/Currency.sol @@ -5,7 +5,7 @@ import {IERC20Minimal} from "../interfaces/external/IERC20Minimal.sol"; type Currency is address; -using {greaterThan as >, lessThan as <, equals as ==} for Currency global; +using {greaterThan as >, lessThan as <, greaterThanOrEqualTo as >=, equals as ==} for Currency global; function equals(Currency currency, Currency other) pure returns (bool) { return Currency.unwrap(currency) == Currency.unwrap(other); @@ -19,6 +19,10 @@ function lessThan(Currency currency, Currency other) pure returns (bool) { return Currency.unwrap(currency) < Currency.unwrap(other); } +function greaterThanOrEqualTo(Currency currency, Currency other) pure returns (bool) { + return Currency.unwrap(currency) >= Currency.unwrap(other); +} + /// @title CurrencyLibrary /// @dev This library allows for transferring and holding native tokens and ERC20 tokens library CurrencyLibrary { diff --git a/test/__snapshots__/PoolManager.gas.spec.ts.snap b/test/__snapshots__/PoolManager.gas.spec.ts.snap index a89a29cb4..bb054b010 100644 --- a/test/__snapshots__/PoolManager.gas.spec.ts.snap +++ b/test/__snapshots__/PoolManager.gas.spec.ts.snap @@ -3,7 +3,7 @@ exports[`PoolManager gas tests ERC20 tokens #initialize initialize pool with no hooks and no protocol fee 1`] = ` Object { "calldataByteLength": 292, - "gasUsed": 55267, + "gasUsed": 55264, } `; diff --git a/test/__snapshots__/PoolManager.spec.ts.snap b/test/__snapshots__/PoolManager.spec.ts.snap index b2cef86a7..a9f9fa5c0 100644 --- a/test/__snapshots__/PoolManager.spec.ts.snap +++ b/test/__snapshots__/PoolManager.spec.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PoolManager bytecode size 1`] = `29268`; +exports[`PoolManager bytecode size 1`] = `29267`; diff --git a/test/foundry-tests/PoolManager.t.sol b/test/foundry-tests/PoolManager.t.sol index 04fb4ee59..1e205ee08 100644 --- a/test/foundry-tests/PoolManager.t.sol +++ b/test/foundry-tests/PoolManager.t.sol @@ -227,6 +227,19 @@ contract PoolManagerTest is Test, Deployers, TokenFixture, GasSnapshot, IERC1155 assertEq(slot0.sqrtPriceX96, sqrtPriceX96); } + function testPoolManagerInitializeRevertsWithIdenticalTokens(uint160 sqrtPriceX96) public { + // Assumptions tested in Pool.t.sol + vm.assume(sqrtPriceX96 >= TickMath.MIN_SQRT_RATIO); + vm.assume(sqrtPriceX96 < TickMath.MAX_SQRT_RATIO); + + // Both currencies are currency0 + PoolKey memory key = + PoolKey({currency0: currency0, currency1: currency0, fee: 3000, hooks: IHooks(address(0)), tickSpacing: 60}); + + vm.expectRevert(IPoolManager.CurrenciesInitializedOutOfOrder.selector); + manager.initialize(key, sqrtPriceX96, ZERO_BYTES); + } + function testPoolManagerInitializeRevertsWithSameTokenCombo(uint160 sqrtPriceX96) public { // Assumptions tested in Pool.t.sol vm.assume(sqrtPriceX96 >= TickMath.MIN_SQRT_RATIO);