Skip to content

Commit e1c33bd

Browse files
committed
add more granularity for take/settle, isntead of including it in trade
1 parent 51d8a0d commit e1c33bd

File tree

2 files changed

+106
-69
lines changed

2 files changed

+106
-69
lines changed

sdks/v4-sdk/src/utils/v4Planner.test.ts

Lines changed: 90 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,29 @@ import { Pool } from '../entities/pool'
66
import { Trade } from '../entities/trade'
77
import { Route } from '../entities/route'
88
import { encodeRouteToPath } from './encodeRouteToPath'
9-
import { ADDRESS_ZERO, FEE_AMOUNT_MEDIUM, TICK_SPACING_TEN, ONE_ETHER, NEGATIVE_ONE } from '../internalConstants'
9+
import {
10+
ADDRESS_ZERO,
11+
FEE_AMOUNT_MEDIUM,
12+
TICK_SPACING_TEN,
13+
ONE_ETHER,
14+
NEGATIVE_ONE
15+
} from '../internalConstants'
1016

1117
import { Actions, V4Planner } from './v4Planner'
1218

1319
const ONE_ETHER_BN = BigNumber.from(1).mul(10).pow(18)
14-
const TICKLIST = [
15-
{
16-
index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN),
17-
liquidityNet: ONE_ETHER,
18-
liquidityGross: ONE_ETHER,
19-
},
20-
{
21-
index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN),
22-
liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE),
23-
liquidityGross: ONE_ETHER,
24-
},
25-
]
20+
const TICKLIST = [
21+
{
22+
index: nearestUsableTick(TickMath.MIN_TICK, TICK_SPACING_TEN),
23+
liquidityNet: ONE_ETHER,
24+
liquidityGross: ONE_ETHER,
25+
},
26+
{
27+
index: nearestUsableTick(TickMath.MAX_TICK, TICK_SPACING_TEN),
28+
liquidityNet: JSBI.multiply(ONE_ETHER, NEGATIVE_ONE),
29+
liquidityGross: ONE_ETHER,
30+
},
31+
]
2632

2733
const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD Coin')
2834
const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'DAI Stablecoin')
@@ -65,6 +71,7 @@ describe('RouterPlanner', () => {
6571

6672
beforeEach(() => {
6773
planner = new V4Planner()
74+
// console.log(planner)
6875
})
6976

7077
describe('addAction', () => {
@@ -79,15 +86,9 @@ describe('RouterPlanner', () => {
7986
hookData: '0x',
8087
},
8188
])
82-
planner.addAction(Actions.SETTLE_TAKE_PAIR, [USDC.address, WETH9[1].address])
83-
84-
expect(planner.actions).toEqual('0x0416')
85-
expect(planner.params[0]).toEqual(
86-
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000'
87-
)
88-
expect(planner.params[1]).toEqual(
89-
'0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
90-
)
89+
90+
expect(planner.actions).toEqual('0x04')
91+
expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000')
9192
})
9293
})
9394

@@ -104,56 +105,32 @@ describe('RouterPlanner', () => {
104105
amountOutMinimum: 0,
105106
},
106107
])
107-
planner.addAction(Actions.SETTLE_TAKE_PAIR, [DAI.address, WETH9[1].address])
108108

109109
// encode with addTrade function
110110
const tradePlanner = new V4Planner()
111-
const trade = await Trade.fromRoute(
112-
route,
113-
CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()),
114-
TradeType.EXACT_INPUT
115-
)
111+
const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(DAI, ONE_ETHER.toString()), TradeType.EXACT_INPUT)
116112
tradePlanner.addTrade(trade)
117113

118-
expect(planner.actions).toEqual('0x0516')
119-
expect(planner.params[0]).toEqual(
120-
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000'
121-
)
122-
expect(planner.params[1]).toEqual(
123-
'0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
124-
)
125-
126-
expect(planner.actions).toEqual(tradePlanner.actions)
127-
expect(planner.params[0]).toEqual(tradePlanner.params[0])
128-
expect(planner.params[1]).toEqual(tradePlanner.params[1])
114+
expect(planner.actions).toEqual('0x05')
115+
expect(planner.params[0]).toEqual('0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000')
116+
117+
expect(planner.actions).toEqual(tradePlanner.actions)
118+
expect(planner.params[0]).toEqual(tradePlanner.params[0])
129119
})
130120

131121
it('completes a v4 exactOut 2 hop swap', async () => {
132122
const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1])
133123
const slippageTolerance = new Percent('5')
134-
const trade = await Trade.fromRoute(
135-
route,
136-
CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()),
137-
TradeType.EXACT_OUTPUT
138-
)
124+
const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT)
139125
planner.addTrade(trade, slippageTolerance)
140126

141-
expect(planner.actions).toEqual('0x0716')
142-
expect(planner.params[0]).toEqual(
143-
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000'
144-
)
145-
expect(planner.params[1]).toEqual(
146-
'0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
147-
)
127+
expect(planner.actions).toEqual('0x07')
128+
expect(planner.params[0]).toEqual('0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000bb8000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000')
148129
})
149130

150131
it('throws an error if adding exactOut trade without slippage tolerance', async () => {
151132
const route = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1])
152-
const trade = await Trade.fromRoute(
153-
route,
154-
CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()),
155-
TradeType.EXACT_OUTPUT
156-
)
133+
const trade = await Trade.fromRoute(route, CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString()), TradeType.EXACT_OUTPUT)
157134
expect(() => planner.addTrade(trade)).toThrow('ExactOut requires slippageTolerance')
158135
})
159136

@@ -162,16 +139,63 @@ describe('RouterPlanner', () => {
162139
const amount = CurrencyAmount.fromRawAmount(WETH9[1], ONE_ETHER.toString())
163140
const route1 = new Route([DAI_USDC, USDC_WETH], DAI, WETH9[1])
164141
const route2 = new Route([DAI_WETH], DAI, WETH9[1])
165-
const trade = await Trade.fromRoutes(
166-
[
167-
{ route: route1, amount },
168-
{ route: route2, amount },
169-
],
170-
TradeType.EXACT_OUTPUT
171-
)
172-
expect(() => planner.addTrade(trade, slippageTolerance)).toThrow(
173-
'Only accepts Trades with 1 swap (must break swaps into individual trades)'
174-
)
142+
const trade = await Trade.fromRoutes([{ route: route1, amount }, { route: route2, amount }], TradeType.EXACT_OUTPUT)
143+
expect(() => planner.addTrade(trade, slippageTolerance)).toThrow('Only accepts Trades with 1 swap (must break swaps into individual trades)')
144+
})
145+
})
146+
147+
describe('addSettle', () => {
148+
it('completes a settle without a specified amount', async () => {
149+
const payerIsUser = true
150+
planner.addSettle(DAI, payerIsUser)
151+
152+
expect(planner.actions).toEqual('0x09')
153+
expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001')
154+
})
155+
156+
it('completes a settle with a specified amount', async () => {
157+
const payerIsUser = true
158+
const amount = BigNumber.from('8')
159+
planner.addSettle(DAI, payerIsUser, amount)
160+
161+
expect(planner.actions).toEqual('0x09')
162+
expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001')
163+
})
164+
165+
it('completes a settle with payerIsUser as false', async () => {
166+
const payerIsUser = false
167+
const amount = BigNumber.from('8')
168+
planner.addSettle(DAI, payerIsUser, amount)
169+
170+
expect(planner.actions).toEqual('0x09')
171+
expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000')
172+
})
173+
})
174+
175+
describe('addTrade', () => {
176+
it('completes a take without a specified amount', async () => {
177+
const routerMustCustody = true
178+
planner.addTake(DAI, routerMustCustody)
179+
180+
expect(planner.actions).toEqual('0x12')
181+
expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000')
182+
})
183+
184+
it('completes a take with a specified amount', async () => {
185+
const routerMustCustody = true
186+
const amount = BigNumber.from('8')
187+
planner.addTake(DAI, routerMustCustody, amount)
188+
189+
expect(planner.actions).toEqual('0x12')
190+
expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008')
191+
})
192+
193+
it('completes a take when router will not custody', async () => {
194+
const routerMustCustody = false
195+
planner.addTake(DAI, routerMustCustody)
196+
197+
expect(planner.actions).toEqual('0x12')
198+
expect(planner.params[0]).toEqual('0x0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000')
175199
})
176200
})
177201
})

sdks/v4-sdk/src/utils/v4Planner.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import invariant from 'tiny-invariant'
22
import { defaultAbiCoder } from 'ethers/lib/utils'
3+
import { BigNumber } from 'ethers'
34
import { Currency, Percent, TradeType } from '@uniswap/sdk-core'
45
import { Trade } from '../entities/trade'
56
import { ADDRESS_ZERO } from '../internalConstants'
@@ -92,16 +93,20 @@ const ABI_DEFINITION: { [key in Actions]: string[] } = {
9293
[Actions.SWAP_EXACT_OUT]: [SWAP_EXACT_OUT_STRUCT],
9394

9495
// Payments commands
95-
[Actions.SETTLE]: ['address', 'uint256', 'bool'],
96+
[Actions.SETTLE]: ['address', 'uint256', 'bool'], // currency, amount, payerIsUser
9697
[Actions.SETTLE_ALL]: ['address', 'uint256'],
97-
[Actions.TAKE]: ['address', 'address', 'uint256'],
98+
[Actions.TAKE]: ['address', 'address', 'uint256'], //
9899
[Actions.TAKE_ALL]: ['address', 'uint256'],
99100
[Actions.TAKE_PORTION]: ['address', 'address', 'uint256'],
100101
[Actions.SETTLE_TAKE_PAIR]: ['address', 'address'],
101102
[Actions.CLOSE_CURRENCY]: ['address'],
102103
[Actions.SWEEP]: ['address', 'address'],
103104
}
104105

106+
const FULL_DELTA_AMOUNT = 0
107+
const MSG_SENDER = '0x0000000000000000000000000000000000000001'
108+
const ADDRESS_THIS = '0x0000000000000000000000000000000000000002'
109+
105110
export class V4Planner {
106111
actions: string
107112
params: string[]
@@ -143,8 +148,16 @@ export class V4Planner {
143148
amountOutMinimum: slippageTolerance ? trade.minimumAmountOut(slippageTolerance).quotient.toString() : 0,
144149
},
145150
])
151+
}
152+
153+
addSettle(currency: Currency, payerIsUser: boolean, amount?: BigNumber): void {
154+
this.addAction(Actions.SETTLE, [currencyAddress(currency), amount ?? FULL_DELTA_AMOUNT, payerIsUser])
155+
}
146156

147-
this.addAction(Actions.SETTLE_TAKE_PAIR, [currencyIn, currencyOut])
157+
addTake(currency: Currency, routerMustCustody: boolean, amount?: BigNumber): void {
158+
const receiver = routerMustCustody ? ADDRESS_THIS : MSG_SENDER
159+
const takeAmount = amount ?? FULL_DELTA_AMOUNT
160+
this.addAction(Actions.TAKE, [currencyAddress(currency), receiver, takeAmount])
148161
}
149162

150163
finalize(): string {

0 commit comments

Comments
 (0)