-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(v4-sdk): V4 planner accommodates exactOut + granular take/settles #97
Changes from all commits
2ec2b3c
9dd3851
7fb74aa
3b74bde
f423d7f
396ebfd
f248edd
51d8a0d
e1c33bd
f1eb086
8d8d1e0
66babef
4677bb9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +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' | ||
|
@@ -91,16 +93,20 @@ 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'], // currency, receiver, amount | ||
[Actions.TAKE_ALL]: ['address', 'uint256'], | ||
[Actions.TAKE_PORTION]: ['address', 'address', 'uint256'], | ||
[Actions.SETTLE_TAKE_PAIR]: ['address', 'address'], | ||
[Actions.CLOSE_CURRENCY]: ['address'], | ||
[Actions.SWEEP]: ['address', 'address'], | ||
} | ||
|
||
const FULL_DELTA_AMOUNT = 0 | ||
const MSG_SENDER = '0x0000000000000000000000000000000000000001' | ||
const ADDRESS_THIS = '0x0000000000000000000000000000000000000002' | ||
|
||
export class V4Planner { | ||
actions: string | ||
params: string[] | ||
|
@@ -117,23 +123,42 @@ export class V4Planner { | |
} | ||
|
||
addTrade(trade: Trade<Currency, Currency, TradeType>, 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 | ||
|
||
// exactInput we sometimes perform aggregated slippage checks, but not with exactOutput | ||
if (exactOutput) invariant(!!slippageTolerance, 'ExactOut requires slippageTolerance') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how come we only check this for exactOuput? just curious There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good question I can leave a comment. on exactInput sometimes we do agg slippage checks so we don't need to know slippage, but we enver do that on exactOutput |
||
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(Actions.SETTLE_TAKE_PAIR, [currencyIn, currencyOut]) | ||
this.addAction(actionType, [ | ||
exactOutput | ||
? { | ||
currencyOut, | ||
path: encodeRouteToPath(trade.route, exactOutput), | ||
amountInMaximum: trade.maximumAmountIn(slippageTolerance ?? new Percent(0)).quotient.toString(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it looks like on 128 we check that slippageTolerance is required? so can we just pass it in directly here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typescript gets mad There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hahah ok got it |
||
amountOut: trade.inputAmount.quotient.toString(), | ||
} | ||
: { | ||
currencyIn, | ||
path: encodeRouteToPath(trade.route, exactOutput), | ||
amountIn: trade.inputAmount.quotient.toString(), | ||
amountOutMinimum: slippageTolerance ? trade.minimumAmountOut(slippageTolerance).quotient.toString() : 0, | ||
}, | ||
]) | ||
} | ||
|
||
addSettle(currency: Currency, payerIsUser: boolean, amount?: BigNumber): void { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: should we add comment headers? |
||
this.addAction(Actions.SETTLE, [currencyAddress(currency), amount ?? FULL_DELTA_AMOUNT, payerIsUser]) | ||
} | ||
|
||
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 { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooh nice I made an ActionsConstant utils file, I can put these in there later when my PR gets merged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yah feel free to move around. this file is def pretty cray