diff --git a/.forge-snapshots/initialize.snap b/.forge-snapshots/initialize.snap index 4cb1ffbaf..eadbd2654 100644 --- a/.forge-snapshots/initialize.snap +++ b/.forge-snapshots/initialize.snap @@ -1 +1 @@ -37964 +38123 diff --git a/contracts/PoolManager.sol b/contracts/PoolManager.sol index eebe0458a..6b1f11ee4 100644 --- a/contracts/PoolManager.sol +++ b/contracts/PoolManager.sol @@ -108,7 +108,7 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, ERC6909 { // 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 a1246e70d..ef7b4361c 100644 --- a/test/foundry-tests/PoolManager.t.sol +++ b/test/foundry-tests/PoolManager.t.sol @@ -224,6 +224,19 @@ contract PoolManagerTest is Test, Deployers, TokenFixture, GasSnapshot { 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);