From 2ec2b3c5fba61a1bc51460f065cd06d407c0a9e3 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 12 Sep 2024 14:08:46 -0400 Subject: [PATCH 01/10] add exactOut cases to v4Planner --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 133 +++++++++++++++--------- sdks/v4-sdk/src/utils/v4Planner.ts | 33 ++++-- 2 files changed, 105 insertions(+), 61 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 1e21c17b1..32be9943d 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -1,6 +1,6 @@ import { BigNumber } from 'ethers' import JSBI from 'jsbi' -import { CurrencyAmount, TradeType, Token, WETH9 } from '@uniswap/sdk-core' +import { CurrencyAmount, Percent, TradeType, Token, WETH9 } from '@uniswap/sdk-core' import { encodeSqrtRatioX96, nearestUsableTick, TickMath } from '@uniswap/v3-sdk' import { Pool } from '../entities/pool' import { Trade } from '../entities/trade' @@ -56,61 +56,94 @@ describe('RouterPlanner', () => { planner = new V4Planner() }) - it('encodes a v4 exactInSingle swap', async () => { - planner.addAction(Actions.SWAP_EXACT_IN_SINGLE, [ - { - poolKey: USDC_WETH.poolKey, - zeroForOne: true, - amountIn: ONE_ETHER_BN, - amountOutMinimum: ONE_ETHER_BN.div(2), - sqrtPriceLimitX96: 0, - hookData: '0x', - }, - ]) - planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address]) + describe('addAction', () => { + it('encodes a v4 exactInSingle swap', async () => { + planner.addAction(Actions.SWAP_EXACT_IN_SINGLE, [ + { + poolKey: USDC_WETH.poolKey, + zeroForOne: true, + amountIn: ONE_ETHER_BN, + amountOutMinimum: ONE_ETHER_BN.div(2), + sqrtPriceLimitX96: 0, + hookData: '0x', + }, + ]) + planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address]) - expect(planner.actions).toEqual('0x0416') - expect(planner.params[0]).toEqual( - '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + expect(planner.actions).toEqual('0x0416') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) + }) }) - it('completes a v4 exactIn 2 hop swap', async () => { - const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) + describe('addTrade', () => { + it('completes a v4 exactIn 2 hop swap with same results as same addAction', async () => { + const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) - // encode with addAction function - planner.addAction(Actions.SWAP_EXACT_IN, [ - { - currencyIn: DAI.address, - path: encodeRouteToPath(route), - amountIn: ONE_ETHER_BN.toString(), - amountOutMinimum: 0, - }, - ]) - planner.addAction(Actions.SETTLE_TAKE_PAIR, [DAI.address, WETH9[1].address]) + // encode with addAction function + planner.addAction(Actions.SWAP_EXACT_IN, [ + { + currencyIn: DAI.address, + path: encodeRouteToPath(route), + amountIn: ONE_ETHER_BN.toString(), + amountOutMinimum: 0, + }, + ]) + planner.addAction(Actions.SETTLE_TAKE_PAIR, [DAI.address, WETH9[1].address]) - // encode with addTrade function - const tradePlanner = new V4Planner() - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), - TradeType.EXACT_INPUT - ) - tradePlanner.addTrade(trade) + // encode with addTrade function + const tradePlanner = new V4Planner() + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), + TradeType.EXACT_INPUT + ) + tradePlanner.addTrade(trade) - expect(planner.actions).toEqual('0x0516') - expect(planner.params[0]).toEqual( - '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + expect(planner.actions).toEqual('0x0516') + expect(planner.params[0]).toEqual( + '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) - expect(planner.actions).toEqual(tradePlanner.actions) - expect(planner.params[0]).toEqual(tradePlanner.params[0]) - expect(planner.params[1]).toEqual(tradePlanner.params[1]) + expect(planner.actions).toEqual(tradePlanner.actions) + expect(planner.params[0]).toEqual(tradePlanner.params[0]) + expect(planner.params[1]).toEqual(tradePlanner.params[1]) + }) + + it('completes a v4 exactOut 2 hop swap', async () => { + const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) + const slippageTolerance = new Percent('5') + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) + planner.addTrade(trade, slippageTolerance) + + expect(planner.actions).toEqual('0x0716') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) + }) + + it('throws an error if adding exactOut trade without slippage tolerance', async () => { + const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) + expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') + }) }) }) diff --git a/sdks/v4-sdk/src/utils/v4Planner.ts b/sdks/v4-sdk/src/utils/v4Planner.ts index 474182d33..6283f6625 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.ts @@ -1,3 +1,4 @@ +import invariant from 'tiny-invariant' import { defaultAbiCoder } from 'ethers/lib/utils' import { Currency, Percent, TradeType } from '@uniswap/sdk-core' import { Trade } from '../entities/trade' @@ -117,21 +118,31 @@ export class V4Planner { } addTrade(trade: Trade, slippageTolerance?: Percent): void { - const actionType = trade.tradeType === TradeType.EXACT_INPUT ? Actions.SWAP_EXACT_IN : Actions.SWAP_EXACT_OUT + const exactOutput = trade.tradeType === TradeType.EXACT_OUTPUT + + if (exactOutput) invariant(!!slippageTolerance, 'ExactOut requires slippageTolerance') + invariant(trade.swaps.length === 1, 'Only accepts Trades with 1 swap (must break swaps into individual trades)') + + const actionType = exactOutput ? Actions.SWAP_EXACT_OUT : Actions.SWAP_EXACT_IN const currencyIn = currencyAddress(trade.inputAmount.currency) const currencyOut = currencyAddress(trade.outputAmount.currency) - for (let swap of trade.swaps) { - this.addAction(actionType, [ - { - currencyIn, - path: encodeRouteToPath(swap.route), - amountIn: swap.inputAmount.quotient.toString(), - amountOutMinimum: slippageTolerance ? trade.minimumAmountOut(slippageTolerance).quotient.toString() : 0, - }, - ]) - } + this.addAction(actionType, [ + exactOutput + ? { + currencyOut, + path: encodeRouteToPath(trade.route, exactOutput), + amountInMaximum: trade.minimumAmountOut(slippageTolerance ?? new Percent(0)).quotient.toString(), + amountOut: trade.inputAmount.quotient.toString(), + } + : { + currencyIn, + path: encodeRouteToPath(trade.route, exactOutput), + amountIn: trade.inputAmount.quotient.toString(), + amountOutMinimum: slippageTolerance ? trade.minimumAmountOut(slippageTolerance).quotient.toString() : 0, + }, + ]) this.addAction(Actions.SETTLE_TAKE_PAIR, [currencyIn, currencyOut]) } From 7fb74aaad444bc7aea8801018d1403a16f5139c4 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 12 Sep 2024 14:24:04 -0400 Subject: [PATCH 02/10] test for 1 swap throw --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 102 ++++++++++++------------ 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 32be9943d..2b80c8a54 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -6,23 +6,29 @@ import { Pool } from '../entities/pool' import { Trade } from '../entities/trade' import { Route } from '../entities/route' import { encodeRouteToPath } from './encodeRouteToPath' -import { ADDRESS_ZERO, FEE_AMOUNT_MEDIUM, TICK_SPACING_TEN, ONE_ETHER, NEGATIVE_ONE } from '../internalConstants' +import { + ADDRESS_ZERO, + FEE_AMOUNT_MEDIUM, + TICK_SPACING_TEN, + ONE_ETHER, + NEGATIVE_ONE +} from '../internalConstants' import { Actions, V4Planner } from './v4Planner' const ONE_ETHER_BN = BigNumber.from(1).mul(10).pow(18) -const TICKLIST = [ - { - index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), - liquidityNet: ONE_ETHER, - liquidityGross: ONE_ETHER, - }, - { - index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), - liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), - liquidityGross: ONE_ETHER, - }, -] +const TICKLIST = [ + { + index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), + liquidityNet: ONE_ETHER, + liquidityGross: ONE_ETHER, + }, + { + index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), + liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), + liquidityGross: ONE_ETHER, + }, + ] const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD Coin') const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin') @@ -48,6 +54,17 @@ const DAI_USDC = new Pool( 0, TICKLIST ) +const DAI_WETH = new Pool( + WETH9[1], + DAI, + FEE_AMOUNT_MEDIUM, + TICK_SPACING_TEN, + ADDRESS_ZERO, + encodeSqrtRatioX96(1, 1), + 0, + 0, + TICKLIST +) describe('RouterPlanner', () => { let planner: V4Planner @@ -71,12 +88,8 @@ describe('RouterPlanner', () => { planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address]) expect(planner.actions).toEqual('0x0416') - expect(planner.params[0]).toEqual( - '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[1]).toEqual('0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') }) }) @@ -97,52 +110,41 @@ describe('RouterPlanner', () => { // encode with addTrade function const tradePlanner = new V4Planner() - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), - TradeType.EXACT_INPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), TradeType.EXACT_INPUT) tradePlanner.addTrade(trade) expect(planner.actions).toEqual('0x0516') - expect(planner.params[0]).toEqual( - '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) - - expect(planner.actions).toEqual(tradePlanner.actions) - expect(planner.params[0]).toEqual(tradePlanner.params[0]) - expect(planner.params[1]).toEqual(tradePlanner.params[1]) + expect(planner.params[0]).toEqual('0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') + + expect(planner.actions).toEqual(tradePlanner.actions) + expect(planner.params[0]).toEqual(tradePlanner.params[0]) + expect(planner.params[1]).toEqual(tradePlanner.params[1]) }) it('completes a v4 exactOut 2 hop swap', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const slippageTolerance = new Percent('5') - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), - TradeType.EXACT_OUTPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) planner.addTrade(trade, slippageTolerance) expect(planner.actions).toEqual('0x0716') - expect(planner.params[0]).toEqual( - '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') }) it('throws an error if adding exactOut trade without slippage tolerance', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), - TradeType.EXACT_OUTPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) + expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') + }) + + + it('throws an error if adding exactOut trade without slippage tolerance', async () => { + const amount = CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()) + const route1 = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) + const route2 = new Route([DAI_WETH], DAI, WETH9[1]) + const trade = await Trade.fromRoutes([{ route: route1, amount }, { route: route2, amount }], TradeType.EXACT_OUTPUT) expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') }) }) From 3b74bde8413af84b0053a06bdf1bbf7c43dd3c59 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 12 Sep 2024 14:31:40 -0400 Subject: [PATCH 03/10] lint --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 96 ++++++++++++++++--------- 1 file changed, 61 insertions(+), 35 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 2b80c8a54..4b519684c 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -6,29 +6,23 @@ import { Pool } from '../entities/pool' import { Trade } from '../entities/trade' import { Route } from '../entities/route' import { encodeRouteToPath } from './encodeRouteToPath' -import { - ADDRESS_ZERO, - FEE_AMOUNT_MEDIUM, - TICK_SPACING_TEN, - ONE_ETHER, - NEGATIVE_ONE -} from '../internalConstants' +import { ADDRESS_ZERO, FEE_AMOUNT_MEDIUM, TICK_SPACING_TEN, ONE_ETHER, NEGATIVE_ONE } from '../internalConstants' import { Actions, V4Planner } from './v4Planner' const ONE_ETHER_BN = BigNumber.from(1).mul(10).pow(18) -const TICKLIST = [ - { - index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), - liquidityNet: ONE_ETHER, - liquidityGross: ONE_ETHER, - }, - { - index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), - liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), - liquidityGross: ONE_ETHER, - }, - ] +const TICKLIST = [ + { + index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), + liquidityNet: ONE_ETHER, + liquidityGross: ONE_ETHER, + }, + { + index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), + liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), + liquidityGross: ONE_ETHER, + }, +] const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD Coin') const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin') @@ -88,8 +82,12 @@ describe('RouterPlanner', () => { planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address]) expect(planner.actions).toEqual('0x0416') - expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000') - expect(planner.params[1]).toEqual('0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) }) }) @@ -110,42 +108,70 @@ describe('RouterPlanner', () => { // encode with addTrade function const tradePlanner = new V4Planner() - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), TradeType.EXACT_INPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), + TradeType.EXACT_INPUT + ) tradePlanner.addTrade(trade) expect(planner.actions).toEqual('0x0516') - expect(planner.params[0]).toEqual('0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') - expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') - - expect(planner.actions).toEqual(tradePlanner.actions) - expect(planner.params[0]).toEqual(tradePlanner.params[0]) - expect(planner.params[1]).toEqual(tradePlanner.params[1]) + expect(planner.params[0]).toEqual( + '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) + + expect(planner.actions).toEqual(tradePlanner.actions) + expect(planner.params[0]).toEqual(tradePlanner.params[0]) + expect(planner.params[1]).toEqual(tradePlanner.params[1]) }) it('completes a v4 exactOut 2 hop swap', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const slippageTolerance = new Percent('5') - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) planner.addTrade(trade, slippageTolerance) expect(planner.actions).toEqual('0x0716') - expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') - expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) }) it('throws an error if adding exactOut trade without slippage tolerance', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') }) - it('throws an error if adding exactOut trade without slippage tolerance', async () => { + const slippageTolerance = new Percent('5') const amount = CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()) const route1 = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const route2 = new Route([DAI_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoutes([{ route: route1, amount }, { route: route2, amount }], TradeType.EXACT_OUTPUT) - expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') + const trade = await Trade.fromRoutes( + [ + { route: route1, amount }, + { route: route2, amount }, + ], + TradeType.EXACT_OUTPUT + ) + expect(() => planner.addTrade(trade, slippageTolerance)).toThrow( + 'Only accepts Trades with 1 swap (must break swaps into individual trades)' + ) }) }) }) From 396ebfd2581b7c83b98a7298c928652600fc1022 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 12 Sep 2024 14:35:55 -0400 Subject: [PATCH 04/10] lint --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 94 +++++++++---------------- 1 file changed, 34 insertions(+), 60 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 4b519684c..010726f72 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -6,23 +6,29 @@ import { Pool } from '../entities/pool' import { Trade } from '../entities/trade' import { Route } from '../entities/route' import { encodeRouteToPath } from './encodeRouteToPath' -import { ADDRESS_ZERO, FEE_AMOUNT_MEDIUM, TICK_SPACING_TEN, ONE_ETHER, NEGATIVE_ONE } from '../internalConstants' +import { + ADDRESS_ZERO, + FEE_AMOUNT_MEDIUM, + TICK_SPACING_TEN, + ONE_ETHER, + NEGATIVE_ONE +} from '../internalConstants' import { Actions, V4Planner } from './v4Planner' const ONE_ETHER_BN = BigNumber.from(1).mul(10).pow(18) -const TICKLIST = [ - { - index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), - liquidityNet: ONE_ETHER, - liquidityGross: ONE_ETHER, - }, - { - index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), - liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), - liquidityGross: ONE_ETHER, - }, -] +const TICKLIST = [ + { + index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), + liquidityNet: ONE_ETHER, + liquidityGross: ONE_ETHER, + }, + { + index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), + liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), + liquidityGross: ONE_ETHER, + }, + ] const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD Coin') const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin') @@ -82,12 +88,8 @@ describe('RouterPlanner', () => { planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address]) expect(planner.actions).toEqual('0x0416') - expect(planner.params[0]).toEqual( - '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[1]).toEqual('0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') }) }) @@ -108,52 +110,32 @@ describe('RouterPlanner', () => { // encode with addTrade function const tradePlanner = new V4Planner() - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), - TradeType.EXACT_INPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), TradeType.EXACT_INPUT) tradePlanner.addTrade(trade) expect(planner.actions).toEqual('0x0516') - expect(planner.params[0]).toEqual( - '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) - - expect(planner.actions).toEqual(tradePlanner.actions) - expect(planner.params[0]).toEqual(tradePlanner.params[0]) - expect(planner.params[1]).toEqual(tradePlanner.params[1]) + expect(planner.params[0]).toEqual('0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') + + expect(planner.actions).toEqual(tradePlanner.actions) + expect(planner.params[0]).toEqual(tradePlanner.params[0]) + expect(planner.params[1]).toEqual(tradePlanner.params[1]) }) it('completes a v4 exactOut 2 hop swap', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const slippageTolerance = new Percent('5') - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), - TradeType.EXACT_OUTPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) planner.addTrade(trade, slippageTolerance) expect(planner.actions).toEqual('0x0716') - expect(planner.params[0]).toEqual( - '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') }) it('throws an error if adding exactOut trade without slippage tolerance', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), - TradeType.EXACT_OUTPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') }) @@ -162,16 +144,8 @@ describe('RouterPlanner', () => { const amount = CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()) const route1 = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const route2 = new Route([DAI_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoutes( - [ - { route: route1, amount }, - { route: route2, amount }, - ], - TradeType.EXACT_OUTPUT - ) - expect(() => planner.addTrade(trade, slippageTolerance)).toThrow( - 'Only accepts Trades with 1 swap (must break swaps into individual trades)' - ) + const trade = await Trade.fromRoutes([{ route: route1, amount }, { route: route2, amount }], TradeType.EXACT_OUTPUT) + expect(() => planner.addTrade(trade, slippageTolerance)).toThrow('Only accepts Trades with 1 swap (must break swaps into individual trades)') }) }) }) From f248edd63de742442a4408e7fe55aa99cbffdd10 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 19 Sep 2024 14:08:52 -0400 Subject: [PATCH 05/10] use maximumAmountIn function --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 2 +- sdks/v4-sdk/src/utils/v4Planner.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 010726f72..3013a1e27 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -129,7 +129,7 @@ describe('RouterPlanner', () => { planner.addTrade(trade, slippageTolerance) expect(planner.actions).toEqual('0x0716') - expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') }) diff --git a/sdks/v4-sdk/src/utils/v4Planner.ts b/sdks/v4-sdk/src/utils/v4Planner.ts index 6283f6625..e17e6e102 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.ts @@ -133,7 +133,7 @@ export class V4Planner { ? { currencyOut, path: encodeRouteToPath(trade.route, exactOutput), - amountInMaximum: trade.minimumAmountOut(slippageTolerance ?? new Percent(0)).quotient.toString(), + amountInMaximum: trade.maximumAmountIn(slippageTolerance ?? new Percent(0)).quotient.toString(), amountOut: trade.inputAmount.quotient.toString(), } : { From 51d8a0def423983a7b7a5b4702f5c40c9a17a320 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 19 Sep 2024 14:16:15 -0400 Subject: [PATCH 06/10] lint --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 94 ++++++++++++++++--------- 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 3013a1e27..23f9bb9ac 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -6,29 +6,23 @@ import { Pool } from '../entities/pool' import { Trade } from '../entities/trade' import { Route } from '../entities/route' import { encodeRouteToPath } from './encodeRouteToPath' -import { - ADDRESS_ZERO, - FEE_AMOUNT_MEDIUM, - TICK_SPACING_TEN, - ONE_ETHER, - NEGATIVE_ONE -} from '../internalConstants' +import { ADDRESS_ZERO, FEE_AMOUNT_MEDIUM, TICK_SPACING_TEN, ONE_ETHER, NEGATIVE_ONE } from '../internalConstants' import { Actions, V4Planner } from './v4Planner' const ONE_ETHER_BN = BigNumber.from(1).mul(10).pow(18) -const TICKLIST = [ - { - index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), - liquidityNet: ONE_ETHER, - liquidityGross: ONE_ETHER, - }, - { - index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), - liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), - liquidityGross: ONE_ETHER, - }, - ] +const TICKLIST = [ + { + index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), + liquidityNet: ONE_ETHER, + liquidityGross: ONE_ETHER, + }, + { + index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), + liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), + liquidityGross: ONE_ETHER, + }, +] const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD Coin') const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin') @@ -88,8 +82,12 @@ describe('RouterPlanner', () => { planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address]) expect(planner.actions).toEqual('0x0416') - expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000') - expect(planner.params[1]).toEqual('0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) }) }) @@ -110,32 +108,52 @@ describe('RouterPlanner', () => { // encode with addTrade function const tradePlanner = new V4Planner() - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), TradeType.EXACT_INPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), + TradeType.EXACT_INPUT + ) tradePlanner.addTrade(trade) expect(planner.actions).toEqual('0x0516') - expect(planner.params[0]).toEqual('0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') - expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') - - expect(planner.actions).toEqual(tradePlanner.actions) - expect(planner.params[0]).toEqual(tradePlanner.params[0]) - expect(planner.params[1]).toEqual(tradePlanner.params[1]) + expect(planner.params[0]).toEqual( + '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) + + expect(planner.actions).toEqual(tradePlanner.actions) + expect(planner.params[0]).toEqual(tradePlanner.params[0]) + expect(planner.params[1]).toEqual(tradePlanner.params[1]) }) it('completes a v4 exactOut 2 hop swap', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const slippageTolerance = new Percent('5') - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) planner.addTrade(trade, slippageTolerance) expect(planner.actions).toEqual('0x0716') - expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') - expect(planner.params[1]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) + expect(planner.params[1]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' + ) }) it('throws an error if adding exactOut trade without slippage tolerance', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') }) @@ -144,8 +162,16 @@ describe('RouterPlanner', () => { const amount = CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()) const route1 = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const route2 = new Route([DAI_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoutes([{ route: route1, amount }, { route: route2, amount }], TradeType.EXACT_OUTPUT) - expect(() => planner.addTrade(trade, slippageTolerance)).toThrow('Only accepts Trades with 1 swap (must break swaps into individual trades)') + const trade = await Trade.fromRoutes( + [ + { route: route1, amount }, + { route: route2, amount }, + ], + TradeType.EXACT_OUTPUT + ) + expect(() => planner.addTrade(trade, slippageTolerance)).toThrow( + 'Only accepts Trades with 1 swap (must break swaps into individual trades)' + ) }) }) }) From e1c33bd17f93a9a6ec55f0ad43034215b754af57 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 19 Sep 2024 15:49:02 -0400 Subject: [PATCH 07/10] add more granularity for take/settle, isntead of including it in trade --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 156 ++++++++++++++---------- sdks/v4-sdk/src/utils/v4Planner.ts | 19 ++- 2 files changed, 106 insertions(+), 69 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 23f9bb9ac..acd924e36 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -6,23 +6,29 @@ import { Pool } from '../entities/pool' import { Trade } from '../entities/trade' import { Route } from '../entities/route' import { encodeRouteToPath } from './encodeRouteToPath' -import { ADDRESS_ZERO, FEE_AMOUNT_MEDIUM, TICK_SPACING_TEN, ONE_ETHER, NEGATIVE_ONE } from '../internalConstants' +import { + ADDRESS_ZERO, + FEE_AMOUNT_MEDIUM, + TICK_SPACING_TEN, + ONE_ETHER, + NEGATIVE_ONE +} from '../internalConstants' import { Actions, V4Planner } from './v4Planner' const ONE_ETHER_BN = BigNumber.from(1).mul(10).pow(18) -const TICKLIST = [ - { - index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), - liquidityNet: ONE_ETHER, - liquidityGross: ONE_ETHER, - }, - { - index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), - liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), - liquidityGross: ONE_ETHER, - }, -] +const TICKLIST = [ + { + index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), + liquidityNet: ONE_ETHER, + liquidityGross: ONE_ETHER, + }, + { + index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), + liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), + liquidityGross: ONE_ETHER, + }, + ] const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD Coin') const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin') @@ -65,6 +71,7 @@ describe('RouterPlanner', () => { beforeEach(() => { planner = new V4Planner() + // console.log(planner) }) describe('addAction', () => { @@ -79,15 +86,9 @@ describe('RouterPlanner', () => { hookData: '0x', }, ]) - planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address]) - - expect(planner.actions).toEqual('0x0416') - expect(planner.params[0]).toEqual( - '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + + expect(planner.actions).toEqual('0x04') + expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000') }) }) @@ -104,56 +105,32 @@ describe('RouterPlanner', () => { amountOutMinimum: 0, }, ]) - planner.addAction(Actions.SETTLE_TAKE_PAIR, [DAI.address, WETH9[1].address]) // encode with addTrade function const tradePlanner = new V4Planner() - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), - TradeType.EXACT_INPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), TradeType.EXACT_INPUT) tradePlanner.addTrade(trade) - expect(planner.actions).toEqual('0x0516') - expect(planner.params[0]).toEqual( - '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) - - expect(planner.actions).toEqual(tradePlanner.actions) - expect(planner.params[0]).toEqual(tradePlanner.params[0]) - expect(planner.params[1]).toEqual(tradePlanner.params[1]) + expect(planner.actions).toEqual('0x05') + expect(planner.params[0]).toEqual('0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + + expect(planner.actions).toEqual(tradePlanner.actions) + expect(planner.params[0]).toEqual(tradePlanner.params[0]) }) it('completes a v4 exactOut 2 hop swap', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const slippageTolerance = new Percent('5') - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), - TradeType.EXACT_OUTPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) planner.addTrade(trade, slippageTolerance) - expect(planner.actions).toEqual('0x0716') - expect(planner.params[0]).toEqual( - '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' - ) - expect(planner.params[1]).toEqual( - '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' - ) + expect(planner.actions).toEqual('0x07') + expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') }) it('throws an error if adding exactOut trade without slippage tolerance', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoute( - route, - CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), - TradeType.EXACT_OUTPUT - ) + const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') }) @@ -162,16 +139,63 @@ describe('RouterPlanner', () => { const amount = CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()) const route1 = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const route2 = new Route([DAI_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoutes( - [ - { route: route1, amount }, - { route: route2, amount }, - ], - TradeType.EXACT_OUTPUT - ) - expect(() => planner.addTrade(trade, slippageTolerance)).toThrow( - 'Only accepts Trades with 1 swap (must break swaps into individual trades)' - ) + const trade = await Trade.fromRoutes([{ route: route1, amount }, { route: route2, amount }], TradeType.EXACT_OUTPUT) + expect(() => planner.addTrade(trade, slippageTolerance)).toThrow('Only accepts Trades with 1 swap (must break swaps into individual trades)') + }) + }) + + describe('addSettle', () => { + it('completes a settle without a specified amount', async () => { + const payerIsUser = true + planner.addSettle(DAI, payerIsUser) + + expect(planner.actions).toEqual('0x09') + expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001') + }) + + it('completes a settle with a specified amount', async () => { + const payerIsUser = true + const amount = BigNumber.from('8') + planner.addSettle(DAI, payerIsUser, amount) + + expect(planner.actions).toEqual('0x09') + expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001') + }) + + it('completes a settle with payerIsUser as false', async () => { + const payerIsUser = false + const amount = BigNumber.from('8') + planner.addSettle(DAI, payerIsUser, amount) + + expect(planner.actions).toEqual('0x09') + expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000') + }) + }) + + describe('addTrade', () => { + it('completes a take without a specified amount', async () => { + const routerMustCustody = true + planner.addTake(DAI, routerMustCustody) + + expect(planner.actions).toEqual('0x12') + expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000') + }) + + it('completes a take with a specified amount', async () => { + const routerMustCustody = true + const amount = BigNumber.from('8') + planner.addTake(DAI, routerMustCustody, amount) + + expect(planner.actions).toEqual('0x12') + expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008') + }) + + it('completes a take when router will not custody', async () => { + const routerMustCustody = false + planner.addTake(DAI, routerMustCustody) + + expect(planner.actions).toEqual('0x12') + expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000') }) }) }) diff --git a/sdks/v4-sdk/src/utils/v4Planner.ts b/sdks/v4-sdk/src/utils/v4Planner.ts index e17e6e102..1ad497b12 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.ts @@ -1,5 +1,6 @@ import invariant from 'tiny-invariant' import { defaultAbiCoder } from 'ethers/lib/utils' +import { BigNumber } from 'ethers' import { Currency, Percent, TradeType } from '@uniswap/sdk-core' import { Trade } from '../entities/trade' import { ADDRESS_ZERO } from '../internalConstants' @@ -92,9 +93,9 @@ const ABI_DEFINITION: { [key in Actions]: string[] } = { [Actions.SWAP_EXACT_OUT]: [SWAP_EXACT_OUT_STRUCT], // Payments commands - [Actions.SETTLE]: ['address', 'uint256', 'bool'], + [Actions.SETTLE]: ['address', 'uint256', 'bool'], // currency, amount, payerIsUser [Actions.SETTLE_ALL]: ['address', 'uint256'], - [Actions.TAKE]: ['address', 'address', 'uint256'], + [Actions.TAKE]: ['address', 'address', 'uint256'], // [Actions.TAKE_ALL]: ['address', 'uint256'], [Actions.TAKE_PORTION]: ['address', 'address', 'uint256'], [Actions.SETTLE_TAKE_PAIR]: ['address', 'address'], @@ -102,6 +103,10 @@ const ABI_DEFINITION: { [key in Actions]: string[] } = { [Actions.SWEEP]: ['address', 'address'], } +const FULL_DELTA_AMOUNT = 0 +const MSG_SENDER = '0x0000000000000000000000000000000000000001' +const ADDRESS_THIS = '0x0000000000000000000000000000000000000002' + export class V4Planner { actions: string params: string[] @@ -143,8 +148,16 @@ export class V4Planner { amountOutMinimum: slippageTolerance ? trade.minimumAmountOut(slippageTolerance).quotient.toString() : 0, }, ]) + } + + addSettle(currency: Currency, payerIsUser: boolean, amount?: BigNumber): void { + this.addAction(Actions.SETTLE, [currencyAddress(currency), amount ?? FULL_DELTA_AMOUNT, payerIsUser]) + } - this.addAction(Actions.SETTLE_TAKE_PAIR, [currencyIn, currencyOut]) + addTake(currency: Currency, routerMustCustody: boolean, amount?: BigNumber): void { + const receiver = routerMustCustody ? ADDRESS_THIS : MSG_SENDER + const takeAmount = amount ?? FULL_DELTA_AMOUNT + this.addAction(Actions.TAKE, [currencyAddress(currency), receiver, takeAmount]) } finalize(): string { From f1eb0868afc87a0683e8c4a9c3ccb467dad94ecf Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 19 Sep 2024 15:50:19 -0400 Subject: [PATCH 08/10] extra code comment + lint --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 102 ++++++++++++++++-------- sdks/v4-sdk/src/utils/v4Planner.ts | 2 +- 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index acd924e36..619823944 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -6,29 +6,23 @@ import { Pool } from '../entities/pool' import { Trade } from '../entities/trade' import { Route } from '../entities/route' import { encodeRouteToPath } from './encodeRouteToPath' -import { - ADDRESS_ZERO, - FEE_AMOUNT_MEDIUM, - TICK_SPACING_TEN, - ONE_ETHER, - NEGATIVE_ONE -} from '../internalConstants' +import { ADDRESS_ZERO, FEE_AMOUNT_MEDIUM, TICK_SPACING_TEN, ONE_ETHER, NEGATIVE_ONE } from '../internalConstants' import { Actions, V4Planner } from './v4Planner' const ONE_ETHER_BN = BigNumber.from(1).mul(10).pow(18) -const TICKLIST = [ - { - index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), - liquidityNet: ONE_ETHER, - liquidityGross: ONE_ETHER, - }, - { - index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), - liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), - liquidityGross: ONE_ETHER, - }, - ] +const TICKLIST = [ + { + index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN), + liquidityNet: ONE_ETHER, + liquidityGross: ONE_ETHER, + }, + { + index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN), + liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE), + liquidityGross: ONE_ETHER, + }, +] const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD Coin') const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin') @@ -88,7 +82,9 @@ describe('RouterPlanner', () => { ]) expect(planner.actions).toEqual('0x04') - expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000' + ) }) }) @@ -108,29 +104,45 @@ describe('RouterPlanner', () => { // encode with addTrade function const tradePlanner = new V4Planner() - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), TradeType.EXACT_INPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), + TradeType.EXACT_INPUT + ) tradePlanner.addTrade(trade) expect(planner.actions).toEqual('0x05') - expect(planner.params[0]).toEqual('0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[0]).toEqual( + '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) - expect(planner.actions).toEqual(tradePlanner.actions) - expect(planner.params[0]).toEqual(tradePlanner.params[0]) + expect(planner.actions).toEqual(tradePlanner.actions) + expect(planner.params[0]).toEqual(tradePlanner.params[0]) }) it('completes a v4 exactOut 2 hop swap', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const slippageTolerance = new Percent('5') - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) planner.addTrade(trade, slippageTolerance) expect(planner.actions).toEqual('0x07') - expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000' + ) }) it('throws an error if adding exactOut trade without slippage tolerance', async () => { const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT) + const trade = await Trade.fromRoute( + route, + CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), + TradeType.EXACT_OUTPUT + ) expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance') }) @@ -139,8 +151,16 @@ describe('RouterPlanner', () => { const amount = CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()) const route1 = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1]) const route2 = new Route([DAI_WETH], DAI, WETH9[1]) - const trade = await Trade.fromRoutes([{ route: route1, amount }, { route: route2, amount }], TradeType.EXACT_OUTPUT) - expect(() => planner.addTrade(trade, slippageTolerance)).toThrow('Only accepts Trades with 1 swap (must break swaps into individual trades)') + const trade = await Trade.fromRoutes( + [ + { route: route1, amount }, + { route: route2, amount }, + ], + TradeType.EXACT_OUTPUT + ) + expect(() => planner.addTrade(trade, slippageTolerance)).toThrow( + 'Only accepts Trades with 1 swap (must break swaps into individual trades)' + ) }) }) @@ -150,7 +170,9 @@ describe('RouterPlanner', () => { planner.addSettle(DAI, payerIsUser) expect(planner.actions).toEqual('0x09') - expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' + ) }) it('completes a settle with a specified amount', async () => { @@ -159,7 +181,9 @@ describe('RouterPlanner', () => { planner.addSettle(DAI, payerIsUser, amount) expect(planner.actions).toEqual('0x09') - expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001' + ) }) it('completes a settle with payerIsUser as false', async () => { @@ -168,7 +192,9 @@ describe('RouterPlanner', () => { planner.addSettle(DAI, payerIsUser, amount) expect(planner.actions).toEqual('0x09') - expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000' + ) }) }) @@ -178,7 +204,9 @@ describe('RouterPlanner', () => { planner.addTake(DAI, routerMustCustody) expect(planner.actions).toEqual('0x12') - expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000' + ) }) it('completes a take with a specified amount', async () => { @@ -187,7 +215,9 @@ describe('RouterPlanner', () => { planner.addTake(DAI, routerMustCustody, amount) expect(planner.actions).toEqual('0x12') - expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008' + ) }) it('completes a take when router will not custody', async () => { @@ -195,7 +225,9 @@ describe('RouterPlanner', () => { planner.addTake(DAI, routerMustCustody) expect(planner.actions).toEqual('0x12') - expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000') + expect(planner.params[0]).toEqual( + '0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000' + ) }) }) }) diff --git a/sdks/v4-sdk/src/utils/v4Planner.ts b/sdks/v4-sdk/src/utils/v4Planner.ts index 1ad497b12..63f8c8ae8 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.ts @@ -95,7 +95,7 @@ const ABI_DEFINITION: { [key in Actions]: string[] } = { // Payments commands [Actions.SETTLE]: ['address', 'uint256', 'bool'], // currency, amount, payerIsUser [Actions.SETTLE_ALL]: ['address', 'uint256'], - [Actions.TAKE]: ['address', 'address', 'uint256'], // + [Actions.TAKE]: ['address', 'address', 'uint256'], // currency, receiver, amount [Actions.TAKE_ALL]: ['address', 'uint256'], [Actions.TAKE_PORTION]: ['address', 'address', 'uint256'], [Actions.SETTLE_TAKE_PAIR]: ['address', 'address'], From 8d8d1e02d1075fc6aae36727f789e73a2bf39743 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 19 Sep 2024 16:23:13 -0400 Subject: [PATCH 09/10] add code comment --- sdks/v4-sdk/src/utils/v4Planner.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/sdks/v4-sdk/src/utils/v4Planner.ts b/sdks/v4-sdk/src/utils/v4Planner.ts index 63f8c8ae8..44d90fc91 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.ts @@ -125,6 +125,7 @@ export class V4Planner { addTrade(trade: Trade, slippageTolerance?: Percent): void { const exactOutput = trade.tradeType === TradeType.EXACT_OUTPUT + // exactInput we sometimes perform aggregated slippage checks, but not with exactOutput if (exactOutput) invariant(!!slippageTolerance, 'ExactOut requires slippageTolerance') invariant(trade.swaps.length === 1, 'Only accepts Trades with 1 swap (must break swaps into individual trades)') From 4677bb95b4af4d977fe29dc195863b0844e1cfb1 Mon Sep 17 00:00:00 2001 From: Emily Williams Date: Thu, 19 Sep 2024 16:27:01 -0400 Subject: [PATCH 10/10] remove console.log --- sdks/v4-sdk/src/utils/v4Planner.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/sdks/v4-sdk/src/utils/v4Planner.test.ts b/sdks/v4-sdk/src/utils/v4Planner.test.ts index 619823944..a78afc164 100644 --- a/sdks/v4-sdk/src/utils/v4Planner.test.ts +++ b/sdks/v4-sdk/src/utils/v4Planner.test.ts @@ -65,7 +65,6 @@ describe('RouterPlanner', () => { beforeEach(() => { planner = new V4Planner() - // console.log(planner) }) describe('addAction', () => {