@uniswap/router-sdk 1.0.0-beta.3 → 1.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,10 @@
1
+ # Alpha software
2
+
3
+ The latest version of the SDK is used in production in the Uniswap Interface,
4
+ but it is considered Alpha software and may contain bugs or change significantly between patch versions.
5
+ If you have questions about how to use the SDK, please reach out in the `#dev-chat` channel of the Discord.
6
+ Pull requests welcome!
7
+
8
+ # Uniswap Swap Router SDK
9
+
10
+ This SDK is meant to facilitate interactions with the contracts in [swap-router-contracts](https://github.com/Uniswap/swap-router-contracts).
@@ -2,11 +2,13 @@ import { Route as V2RouteSDK, Pair } from '@uniswap/v2-sdk';
2
2
  import { Route as V3RouteSDK, Pool } from '@uniswap/v3-sdk';
3
3
  import { Protocol } from './protocol';
4
4
  import { Currency, Price, Token } from '@uniswap/sdk-core';
5
- export interface IRoute<TInput extends Currency, TOutput extends Currency, TPool extends (Pool | Pair)> {
5
+ export interface IRoute<TInput extends Currency, TOutput extends Currency, TPool extends Pool | Pair> {
6
6
  protocol: Protocol;
7
7
  pools: TPool[];
8
8
  path: Token[];
9
9
  midPrice: Price<TInput, TOutput>;
10
+ input: TInput;
11
+ output: TOutput;
10
12
  }
11
13
  export declare class RouteV2<TInput extends Currency, TOutput extends Currency> extends V2RouteSDK<TInput, TOutput> implements IRoute<TInput, TOutput, Pair> {
12
14
  readonly protocol: Protocol;
@@ -1,9 +1,9 @@
1
1
  import { Currency, CurrencyAmount, Percent, Price, TradeType } from '@uniswap/sdk-core';
2
+ import { Pair, Route as V2RouteSDK } from '@uniswap/v2-sdk';
3
+ import { Pool, Route as V3RouteSDK } from '@uniswap/v3-sdk';
2
4
  import { IRoute } from './route';
3
- import { Route as V2RouteSDK, Pair } from '@uniswap/v2-sdk';
4
- import { Route as V3RouteSDK, Pool } from '@uniswap/v3-sdk';
5
5
  export declare class Trade<TInput extends Currency, TOutput extends Currency, TTradeType extends TradeType> {
6
- readonly routes: IRoute<TInput, TOutput, (Pair | Pool)>[];
6
+ readonly routes: IRoute<TInput, TOutput, Pair | Pool>[];
7
7
  readonly tradeType: TTradeType;
8
8
  private _outputAmount;
9
9
  private _inputAmount;
@@ -12,7 +12,7 @@ export declare class Trade<TInput extends Currency, TOutput extends Currency, TT
12
12
  * make up the trade. May consist of swaps in v2 or v3.
13
13
  */
14
14
  readonly swaps: {
15
- route: IRoute<TInput, TOutput, (Pair | Pool)>;
15
+ route: IRoute<TInput, TOutput, Pair | Pool>;
16
16
  inputAmount: CurrencyAmount<TInput>;
17
17
  outputAmount: CurrencyAmount<TOutput>;
18
18
  }[];
@@ -1,15 +1,15 @@
1
- import JSBI from 'jsbi';
2
1
  import { Interface } from '@ethersproject/abi';
3
- import { FeeOptions } from '@uniswap/v3-sdk';
4
2
  import { Token } from '@uniswap/sdk-core';
3
+ import { FeeOptions } from '@uniswap/v3-sdk';
4
+ import JSBI from 'jsbi';
5
5
  export declare abstract class PaymentsExtended {
6
6
  static INTERFACE: Interface;
7
7
  /**
8
8
  * Cannot be constructed.
9
9
  */
10
10
  private constructor();
11
- private static encodeFeeBips;
12
11
  static encodeUnwrapWETH9(amountMinimum: JSBI, recipient?: string, feeOptions?: FeeOptions): string;
13
12
  static encodeSweepToken(token: Token, amountMinimum: JSBI, recipient?: string, feeOptions?: FeeOptions): string;
14
13
  static encodePull(token: Token, amount: JSBI): string;
14
+ static encodeWrapETH(amount: JSBI): string;
15
15
  }
@@ -6,13 +6,13 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
6
6
 
7
7
  var JSBI = _interopDefault(require('jsbi'));
8
8
  var abi = require('@ethersproject/abi');
9
- var v3Sdk = require('@uniswap/v3-sdk');
10
9
  var IMulticallExtended_json = require('@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IMulticallExtended.sol/IMulticallExtended.json');
11
- var IPeripheryPaymentsWithFeeExtended_json = require('@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IPeripheryPaymentsWithFeeExtended.sol/IPeripheryPaymentsWithFeeExtended.json');
10
+ var v3Sdk = require('@uniswap/v3-sdk');
12
11
  var sdkCore = require('@uniswap/sdk-core');
13
- var invariant = _interopDefault(require('tiny-invariant'));
12
+ var IPeripheryPaymentsWithFeeExtended_json = require('@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IPeripheryPaymentsWithFeeExtended.sol/IPeripheryPaymentsWithFeeExtended.json');
14
13
  var ISwapRouter02_json = require('@uniswap/swap-router-contracts/artifacts/contracts/interfaces/ISwapRouter02.sol/ISwapRouter02.json');
15
14
  var v2Sdk = require('@uniswap/v2-sdk');
15
+ var invariant = _interopDefault(require('tiny-invariant'));
16
16
 
17
17
  var MSG_SENDER = '0x0000000000000000000000000000000000000000';
18
18
  var ADDRESS_THIS = '0x0000000000000000000000000000000000000001';
@@ -45,7 +45,7 @@ var MulticallExtended = /*#__PURE__*/function () {
45
45
  } // this means the validation value should be a previousBlockhash
46
46
 
47
47
 
48
- if (typeof validation === 'string') {
48
+ if (typeof validation === 'string' && validation.startsWith('0x')) {
49
49
  var previousBlockhash = validateAndParseBytes32(validation);
50
50
  return MulticallExtended.INTERFACE.encodeFunctionData('multicall(bytes32,bytes[])', [previousBlockhash, calldatas]);
51
51
  } else {
@@ -58,16 +58,16 @@ var MulticallExtended = /*#__PURE__*/function () {
58
58
  }();
59
59
  MulticallExtended.INTERFACE = /*#__PURE__*/new abi.Interface(IMulticallExtended_json.abi);
60
60
 
61
+ function encodeFeeBips(fee) {
62
+ return v3Sdk.toHex(fee.multiply(10000).quotient);
63
+ }
64
+
61
65
  var PaymentsExtended = /*#__PURE__*/function () {
62
66
  /**
63
67
  * Cannot be constructed.
64
68
  */
65
69
  function PaymentsExtended() {}
66
70
 
67
- PaymentsExtended.encodeFeeBips = function encodeFeeBips(fee) {
68
- return v3Sdk.toHex(fee.multiply(10000).quotient);
69
- };
70
-
71
71
  PaymentsExtended.encodeUnwrapWETH9 = function encodeUnwrapWETH9(amountMinimum, recipient, feeOptions) {
72
72
  // if there's a recipient, just pass it along
73
73
  if (typeof recipient === 'string') {
@@ -75,7 +75,7 @@ var PaymentsExtended = /*#__PURE__*/function () {
75
75
  }
76
76
 
77
77
  if (!!feeOptions) {
78
- var feeBips = this.encodeFeeBips(feeOptions.fee);
78
+ var feeBips = encodeFeeBips(feeOptions.fee);
79
79
  var feeRecipient = sdkCore.validateAndParseAddress(feeOptions.recipient);
80
80
  return PaymentsExtended.INTERFACE.encodeFunctionData('unwrapWETH9WithFee(uint256,uint256,address)', [v3Sdk.toHex(amountMinimum), feeBips, feeRecipient]);
81
81
  } else {
@@ -90,7 +90,7 @@ var PaymentsExtended = /*#__PURE__*/function () {
90
90
  }
91
91
 
92
92
  if (!!feeOptions) {
93
- var feeBips = this.encodeFeeBips(feeOptions.fee);
93
+ var feeBips = encodeFeeBips(feeOptions.fee);
94
94
  var feeRecipient = sdkCore.validateAndParseAddress(feeOptions.recipient);
95
95
  return PaymentsExtended.INTERFACE.encodeFunctionData('sweepTokenWithFee(address,uint256,uint256,address)', [token.address, v3Sdk.toHex(amountMinimum), feeBips, feeRecipient]);
96
96
  } else {
@@ -102,6 +102,10 @@ var PaymentsExtended = /*#__PURE__*/function () {
102
102
  return PaymentsExtended.INTERFACE.encodeFunctionData('pull', [token.address, v3Sdk.toHex(amount)]);
103
103
  };
104
104
 
105
+ PaymentsExtended.encodeWrapETH = function encodeWrapETH(amount) {
106
+ return PaymentsExtended.INTERFACE.encodeFunctionData('wrapETH', [v3Sdk.toHex(amount)]);
107
+ };
108
+
105
109
  return PaymentsExtended;
106
110
  }();
107
111
  PaymentsExtended.INTERFACE = /*#__PURE__*/new abi.Interface(IPeripheryPaymentsWithFeeExtended_json.abi);
@@ -212,6 +216,11 @@ function _createForOfIteratorHelperLoose(o, allowArrayLike) {
212
216
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
213
217
  }
214
218
 
219
+ (function (Protocol) {
220
+ Protocol["V2"] = "V2";
221
+ Protocol["V3"] = "V3";
222
+ })(exports.Protocol || (exports.Protocol = {}));
223
+
215
224
  function createCommonjsModule(fn, module) {
216
225
  return module = { exports: {} }, fn(module, module.exports), module.exports;
217
226
  }
@@ -972,11 +981,6 @@ try {
972
981
  }
973
982
  });
974
983
 
975
- (function (Protocol) {
976
- Protocol["V2"] = "V2";
977
- Protocol["V3"] = "V3";
978
- })(exports.Protocol || (exports.Protocol = {}));
979
-
980
984
  var RouteV2 = /*#__PURE__*/function (_V2RouteSDK) {
981
985
  _inheritsLoose(RouteV2, _V2RouteSDK);
982
986
 
@@ -1047,7 +1051,43 @@ var Trade = /*#__PURE__*/function () {
1047
1051
  });
1048
1052
  }
1049
1053
 
1050
- this.tradeType = tradeType;
1054
+ this.tradeType = tradeType; // each route must have the same input and output currency
1055
+
1056
+ var inputCurrency = this.swaps[0].inputAmount.currency;
1057
+ var outputCurrency = this.swaps[0].outputAmount.currency;
1058
+ !this.swaps.every(function (_ref2) {
1059
+ var route = _ref2.route;
1060
+ return inputCurrency.wrapped.equals(route.input.wrapped);
1061
+ }) ? invariant(false, 'INPUT_CURRENCY_MATCH') : void 0;
1062
+ !this.swaps.every(function (_ref3) {
1063
+ var route = _ref3.route;
1064
+ return outputCurrency.wrapped.equals(route.output.wrapped);
1065
+ }) ? invariant(false, 'OUTPUT_CURRENCY_MATCH') : void 0; // pools must be unique inter protocols
1066
+
1067
+ var numPools = this.swaps.map(function (_ref4) {
1068
+ var route = _ref4.route;
1069
+ return route.pools.length;
1070
+ }).reduce(function (total, cur) {
1071
+ return total + cur;
1072
+ }, 0);
1073
+ var poolAddressSet = new Set();
1074
+
1075
+ for (var _iterator3 = _createForOfIteratorHelperLoose(this.swaps), _step3; !(_step3 = _iterator3()).done;) {
1076
+ var _route2 = _step3.value.route;
1077
+
1078
+ for (var _iterator4 = _createForOfIteratorHelperLoose(_route2.pools), _step4; !(_step4 = _iterator4()).done;) {
1079
+ var pool = _step4.value;
1080
+
1081
+ if (_route2.protocol == exports.Protocol.V3) {
1082
+ poolAddressSet.add(v3Sdk.Pool.getAddress(pool.token0, pool.token1, pool.fee));
1083
+ } else {
1084
+ var pair = pool;
1085
+ poolAddressSet.add(v2Sdk.Pair.getAddress(pair.token0, pair.token1));
1086
+ }
1087
+ }
1088
+ }
1089
+
1090
+ !(numPools == poolAddressSet.size) ? invariant(false, 'POOLS_DUPLICATED') : void 0;
1051
1091
  }
1052
1092
 
1053
1093
  var _proto = Trade.prototype;
@@ -1105,7 +1145,7 @@ var Trade = /*#__PURE__*/function () {
1105
1145
 
1106
1146
  Trade.fromRoutes = /*#__PURE__*/function () {
1107
1147
  var _fromRoutes = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(v2Routes, v3Routes, tradeType) {
1108
- var populatedV2Routes, populatedV3Routes, _iterator3, _step3, _step3$value, routev2, amount, v2Trade, inputAmount, outputAmount, _iterator4, _step4, _step4$value, routev3, _amount, v3Trade, _inputAmount2, _outputAmount2;
1148
+ var populatedV2Routes, populatedV3Routes, _iterator5, _step5, _step5$value, routev2, amount, v2Trade, inputAmount, outputAmount, _iterator6, _step6, _step6$value, routev3, _amount, v3Trade, _inputAmount2, _outputAmount2;
1109
1149
 
1110
1150
  return runtime_1.wrap(function _callee$(_context) {
1111
1151
  while (1) {
@@ -1114,8 +1154,8 @@ var Trade = /*#__PURE__*/function () {
1114
1154
  populatedV2Routes = [];
1115
1155
  populatedV3Routes = [];
1116
1156
 
1117
- for (_iterator3 = _createForOfIteratorHelperLoose(v2Routes); !(_step3 = _iterator3()).done;) {
1118
- _step3$value = _step3.value, routev2 = _step3$value.routev2, amount = _step3$value.amount;
1157
+ for (_iterator5 = _createForOfIteratorHelperLoose(v2Routes); !(_step5 = _iterator5()).done;) {
1158
+ _step5$value = _step5.value, routev2 = _step5$value.routev2, amount = _step5$value.amount;
1119
1159
  v2Trade = new v2Sdk.Trade(routev2, amount, tradeType);
1120
1160
  inputAmount = v2Trade.inputAmount, outputAmount = v2Trade.outputAmount;
1121
1161
  populatedV2Routes.push({
@@ -1125,15 +1165,15 @@ var Trade = /*#__PURE__*/function () {
1125
1165
  });
1126
1166
  }
1127
1167
 
1128
- _iterator4 = _createForOfIteratorHelperLoose(v3Routes);
1168
+ _iterator6 = _createForOfIteratorHelperLoose(v3Routes);
1129
1169
 
1130
1170
  case 4:
1131
- if ((_step4 = _iterator4()).done) {
1171
+ if ((_step6 = _iterator6()).done) {
1132
1172
  _context.next = 13;
1133
1173
  break;
1134
1174
  }
1135
1175
 
1136
- _step4$value = _step4.value, routev3 = _step4$value.routev3, _amount = _step4$value.amount;
1176
+ _step6$value = _step6.value, routev3 = _step6$value.routev3, _amount = _step6$value.amount;
1137
1177
  _context.next = 8;
1138
1178
  return v3Sdk.Trade.fromRoute(routev3, _amount, tradeType);
1139
1179
 
@@ -1240,8 +1280,8 @@ var Trade = /*#__PURE__*/function () {
1240
1280
  }
1241
1281
 
1242
1282
  var inputCurrency = this.swaps[0].inputAmount.currency;
1243
- var totalInputFromRoutes = this.swaps.map(function (_ref2) {
1244
- var inputAmount = _ref2.inputAmount;
1283
+ var totalInputFromRoutes = this.swaps.map(function (_ref5) {
1284
+ var inputAmount = _ref5.inputAmount;
1245
1285
  return inputAmount;
1246
1286
  }).reduce(function (total, cur) {
1247
1287
  return total.add(cur);
@@ -1257,8 +1297,8 @@ var Trade = /*#__PURE__*/function () {
1257
1297
  }
1258
1298
 
1259
1299
  var outputCurrency = this.swaps[0].outputAmount.currency;
1260
- var totalOutputFromRoutes = this.swaps.map(function (_ref3) {
1261
- var outputAmount = _ref3.outputAmount;
1300
+ var totalOutputFromRoutes = this.swaps.map(function (_ref6) {
1301
+ var outputAmount = _ref6.outputAmount;
1262
1302
  return outputAmount;
1263
1303
  }).reduce(function (total, cur) {
1264
1304
  return total.add(cur);
@@ -1290,10 +1330,10 @@ var Trade = /*#__PURE__*/function () {
1290
1330
 
1291
1331
  var spotOutputAmount = sdkCore.CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0);
1292
1332
 
1293
- for (var _iterator5 = _createForOfIteratorHelperLoose(this.swaps), _step5; !(_step5 = _iterator5()).done;) {
1294
- var _step5$value = _step5.value,
1295
- route = _step5$value.route,
1296
- inputAmount = _step5$value.inputAmount;
1333
+ for (var _iterator7 = _createForOfIteratorHelperLoose(this.swaps), _step7; !(_step7 = _iterator7()).done;) {
1334
+ var _step7$value = _step7.value,
1335
+ route = _step7$value.route,
1336
+ inputAmount = _step7$value.inputAmount;
1297
1337
  var midPrice = route.midPrice;
1298
1338
  spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount));
1299
1339
  }
@@ -1307,7 +1347,6 @@ var Trade = /*#__PURE__*/function () {
1307
1347
  return Trade;
1308
1348
  }();
1309
1349
 
1310
- var ZERO$1 = /*#__PURE__*/JSBI.BigInt(0);
1311
1350
  /**
1312
1351
  * Represents the Uniswap V2 + V3 SwapRouter02, and has static methods for helping execute trades.
1313
1352
  */
@@ -1318,18 +1357,16 @@ var SwapRouter = /*#__PURE__*/function () {
1318
1357
  */
1319
1358
  function SwapRouter() {}
1320
1359
 
1321
- SwapRouter.encodeV2Swap = function encodeV2Swap(trade, options, routerMustCustody) {
1360
+ SwapRouter.encodeV2Swap = function encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
1322
1361
  var amountIn = v3Sdk.toHex(trade.maximumAmountIn(options.slippageTolerance).quotient);
1323
1362
  var amountOut = v3Sdk.toHex(trade.minimumAmountOut(options.slippageTolerance).quotient);
1324
1363
  var path = trade.route.path.map(function (token) {
1325
1364
  return token.address;
1326
1365
  });
1327
- var recipient = routerMustCustody ? ADDRESS_THIS : options.recipient ? sdkCore.validateAndParseAddress(options.recipient) : MSG_SENDER;
1366
+ var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : sdkCore.validateAndParseAddress(options.recipient);
1328
1367
 
1329
1368
  if (trade.tradeType === sdkCore.TradeType.EXACT_INPUT) {
1330
- var exactInputParams = [amountIn, // save gas by only passing slippage check if we can't check it later
1331
- // not a pure win, as sometimes this will cost us more when it would have caused an earlier failure
1332
- routerMustCustody ? 0 : amountOut, path, recipient];
1369
+ var exactInputParams = [amountIn, performAggregatedSlippageCheck ? 0 : amountOut, path, recipient];
1333
1370
  return SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams);
1334
1371
  } else {
1335
1372
  var exactOutputParams = [amountOut, amountIn, path, recipient];
@@ -1337,7 +1374,7 @@ var SwapRouter = /*#__PURE__*/function () {
1337
1374
  }
1338
1375
  };
1339
1376
 
1340
- SwapRouter.encodeV3Swap = function encodeV3Swap(trade, options, routerMustCustody) {
1377
+ SwapRouter.encodeV3Swap = function encodeV3Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
1341
1378
  var calldatas = [];
1342
1379
 
1343
1380
  for (var _iterator = _createForOfIteratorHelperLoose(trade.swaps), _step; !(_step = _iterator()).done;) {
@@ -1349,7 +1386,7 @@ var SwapRouter = /*#__PURE__*/function () {
1349
1386
  var amountOut = v3Sdk.toHex(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient); // flag for whether the trade is single hop or not
1350
1387
 
1351
1388
  var singleHop = route.pools.length === 1;
1352
- var recipient = routerMustCustody ? ADDRESS_THIS : options.recipient ? sdkCore.validateAndParseAddress(options.recipient) : MSG_SENDER;
1389
+ var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : sdkCore.validateAndParseAddress(options.recipient);
1353
1390
 
1354
1391
  if (singleHop) {
1355
1392
  if (trade.tradeType === sdkCore.TradeType.EXACT_INPUT) {
@@ -1359,7 +1396,7 @@ var SwapRouter = /*#__PURE__*/function () {
1359
1396
  fee: route.pools[0].fee,
1360
1397
  recipient: recipient,
1361
1398
  amountIn: amountIn,
1362
- amountOutMinimum: amountOut,
1399
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
1363
1400
  sqrtPriceLimitX96: 0
1364
1401
  };
1365
1402
  calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInputSingle', [exactInputSingleParams]));
@@ -1383,7 +1420,7 @@ var SwapRouter = /*#__PURE__*/function () {
1383
1420
  path: path,
1384
1421
  recipient: recipient,
1385
1422
  amountIn: amountIn,
1386
- amountOutMinimum: amountOut
1423
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut
1387
1424
  };
1388
1425
  calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInput', [exactInputParams]));
1389
1426
  } else {
@@ -1440,6 +1477,9 @@ var SwapRouter = /*#__PURE__*/function () {
1440
1477
  trades = [trades];
1441
1478
  }
1442
1479
 
1480
+ var numberOfTrades = trades.reduce(function (numberOfTrades, trade) {
1481
+ return numberOfTrades + (trade instanceof v3Sdk.Trade ? trade.swaps.length : 1);
1482
+ }, 0);
1443
1483
  var sampleTrade = trades[0]; // All trades should have the same starting/ending currency and trade type
1444
1484
 
1445
1485
  !trades.every(function (trade) {
@@ -1461,13 +1501,17 @@ var SwapRouter = /*#__PURE__*/function () {
1461
1501
  var outputIsNative = sampleTrade.outputAmount.currency.isNative; // flag for whether a refund needs to happen
1462
1502
  // 1. when paying in ETH, but with an uncertain input amount
1463
1503
 
1464
- var mustRefund = inputIsNative && sampleTrade.tradeType === sdkCore.TradeType.EXACT_OUTPUT; // flag for whether funds should be send first to the router
1504
+ var mustRefund = inputIsNative && sampleTrade.tradeType === sdkCore.TradeType.EXACT_OUTPUT; // flag for whether we want to perform an aggregated slippage check
1505
+ // 1. when there are >2 exact input trades. this is only a heuristic,
1506
+ // as it's still more gas-expensive even in this case, but has benefits
1507
+ // in that the reversion probability is lower
1508
+
1509
+ var performAggregatedSlippageCheck = sampleTrade.tradeType === sdkCore.TradeType.EXACT_INPUT && numberOfTrades > 2; // flag for whether funds should be send first to the router
1465
1510
  // 1. when receiving ETH (which much be unwrapped from WETH)
1466
1511
  // 2. when a fee on the output is being taken
1467
- // 3. when there are >1 exact input trades. this one isn't strictly necessary,
1468
- // but typically we want to perform an aggregated slippage check
1512
+ // 3. when performing an aggregated slippage check
1469
1513
 
1470
- var routerMustCustody = outputIsNative || !!options.fee || trades.length > 1 && sampleTrade.tradeType === sdkCore.TradeType.EXACT_INPUT;
1514
+ var routerMustCustody = outputIsNative || !!options.fee || performAggregatedSlippageCheck;
1471
1515
  var totalValue = inputIsNative ? trades.reduce(function (sum, trade) {
1472
1516
  return sum.add(trade.maximumAmountIn(options.slippageTolerance));
1473
1517
  }, ZERO_IN) : ZERO_IN; // encode permit if necessary
@@ -1481,25 +1525,21 @@ var SwapRouter = /*#__PURE__*/function () {
1481
1525
  var trade = _step3.value;
1482
1526
 
1483
1527
  if (trade instanceof v2Sdk.Trade) {
1484
- calldatas.push(SwapRouter.encodeV2Swap(trade, options, routerMustCustody));
1528
+ calldatas.push(SwapRouter.encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck));
1485
1529
  } else {
1486
- for (var _iterator4 = _createForOfIteratorHelperLoose(SwapRouter.encodeV3Swap(trade, options, routerMustCustody)), _step4; !(_step4 = _iterator4()).done;) {
1530
+ for (var _iterator4 = _createForOfIteratorHelperLoose(SwapRouter.encodeV3Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck)), _step4; !(_step4 = _iterator4()).done;) {
1487
1531
  var calldata = _step4.value;
1488
1532
  calldatas.push(calldata);
1489
1533
  }
1490
1534
  }
1491
- } // unwrap
1535
+ } // unwrap or sweep
1492
1536
 
1493
1537
 
1494
1538
  if (routerMustCustody) {
1495
- // if all trades are exact output, we can save gas by not passing a slippage check
1496
- var canOmitSlippageCheck = sampleTrade.tradeType === sdkCore.TradeType.EXACT_OUTPUT;
1497
- var amountNecessary = canOmitSlippageCheck ? ZERO$1 : totalAmountOut.quotient;
1498
-
1499
1539
  if (outputIsNative) {
1500
- calldatas.push(PaymentsExtended.encodeUnwrapWETH9(amountNecessary, options.recipient, options.fee));
1540
+ calldatas.push(PaymentsExtended.encodeUnwrapWETH9(totalAmountOut.quotient, options.recipient, options.fee));
1501
1541
  } else {
1502
- calldatas.push(PaymentsExtended.encodeSweepToken(sampleTrade.outputAmount.currency.wrapped, amountNecessary, options.recipient, options.fee));
1542
+ calldatas.push(PaymentsExtended.encodeSweepToken(sampleTrade.outputAmount.currency.wrapped, totalAmountOut.quotient, options.recipient, options.fee));
1503
1543
  }
1504
1544
  } // refund
1505
1545