diff --git a/src/periphery/contracts/base/PoolInitializer.sol b/src/periphery/contracts/base/PoolInitializer.sol index 0c59de7b..6203e061 100644 --- a/src/periphery/contracts/base/PoolInitializer.sol +++ b/src/periphery/contracts/base/PoolInitializer.sol @@ -19,7 +19,8 @@ abstract contract PoolInitializer is IPoolInitializer, PeripheryImmutableState { address token0, address token1, address deployer, - uint160 sqrtPriceX96 + uint160 sqrtPriceX96, + bytes calldata data ) external payable override returns (address pool) { require(token0 < token1, 'Invalid order of tokens'); @@ -32,7 +33,7 @@ abstract contract PoolInitializer is IPoolInitializer, PeripheryImmutableState { if (pool == address(0)) { if (deployer == address(0)) { - pool = _factory.createPool(token0, token1, ''); + pool = _factory.createPool(token0, token1, data); _initializePool(pool, sqrtPriceX96); } diff --git a/src/periphery/contracts/interfaces/IPoolInitializer.sol b/src/periphery/contracts/interfaces/IPoolInitializer.sol index a8f8aac5..8fa9bc33 100644 --- a/src/periphery/contracts/interfaces/IPoolInitializer.sol +++ b/src/periphery/contracts/interfaces/IPoolInitializer.sol @@ -13,11 +13,13 @@ interface IPoolInitializer { /// @param token0 The contract address of token0 of the pool /// @param token1 The contract address of token1 of the pool /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value + /// @param data Data for plugin initialization /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary function createAndInitializePoolIfNecessary( address token0, address token1, address deployer, - uint160 sqrtPriceX96 + uint160 sqrtPriceX96, + bytes calldata data ) external payable returns (address pool); } diff --git a/src/periphery/contracts/interfaces/IQuoterV2.sol b/src/periphery/contracts/interfaces/IQuoterV2.sol index 4782649a..5c55f38a 100644 --- a/src/periphery/contracts/interfaces/IQuoterV2.sol +++ b/src/periphery/contracts/interfaces/IQuoterV2.sol @@ -13,8 +13,8 @@ interface IQuoterV2 { /// @notice Returns the amount out received for a given exact input swap without executing the swap /// @param path The path of the swap, i.e. each token pair /// @param amountInRequired The desired amount of the first token to swap - /// @return amountOut The amount of the last token that would be received - /// @return amountIn The amount of the last token that should be paid + /// @return amountOutList The amount of the last token that would be received + /// @return amountInList The amount of the last token that should be paid /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path /// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path /// @return gasEstimate The estimate of the gas that the swap consumes @@ -25,8 +25,8 @@ interface IQuoterV2 { ) external returns ( - uint256 amountOut, - uint256 amountIn, + uint256[] memory amountOutList, + uint256[] memory amountInList, uint160[] memory sqrtPriceX96AfterList, uint32[] memory initializedTicksCrossedList, uint256 gasEstimate, @@ -69,8 +69,8 @@ interface IQuoterV2 { /// @notice Returns the amount in required for a given exact output swap without executing the swap /// @param path The path of the swap, i.e. each token pair. Path must be provided in reverse order /// @param amountOutRequired The amount of the last token to receive - /// @return amountOut The amount of the last token that would be received - /// @return amountIn The amount of first token required to be paid + /// @return amountOutList The amount of the last token that would be received + /// @return amountInList The amount of first token required to be paid /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path /// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path /// @return gasEstimate The estimate of the gas that the swap consumes @@ -81,8 +81,8 @@ interface IQuoterV2 { ) external returns ( - uint256 amountOut, - uint256 amountIn, + uint256[] memory amountOutList, + uint256[] memory amountInList, uint160[] memory sqrtPriceX96AfterList, uint32[] memory initializedTicksCrossedList, uint256 gasEstimate, diff --git a/src/periphery/contracts/lens/QuoterV2.sol b/src/periphery/contracts/lens/QuoterV2.sol index 8edf893a..492c02de 100644 --- a/src/periphery/contracts/lens/QuoterV2.sol +++ b/src/periphery/contracts/lens/QuoterV2.sol @@ -160,14 +160,16 @@ contract QuoterV2 is IQuoterV2, IAlgebraSwapCallback, PeripheryImmutableState { public override returns ( - uint256 amountOut, - uint256 amountIn, + uint256[] memory amountOutList, + uint256[] memory amountInList, uint160[] memory sqrtPriceX96AfterList, uint32[] memory initializedTicksCrossedList, uint256 gasEstimate, uint16[] memory feeList ) { + amountOutList = new uint256[](path.numPools()); + amountInList = new uint256[](path.numPools()); sqrtPriceX96AfterList = new uint160[](path.numPools()); initializedTicksCrossedList = new uint32[](path.numPools()); feeList = new uint16[](path.numPools()); @@ -185,21 +187,17 @@ contract QuoterV2 is IQuoterV2, IAlgebraSwapCallback, PeripheryImmutableState { } // the outputs of prior swaps become the inputs to subsequent ones - uint256 _amountOut; - uint256 _amountIn; uint256 _gasEstimate; ( - _amountOut, - _amountIn, + amountOutList[i], + amountInList[i], sqrtPriceX96AfterList[i], initializedTicksCrossedList[i], _gasEstimate, feeList[i] ) = quoteExactInputSingle(params); - if (i == 0) amountIn = _amountIn; - - amountInRequired = _amountOut; + amountInRequired = amountOutList[i]; gasEstimate += _gasEstimate; i++; @@ -208,8 +206,8 @@ contract QuoterV2 is IQuoterV2, IAlgebraSwapCallback, PeripheryImmutableState { path = path.skipToken(); } else { return ( - amountInRequired, - amountIn, + amountOutList, + amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList, gasEstimate, @@ -264,14 +262,16 @@ contract QuoterV2 is IQuoterV2, IAlgebraSwapCallback, PeripheryImmutableState { public override returns ( - uint256 amountOut, - uint256 amountIn, + uint256[] memory amountOutList, + uint256[] memory amountInList, uint160[] memory sqrtPriceX96AfterList, uint32[] memory initializedTicksCrossedList, uint256 gasEstimate, uint16[] memory feeList ) { + amountOutList = new uint256[](path.numPools()); + amountInList = new uint256[](path.numPools()); sqrtPriceX96AfterList = new uint160[](path.numPools()); initializedTicksCrossedList = new uint32[](path.numPools()); feeList = new uint16[](path.numPools()); @@ -289,21 +289,17 @@ contract QuoterV2 is IQuoterV2, IAlgebraSwapCallback, PeripheryImmutableState { } // the inputs of prior swaps become the outputs of subsequent ones - uint256 _amountOut; - uint256 _amountIn; uint256 _gasEstimate; ( - _amountOut, - _amountIn, + amountOutList[i], + amountInList[i], sqrtPriceX96AfterList[i], initializedTicksCrossedList[i], _gasEstimate, feeList[i] ) = quoteExactOutputSingle(params); - if (i == 0) amountOut = _amountOut; - - amountOutRequired = _amountIn; + amountOutRequired = amountInList[i]; gasEstimate += _gasEstimate; i++; @@ -312,8 +308,8 @@ contract QuoterV2 is IQuoterV2, IAlgebraSwapCallback, PeripheryImmutableState { path = path.skipToken(); } else { return ( - amountOut, - amountOutRequired, + amountOutList, + amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList, gasEstimate, diff --git a/src/periphery/test/NonfungiblePositionManager.spec.ts b/src/periphery/test/NonfungiblePositionManager.spec.ts index eb7fe87a..e20768e6 100644 --- a/src/periphery/test/NonfungiblePositionManager.spec.ts +++ b/src/periphery/test/NonfungiblePositionManager.spec.ts @@ -86,13 +86,13 @@ describe('NonfungiblePositionManager', () => { ]); const code = await wallet.provider.getCode(expectedAddress); expect(code).to.eq('0x'); - await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1)); + await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'); const codeAfter = await wallet.provider.getCode(expectedAddress); expect(codeAfter).to.not.eq('0x'); }); it('is payable', async () => { - await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1), { value: 1 }); + await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x', { value: 1 }); }); it('works if pool is created but not initialized', async () => { @@ -105,7 +105,7 @@ describe('NonfungiblePositionManager', () => { await factory.createPool(tokens[0], tokens[1], '0x'); const code = await wallet.provider.getCode(expectedAddress); expect(code).to.not.eq('0x'); - await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(2, 1)); + await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(2, 1), '0x'); }); it('works if pool is created and initialized', async () => { @@ -121,7 +121,7 @@ describe('NonfungiblePositionManager', () => { if (!wallet.provider) throw new Error('No provider'); const code = await wallet.provider.getCode(expectedAddress); expect(code).to.not.eq('0x'); - await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(4, 1)); + await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(4, 1), '0x'); }); it('could theoretically use eth via multicall', async () => { @@ -129,14 +129,14 @@ describe('NonfungiblePositionManager', () => { const createAndInitializePoolIfNecessaryData = nft.interface.encodeFunctionData( 'createAndInitializePoolIfNecessary', - [await token0.getAddress(), await token1.getAddress(), ZERO_ADDRESS, encodePriceSqrt(1, 1)] + [await token0.getAddress(), await token1.getAddress(), ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'] ); await nft.multicall([createAndInitializePoolIfNecessaryData], { value: expandTo18Decimals(1) }); }); it('gas [ @skip-on-coverage ]', async () => { - await snapshotGasCost(nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1))); + await snapshotGasCost(nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x')); }); }); @@ -160,7 +160,7 @@ describe('NonfungiblePositionManager', () => { }); it('fails if cannot transfer', async () => { - await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1)); + await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'); await tokens[0].approve(nft, 0); await expect( nft.mint({ @@ -180,7 +180,7 @@ describe('NonfungiblePositionManager', () => { }); it('fails if deadline passed', async () => { - await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1)); + await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'); await nft.setTime(2); await expect( nft.mint({ @@ -204,7 +204,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ token0: tokens[0].getAddress(), @@ -253,7 +254,8 @@ describe('NonfungiblePositionManager', () => { await token0.getAddress(), await token1.getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1), + encodePriceSqrt(1, 1), + '0x' ]); const mintData = nft.interface.encodeFunctionData('mint', [ @@ -293,7 +295,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await snapshotGasCost( @@ -315,7 +318,7 @@ describe('NonfungiblePositionManager', () => { it('gas first mint for pool using eth with zero refund [ @skip-on-coverage ]', async () => { const [token0, token1] = await sortedTokens(wnative, tokens[0]); - await nft.createAndInitializePoolIfNecessary(token0, token1, ZERO_ADDRESS, encodePriceSqrt(1, 1)); + await nft.createAndInitializePoolIfNecessary(token0, token1, ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'); await snapshotGasCost( nft.multicall( @@ -344,7 +347,7 @@ describe('NonfungiblePositionManager', () => { it('gas first mint for pool using eth with non-zero refund [ @skip-on-coverage ]', async () => { const [token0, token1] = await sortedTokens(wnative, tokens[0]); - await nft.createAndInitializePoolIfNecessary(token0, token1, ZERO_ADDRESS, encodePriceSqrt(1, 1)); + await nft.createAndInitializePoolIfNecessary(token0, token1, ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'); await snapshotGasCost( nft.multicall( @@ -372,7 +375,7 @@ describe('NonfungiblePositionManager', () => { }); it('gas mint on same ticks [ @skip-on-coverage ]', async () => { - await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1)); + await nft.createAndInitializePoolIfNecessary(tokens[0], tokens[1], ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'); await nft.mint({ token0: await tokens[0].getAddress(), @@ -410,7 +413,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -452,7 +456,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -523,7 +528,7 @@ describe('NonfungiblePositionManager', () => { const tokenId = 1; - await nft.createAndInitializePoolIfNecessary(token0, token1, ZERO_ADDRESS, encodePriceSqrt(1, 1)); + await nft.createAndInitializePoolIfNecessary(token0, token1, ZERO_ADDRESS, encodePriceSqrt(1, 1), '0x'); const mintData = nft.interface.encodeFunctionData('mint', [ { @@ -577,7 +582,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -701,7 +707,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -849,7 +856,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -930,7 +938,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -986,7 +995,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -1051,7 +1061,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -1111,7 +1122,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -1200,7 +1212,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ @@ -1240,7 +1253,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); // nft 1 earns 25% of fees await nft.mint({ @@ -1297,7 +1311,6 @@ describe('NonfungiblePositionManager', () => { amount0Max: MaxUint128, amount1Max: MaxUint128, }); - console.log(nft1Amount0.toString(), nft1Amount1.toString(), nft2Amount0.toString(), nft2Amount1.toString()); expect(nft1Amount0).to.eq(416); expect(nft1Amount1).to.eq(0); expect(nft2Amount0).to.eq(1250); @@ -1343,7 +1356,8 @@ describe('NonfungiblePositionManager', () => { tokens[0].getAddress(), tokens[1].getAddress(), ZERO_ADDRESS, - encodePriceSqrt(1, 1) + encodePriceSqrt(1, 1), + '0x' ); await nft.mint({ diff --git a/src/periphery/test/QuoterV2.spec.ts b/src/periphery/test/QuoterV2.spec.ts index c478d687..4c963e94 100644 --- a/src/periphery/test/QuoterV2.spec.ts +++ b/src/periphery/test/QuoterV2.spec.ts @@ -85,21 +85,21 @@ describe('QuoterV2', function () { describe('#quoteExactInput', () => { it('0 -> 2 cross 2 tick', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 10000); ////await snapshotGasCost(gasEstimate) expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('78459826284680823468887704103'); expect(initializedTicksCrossedList[0]).to.eq(2); - expect(amountIn).to.eq(10000); - expect(amountOut).to.eq(9897); + expect(amountInList[0]).to.eq(10000); + expect(amountOutList[0]).to.eq(9897); }); it('0 -> 2 cross 2 tick where after is initialized', async () => { // The swap amount is set such that the active tick after the swap is -120. // -120 is an initialized tick for this pool. We check that we don't count it. - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 6200); ////await snapshotGasCost(gasEstimate) @@ -107,52 +107,52 @@ describe('QuoterV2', function () { expect(sqrtPriceX96AfterList[0]).to.eq('78755992497053066283316544500'); expect(initializedTicksCrossedList.length).to.eq(1); expect(initializedTicksCrossedList[0]).to.eq(1); - expect(amountOut).to.eq(6158); - expect(amountIn).to.eq(6200); + expect(amountOutList[0]).to.eq(6158); + expect(amountInList[0]).to.eq(6200); }); it('0 -> 2 cross 1 tick', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 4000); ////await snapshotGasCost(gasEstimate) expect(initializedTicksCrossedList[0]).to.eq(1); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('78925679077027744088480448931'); - expect(amountOut).to.eq(3981); - expect(amountIn).to.eq(4000); + expect(amountOutList[0]).to.eq(3981); + expect(amountInList[0]).to.eq(4000); }); it('0 -> 2 cross 0 tick, starting tick not initialized', async () => { // Tick before 0, tick after -1. - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 10); ////await snapshotGasCost(gasEstimate) expect(initializedTicksCrossedList[0]).to.eq(0); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79227483487511329217250071027'); - expect(amountOut).to.eq(8); - expect(amountIn).to.eq(10); + expect(amountOutList[0]).to.eq(8); + expect(amountInList[0]).to.eq(10); }); it('0 -> 2 cross 0 tick, starting tick initialized', async () => { // Tick before 0, tick after -1. Tick 0 initialized. await createPoolWithZeroTickInitialized(nft, wallet, tokens[0].address, tokens[2].address); - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 10); ////await snapshotGasCost(gasEstimate) expect(initializedTicksCrossedList[0]).to.eq(1); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79227817515327498931091950511'); - expect(amountOut).to.eq(8); - expect(amountIn).to.eq(10); + expect(amountOutList[0]).to.eq(8); + expect(amountInList[0]).to.eq(10); }); it('2 -> 0 cross 2', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 10000); ////await snapshotGasCost(gasEstimate) @@ -160,32 +160,31 @@ describe('QuoterV2', function () { expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('80004022856373268738318816658'); expect(initializedTicksCrossedList.length).to.eq(1); - expect(amountOut).to.eq(9897); - expect(amountIn).to.eq(10000); + expect(amountOutList[0]).to.eq(9897); + expect(amountInList[0]).to.eq(10000); }); it('2 -> 0 cross 2 where tick after is initialized', async () => { // The swap amount is set such that the active tick after the swap is 120. // 120 is an initialized tick for this pool. We check we don't count it. - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 6250); ////await snapshotGasCost(gasEstimate) - console.log(sqrtPriceX96AfterList[0].toString()); expect(initializedTicksCrossedList[0]).to.eq(2); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79706996475107291736680620388'); expect(initializedTicksCrossedList.length).to.eq(1); - expect(amountOut).to.eq(6206); - expect(amountIn).to.eq(6250); + expect(amountOutList[0]).to.eq(6206); + expect(amountInList[0]).to.eq(6250); }); it('2 -> 0 cross 0 tick, starting tick initialized', async () => { // Tick 0 initialized. Tick after = 1 await createPoolWithZeroTickInitialized(nft, wallet, tokens[0].address, tokens[2].address); - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 200); ////await snapshotGasCost(gasEstimate) @@ -193,13 +192,13 @@ describe('QuoterV2', function () { expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79235729830182478001034429156'); expect(initializedTicksCrossedList.length).to.eq(1); - expect(amountOut).to.eq(198); - expect(amountIn).to.eq(200); + expect(amountOutList[0]).to.eq(198); + expect(amountInList[0]).to.eq(200); }); it('2 -> 0 cross 0 tick, starting tick not initialized', async () => { // Tick 0 initialized. Tick after = 1 - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 103); ////await snapshotGasCost(gasEstimate) @@ -207,12 +206,12 @@ describe('QuoterV2', function () { expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79235858216754624215638319723'); expect(initializedTicksCrossedList.length).to.eq(1); - expect(amountOut).to.eq(101); - expect(amountIn).to.eq(103); + expect(amountOutList[0]).to.eq(101); + expect(amountInList[0]).to.eq(103); }); it('2 -> 1', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall(encodePath([path[4], path[3], path[2]]), 10000); @@ -220,12 +219,12 @@ describe('QuoterV2', function () { expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('80020047998594409647791422119'); expect(initializedTicksCrossedList[0]).to.eq(0); - expect(amountOut).to.eq(9896); - expect(amountIn).to.eq(10000); + expect(amountOutList[0]).to.eq(9896); + expect(amountInList[0]).to.eq(10000); }); it('0 -> 2 -> 1', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactInput.staticCall( encodePath([path[0], ZERO_ADDRESS, path[4], path[3], path[2]]), 10000 @@ -237,8 +236,8 @@ describe('QuoterV2', function () { expect(sqrtPriceX96AfterList[1]).to.eq('80011887497855440421019287092'); expect(initializedTicksCrossedList[0]).to.eq(2); expect(initializedTicksCrossedList[1]).to.eq(0); - expect(amountOut).to.eq(9795); - expect(amountIn).to.eq(10000); + expect(amountOutList[1]).to.eq(9795); + expect(amountInList[0]).to.eq(10000); }); }); @@ -339,13 +338,13 @@ describe('QuoterV2', function () { describe('#quoteExactOutput', () => { it('0 -> 2 cross 2 tick', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 15000); expect(initializedTicksCrossedList.length).to.eq(1); expect(initializedTicksCrossedList[0]).to.eq(2); - expect(amountIn).to.eq(15234); - expect(amountOut).to.be.eq(15000); + expect(amountInList[0]).to.eq(15234); + expect(amountOutList[0]).to.be.eq(15000); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('78055527257643669242286029831'); @@ -354,25 +353,25 @@ describe('QuoterV2', function () { it('0 -> 2 cross 2 where tick after is initialized', async () => { // The swap amount is set such that the active tick after the swap is -120. // -120 is an initialized tick for this pool. We check that we count it. - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 6158); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('78756056567076985409608047254'); expect(initializedTicksCrossedList.length).to.eq(1); expect(initializedTicksCrossedList[0]).to.eq(1); - expect(amountIn).to.eq(6200); - expect(amountOut).to.be.eq(6158); + expect(amountInList[0]).to.eq(6200); + expect(amountOutList[0]).to.be.eq(6158); }); it('0 -> 2 cross 1 tick', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 4000); expect(initializedTicksCrossedList.length).to.eq(1); expect(initializedTicksCrossedList[0]).to.eq(1); - expect(amountIn).to.eq(4019); - expect(amountOut).to.be.eq(4000); + expect(amountInList[0]).to.eq(4019); + expect(amountOutList[0]).to.be.eq(4000); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('78924219757724709840818372098'); @@ -381,39 +380,39 @@ describe('QuoterV2', function () { it('0 -> 2 cross 0 tick starting tick initialized', async () => { // Tick before 0, tick after 1. Tick 0 initialized. await createPoolWithZeroTickInitialized(nft, wallet, tokens[0].address, tokens[2].address); - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 100); expect(initializedTicksCrossedList.length).to.eq(1); expect(initializedTicksCrossedList[0]).to.eq(1); - expect(amountIn).to.eq(102); - expect(amountOut).to.be.eq(100); + expect(amountInList[0]).to.eq(102); + expect(amountOutList[0]).to.be.eq(100); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79224329176051641448521403903'); }); it('0 -> 2 cross 0 tick starting tick not initialized', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[2].address, ZERO_ADDRESS, tokens[0].address]), 10); expect(initializedTicksCrossedList.length).to.eq(1); expect(initializedTicksCrossedList[0]).to.eq(0); - expect(amountIn).to.eq(12); - expect(amountOut).to.be.eq(10); + expect(amountInList[0]).to.eq(12); + expect(amountOutList[0]).to.be.eq(10); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79227408033628034983534698435'); }); it('2 -> 0 cross 2 ticks', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 15000); expect(initializedTicksCrossedList.length).to.eq(1); expect(initializedTicksCrossedList[0]).to.eq(2); - expect(amountIn).to.eq(15234); - expect(amountOut).to.be.eq(15000); + expect(amountInList[0]).to.eq(15234); + expect(amountOutList[0]).to.be.eq(15000); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('80418414376567919517220409857'); }); @@ -421,42 +420,42 @@ describe('QuoterV2', function () { it('2 -> 0 cross 2 where tick after is initialized', async () => { // The swap amount is set such that the active tick after the swap is 120. // 120 is an initialized tick for this pool. We check that we don't count it. - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 6223); expect(initializedTicksCrossedList[0]).to.eq(2); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79708304437530892332449657932'); expect(initializedTicksCrossedList.length).to.eq(1); - expect(amountIn).to.eq(6267); - expect(amountOut).to.be.eq(6223); + expect(amountInList[0]).to.eq(6267); + expect(amountOutList[0]).to.be.eq(6223); }); it('2 -> 0 cross 1 tick', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([tokens[0].address, ZERO_ADDRESS, tokens[2].address]), 6000); expect(initializedTicksCrossedList[0]).to.eq(1); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('79690640184021170956740081887'); expect(initializedTicksCrossedList.length).to.eq(1); - expect(amountIn).to.eq(6040); - expect(amountOut).to.be.eq(6000); + expect(amountInList[0]).to.eq(6040); + expect(amountOutList[0]).to.be.eq(6000); }); it('2 -> 1', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall(encodePath([path[2], path[3], path[4]]), 9897); expect(sqrtPriceX96AfterList.length).to.eq(1); expect(sqrtPriceX96AfterList[0]).to.eq('80020121658316697953186638498'); expect(initializedTicksCrossedList[0]).to.eq(0); - expect(amountIn).to.eq(10002); - expect(amountOut).to.be.eq(9897); + expect(amountInList[0]).to.eq(10002); + expect(amountOutList[0]).to.be.eq(9897); }); it('0 -> 2 -> 1', async () => { - const { amountOut, amountIn, sqrtPriceX96AfterList, initializedTicksCrossedList } = + const { amountOutList, amountInList, sqrtPriceX96AfterList, initializedTicksCrossedList } = await quoter.quoteExactOutput.staticCall( encodePath([path[0], ZERO_ADDRESS, path[4], path[3], path[2]].reverse()), 9795 @@ -467,8 +466,10 @@ describe('QuoterV2', function () { expect(sqrtPriceX96AfterList[1]).to.eq('78459828570953960157025884610'); expect(initializedTicksCrossedList[0]).to.eq(0); expect(initializedTicksCrossedList[1]).to.eq(2); - expect(amountIn).to.eq(10000); - expect(amountOut).to.be.eq(9795); + expect(amountInList[0]).to.eq(9897); + expect(amountInList[1]).to.eq(10000); + expect(amountOutList[0]).to.be.eq(9795); + expect(amountOutList[1]).to.eq(9897); }); describe('gas [ @skip-on-coverage ]', () => { diff --git a/src/periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap b/src/periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap index ff2e5228..447467e0 100644 --- a/src/periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap +++ b/src/periphery/test/__snapshots__/NonfungiblePositionManager.spec.ts.snap @@ -2,38 +2,38 @@ exports[`NonfungiblePositionManager #burn gas [ @skip-on-coverage ] 1`] = `62302`; -exports[`NonfungiblePositionManager #collect gas transfers both [ @skip-on-coverage ] 1`] = `125983`; +exports[`NonfungiblePositionManager #collect gas transfers both [ @skip-on-coverage ] 1`] = `126407`; -exports[`NonfungiblePositionManager #collect gas transfers token0 only [ @skip-on-coverage ] 1`] = `122321`; +exports[`NonfungiblePositionManager #collect gas transfers token0 only [ @skip-on-coverage ] 1`] = `122745`; -exports[`NonfungiblePositionManager #collect gas transfers token1 only [ @skip-on-coverage ] 1`] = `122512`; +exports[`NonfungiblePositionManager #collect gas transfers token1 only [ @skip-on-coverage ] 1`] = `122936`; -exports[`NonfungiblePositionManager #createAndInitializePoolIfNecessary gas [ @skip-on-coverage ] 1`] = `5277310`; +exports[`NonfungiblePositionManager #createAndInitializePoolIfNecessary gas [ @skip-on-coverage ] 1`] = `5231043`; -exports[`NonfungiblePositionManager #decreaseLiquidity gas complete decrease [ @skip-on-coverage ] 1`] = `171239`; +exports[`NonfungiblePositionManager #decreaseLiquidity gas complete decrease [ @skip-on-coverage ] 1`] = `171665`; -exports[`NonfungiblePositionManager #decreaseLiquidity gas partial decrease [ @skip-on-coverage ] 1`] = `176207`; +exports[`NonfungiblePositionManager #decreaseLiquidity gas partial decrease [ @skip-on-coverage ] 1`] = `176589`; -exports[`NonfungiblePositionManager #increaseLiquidity gas [ @skip-on-coverage ] 1`] = `182683`; +exports[`NonfungiblePositionManager #increaseLiquidity gas [ @skip-on-coverage ] 1`] = `184149`; -exports[`NonfungiblePositionManager #mint gas first mint for pool [ @skip-on-coverage ] 1`] = `635168`; +exports[`NonfungiblePositionManager #mint gas first mint for pool [ @skip-on-coverage ] 1`] = `636773`; -exports[`NonfungiblePositionManager #mint gas first mint for pool using eth with non-zero refund [ @skip-on-coverage ] 1`] = `649531`; +exports[`NonfungiblePositionManager #mint gas first mint for pool using eth with non-zero refund [ @skip-on-coverage ] 1`] = `651121`; -exports[`NonfungiblePositionManager #mint gas first mint for pool using eth with zero refund [ @skip-on-coverage ] 1`] = `642364`; +exports[`NonfungiblePositionManager #mint gas first mint for pool using eth with zero refund [ @skip-on-coverage ] 1`] = `643954`; -exports[`NonfungiblePositionManager #mint gas mint for same pool, different ticks [ @skip-on-coverage ] 1`] = `440868`; +exports[`NonfungiblePositionManager #mint gas mint for same pool, different ticks [ @skip-on-coverage ] 1`] = `442385`; -exports[`NonfungiblePositionManager #mint gas mint on same ticks [ @skip-on-coverage ] 1`] = `330678`; +exports[`NonfungiblePositionManager #mint gas mint on same ticks [ @skip-on-coverage ] 1`] = `332156`; -exports[`NonfungiblePositionManager #permit owned by eoa gas [ @skip-on-coverage ] 1`] = `60014`; +exports[`NonfungiblePositionManager #permit owned by eoa gas [ @skip-on-coverage ] 1`] = `60003`; -exports[`NonfungiblePositionManager #permit owned by verifying contract gas [ @skip-on-coverage ] 1`] = `63880`; +exports[`NonfungiblePositionManager #permit owned by verifying contract gas [ @skip-on-coverage ] 1`] = `63869`; exports[`NonfungiblePositionManager #transferFrom gas [ @skip-on-coverage ] 1`] = `86323`; exports[`NonfungiblePositionManager #transferFrom gas comes from approved [ @skip-on-coverage ] 1`] = `87247`; -exports[`NonfungiblePositionManager bytecode size [ @skip-on-coverage ] 1`] = `21901`; +exports[`NonfungiblePositionManager bytecode size [ @skip-on-coverage ] 1`] = `22015`; -exports[`NonfungiblePositionManager multicall exit gas [ @skip-on-coverage ] 1`] = `246963`; +exports[`NonfungiblePositionManager multicall exit gas [ @skip-on-coverage ] 1`] = `247432`; diff --git a/src/periphery/test/__snapshots__/QuoterV2.spec.ts.snap b/src/periphery/test/__snapshots__/QuoterV2.spec.ts.snap index 77df00a4..84325df3 100644 --- a/src/periphery/test/__snapshots__/QuoterV2.spec.ts.snap +++ b/src/periphery/test/__snapshots__/QuoterV2.spec.ts.snap @@ -1,29 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`QuoterV2 quotes #quoteExactInputSingle gas [ @skip-on-coverage ] 0 -> 2 1`] = `156869`; +exports[`QuoterV2 quotes #quoteExactInputSingle gas [ @skip-on-coverage ] 0 -> 2 1`] = `157987`; -exports[`QuoterV2 quotes #quoteExactInputSingle gas [ @skip-on-coverage ] 2 -> 0 1`] = `156805`; +exports[`QuoterV2 quotes #quoteExactInputSingle gas [ @skip-on-coverage ] 2 -> 0 1`] = `157893`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 -> 1 1`] = `248736`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 -> 1 1`] = `250721`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 0 tick starting tick initialized 1`] = `106435`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 0 tick starting tick initialized 1`] = `107424`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 0 tick starting tick not initialized 1`] = `91088`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 0 tick starting tick not initialized 1`] = `91954`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 1 tick 1`] = `126531`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 1 tick 1`] = `127520`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 2 tick 1`] = `156770`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 2 tick 1`] = `157864`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 2 where tick after is initialized 1`] = `126540`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 0 -> 2 cross 2 where tick after is initialized 1`] = `127529`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 0 cross 1 tick 1`] = `126874`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 0 cross 1 tick 1`] = `127884`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 0 cross 2 ticks 1`] = `157387`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 0 cross 2 ticks 1`] = `158499`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 0 cross 2 where tick after is initialized 1`] = `157391`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 0 cross 2 where tick after is initialized 1`] = `158503`; -exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 1 1`] = `91985`; +exports[`QuoterV2 quotes #quoteExactOutput gas [ @skip-on-coverage ] 2 -> 1 1`] = `92876`; -exports[`QuoterV2 quotes #quoteExactOutputSingle gas [ @skip-on-coverage ] 0 -> 1 1`] = `92069`; +exports[`QuoterV2 quotes #quoteExactOutputSingle gas [ @skip-on-coverage ] 0 -> 1 1`] = `92935`; -exports[`QuoterV2 quotes #quoteExactOutputSingle gas [ @skip-on-coverage ] 1 -> 0 1`] = `92086`; +exports[`QuoterV2 quotes #quoteExactOutputSingle gas [ @skip-on-coverage ] 1 -> 0 1`] = `92952`;