@uniswap/router-sdk 1.0.0-beta.5 → 1.0.0

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.
@@ -1,15 +1,16 @@
1
1
  import JSBI from 'jsbi';
2
2
  import { Interface } from '@ethersproject/abi';
3
- import { Multicall, toHex, Payments, Route as Route$1, Trade as Trade$1, encodeRouteToPath, SelfPermit } from '@uniswap/v3-sdk';
4
3
  import { abi } from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IMulticallExtended.sol/IMulticallExtended.json';
4
+ import { Multicall, toHex, Payments, NonfungiblePositionManager, Route as Route$1, Pool, Trade as Trade$1, encodeRouteToPath, SelfPermit } from '@uniswap/v3-sdk';
5
+ import { validateAndParseAddress, TradeType, Fraction, CurrencyAmount, Price, Percent, WETH9 } from '@uniswap/sdk-core';
5
6
  import { abi as abi$1 } from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IPeripheryPaymentsWithFeeExtended.sol/IPeripheryPaymentsWithFeeExtended.json';
6
- import { validateAndParseAddress, TradeType, Fraction, CurrencyAmount, Price, Percent } from '@uniswap/sdk-core';
7
+ import { abi as abi$3 } from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/ISwapRouter02.sol/ISwapRouter02.json';
8
+ import { Route, Pair, Trade as Trade$2 } from '@uniswap/v2-sdk';
7
9
  import invariant from 'tiny-invariant';
8
- import { abi as abi$2 } from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/ISwapRouter02.sol/ISwapRouter02.json';
9
- import { Route, Trade as Trade$2 } from '@uniswap/v2-sdk';
10
+ import { abi as abi$2 } from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IApproveAndCall.sol/IApproveAndCall.json';
10
11
 
11
- var MSG_SENDER = '0x0000000000000000000000000000000000000000';
12
- var ADDRESS_THIS = '0x0000000000000000000000000000000000000001';
12
+ var MSG_SENDER = '0x0000000000000000000000000000000000000001';
13
+ var ADDRESS_THIS = '0x0000000000000000000000000000000000000002';
13
14
  var ZERO = /*#__PURE__*/JSBI.BigInt(0);
14
15
  var ONE = /*#__PURE__*/JSBI.BigInt(1);
15
16
 
@@ -52,16 +53,16 @@ var MulticallExtended = /*#__PURE__*/function () {
52
53
  }();
53
54
  MulticallExtended.INTERFACE = /*#__PURE__*/new Interface(abi);
54
55
 
56
+ function encodeFeeBips(fee) {
57
+ return toHex(fee.multiply(10000).quotient);
58
+ }
59
+
55
60
  var PaymentsExtended = /*#__PURE__*/function () {
56
61
  /**
57
62
  * Cannot be constructed.
58
63
  */
59
64
  function PaymentsExtended() {}
60
65
 
61
- PaymentsExtended.encodeFeeBips = function encodeFeeBips(fee) {
62
- return toHex(fee.multiply(10000).quotient);
63
- };
64
-
65
66
  PaymentsExtended.encodeUnwrapWETH9 = function encodeUnwrapWETH9(amountMinimum, recipient, feeOptions) {
66
67
  // if there's a recipient, just pass it along
67
68
  if (typeof recipient === 'string') {
@@ -69,7 +70,7 @@ var PaymentsExtended = /*#__PURE__*/function () {
69
70
  }
70
71
 
71
72
  if (!!feeOptions) {
72
- var feeBips = this.encodeFeeBips(feeOptions.fee);
73
+ var feeBips = encodeFeeBips(feeOptions.fee);
73
74
  var feeRecipient = validateAndParseAddress(feeOptions.recipient);
74
75
  return PaymentsExtended.INTERFACE.encodeFunctionData('unwrapWETH9WithFee(uint256,uint256,address)', [toHex(amountMinimum), feeBips, feeRecipient]);
75
76
  } else {
@@ -84,7 +85,7 @@ var PaymentsExtended = /*#__PURE__*/function () {
84
85
  }
85
86
 
86
87
  if (!!feeOptions) {
87
- var feeBips = this.encodeFeeBips(feeOptions.fee);
88
+ var feeBips = encodeFeeBips(feeOptions.fee);
88
89
  var feeRecipient = validateAndParseAddress(feeOptions.recipient);
89
90
  return PaymentsExtended.INTERFACE.encodeFunctionData('sweepTokenWithFee(address,uint256,uint256,address)', [token.address, toHex(amountMinimum), feeBips, feeRecipient]);
90
91
  } else {
@@ -96,6 +97,10 @@ var PaymentsExtended = /*#__PURE__*/function () {
96
97
  return PaymentsExtended.INTERFACE.encodeFunctionData('pull', [token.address, toHex(amount)]);
97
98
  };
98
99
 
100
+ PaymentsExtended.encodeWrapETH = function encodeWrapETH(amount) {
101
+ return PaymentsExtended.INTERFACE.encodeFunctionData('wrapETH', [toHex(amount)]);
102
+ };
103
+
99
104
  return PaymentsExtended;
100
105
  }();
101
106
  PaymentsExtended.INTERFACE = /*#__PURE__*/new Interface(abi$1);
@@ -206,6 +211,72 @@ function _createForOfIteratorHelperLoose(o, allowArrayLike) {
206
211
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
207
212
  }
208
213
 
214
+ var ApprovalTypes;
215
+
216
+ (function (ApprovalTypes) {
217
+ ApprovalTypes[ApprovalTypes["NOT_REQUIRED"] = 0] = "NOT_REQUIRED";
218
+ ApprovalTypes[ApprovalTypes["MAX"] = 1] = "MAX";
219
+ ApprovalTypes[ApprovalTypes["MAX_MINUS_ONE"] = 2] = "MAX_MINUS_ONE";
220
+ ApprovalTypes[ApprovalTypes["ZERO_THEN_MAX"] = 3] = "ZERO_THEN_MAX";
221
+ ApprovalTypes[ApprovalTypes["ZERO_THEN_MAX_MINUS_ONE"] = 4] = "ZERO_THEN_MAX_MINUS_ONE";
222
+ })(ApprovalTypes || (ApprovalTypes = {}));
223
+
224
+ var ApproveAndCall = /*#__PURE__*/function () {
225
+ /**
226
+ * Cannot be constructed.
227
+ */
228
+ function ApproveAndCall() {}
229
+
230
+ ApproveAndCall.encodeApproveMax = function encodeApproveMax(token) {
231
+ return ApproveAndCall.INTERFACE.encodeFunctionData('approveMax', [token.address]);
232
+ };
233
+
234
+ ApproveAndCall.encodeApproveMaxMinusOne = function encodeApproveMaxMinusOne(token) {
235
+ return ApproveAndCall.INTERFACE.encodeFunctionData('approveMaxMinusOne', [token.address]);
236
+ };
237
+
238
+ ApproveAndCall.encodeApproveZeroThenMax = function encodeApproveZeroThenMax(token) {
239
+ return ApproveAndCall.INTERFACE.encodeFunctionData('approveZeroThenMax', [token.address]);
240
+ };
241
+
242
+ ApproveAndCall.encodeApproveZeroThenMaxMinusOne = function encodeApproveZeroThenMaxMinusOne(token) {
243
+ return ApproveAndCall.INTERFACE.encodeFunctionData('approveZeroThenMaxMinusOne', [token.address]);
244
+ };
245
+
246
+ ApproveAndCall.encodeCallPositionManager = function encodeCallPositionManager(calldatas) {
247
+ !(calldatas.length > 0) ? process.env.NODE_ENV !== "production" ? invariant(false, 'NULL_CALLDATA') : invariant(false) : void 0;
248
+
249
+ if (calldatas.length == 1) {
250
+ return ApproveAndCall.INTERFACE.encodeFunctionData('callPositionManager', calldatas);
251
+ } else {
252
+ var encodedMulticall = NonfungiblePositionManager.INTERFACE.encodeFunctionData('multicall', [calldatas]);
253
+ return ApproveAndCall.INTERFACE.encodeFunctionData('callPositionManager', [encodedMulticall]);
254
+ }
255
+ };
256
+
257
+ ApproveAndCall.encodeApprove = function encodeApprove(token, approvalType) {
258
+ switch (approvalType) {
259
+ case ApprovalTypes.MAX:
260
+ return ApproveAndCall.encodeApproveMax(token.wrapped);
261
+
262
+ case ApprovalTypes.MAX_MINUS_ONE:
263
+ return ApproveAndCall.encodeApproveMaxMinusOne(token.wrapped);
264
+
265
+ case ApprovalTypes.ZERO_THEN_MAX:
266
+ return ApproveAndCall.encodeApproveZeroThenMax(token.wrapped);
267
+
268
+ case ApprovalTypes.ZERO_THEN_MAX_MINUS_ONE:
269
+ return ApproveAndCall.encodeApproveZeroThenMaxMinusOne(token.wrapped);
270
+
271
+ default:
272
+ throw 'Error: invalid ApprovalType';
273
+ }
274
+ };
275
+
276
+ return ApproveAndCall;
277
+ }();
278
+ ApproveAndCall.INTERFACE = /*#__PURE__*/new Interface(abi$2);
279
+
209
280
  function createCommonjsModule(fn, module) {
210
281
  return module = { exports: {} }, fn(module, module.exports), module.exports;
211
282
  }
@@ -1043,7 +1114,43 @@ var Trade = /*#__PURE__*/function () {
1043
1114
  });
1044
1115
  }
1045
1116
 
1046
- this.tradeType = tradeType;
1117
+ this.tradeType = tradeType; // each route must have the same input and output currency
1118
+
1119
+ var inputCurrency = this.swaps[0].inputAmount.currency;
1120
+ var outputCurrency = this.swaps[0].outputAmount.currency;
1121
+ !this.swaps.every(function (_ref2) {
1122
+ var route = _ref2.route;
1123
+ return inputCurrency.wrapped.equals(route.input.wrapped);
1124
+ }) ? process.env.NODE_ENV !== "production" ? invariant(false, 'INPUT_CURRENCY_MATCH') : invariant(false) : void 0;
1125
+ !this.swaps.every(function (_ref3) {
1126
+ var route = _ref3.route;
1127
+ return outputCurrency.wrapped.equals(route.output.wrapped);
1128
+ }) ? process.env.NODE_ENV !== "production" ? invariant(false, 'OUTPUT_CURRENCY_MATCH') : invariant(false) : void 0; // pools must be unique inter protocols
1129
+
1130
+ var numPools = this.swaps.map(function (_ref4) {
1131
+ var route = _ref4.route;
1132
+ return route.pools.length;
1133
+ }).reduce(function (total, cur) {
1134
+ return total + cur;
1135
+ }, 0);
1136
+ var poolAddressSet = new Set();
1137
+
1138
+ for (var _iterator3 = _createForOfIteratorHelperLoose(this.swaps), _step3; !(_step3 = _iterator3()).done;) {
1139
+ var _route2 = _step3.value.route;
1140
+
1141
+ for (var _iterator4 = _createForOfIteratorHelperLoose(_route2.pools), _step4; !(_step4 = _iterator4()).done;) {
1142
+ var pool = _step4.value;
1143
+
1144
+ if (_route2.protocol == Protocol.V3) {
1145
+ poolAddressSet.add(Pool.getAddress(pool.token0, pool.token1, pool.fee));
1146
+ } else {
1147
+ var pair = pool;
1148
+ poolAddressSet.add(Pair.getAddress(pair.token0, pair.token1));
1149
+ }
1150
+ }
1151
+ }
1152
+
1153
+ !(numPools == poolAddressSet.size) ? process.env.NODE_ENV !== "production" ? invariant(false, 'POOLS_DUPLICATED') : invariant(false) : void 0;
1047
1154
  }
1048
1155
 
1049
1156
  var _proto = Trade.prototype;
@@ -1101,7 +1208,7 @@ var Trade = /*#__PURE__*/function () {
1101
1208
 
1102
1209
  Trade.fromRoutes = /*#__PURE__*/function () {
1103
1210
  var _fromRoutes = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(v2Routes, v3Routes, tradeType) {
1104
- var populatedV2Routes, populatedV3Routes, _iterator3, _step3, _step3$value, routev2, amount, v2Trade, inputAmount, outputAmount, _iterator4, _step4, _step4$value, routev3, _amount, v3Trade, _inputAmount2, _outputAmount2;
1211
+ var populatedV2Routes, populatedV3Routes, _iterator5, _step5, _step5$value, routev2, amount, v2Trade, inputAmount, outputAmount, _iterator6, _step6, _step6$value, routev3, _amount, v3Trade, _inputAmount2, _outputAmount2;
1105
1212
 
1106
1213
  return runtime_1.wrap(function _callee$(_context) {
1107
1214
  while (1) {
@@ -1110,8 +1217,8 @@ var Trade = /*#__PURE__*/function () {
1110
1217
  populatedV2Routes = [];
1111
1218
  populatedV3Routes = [];
1112
1219
 
1113
- for (_iterator3 = _createForOfIteratorHelperLoose(v2Routes); !(_step3 = _iterator3()).done;) {
1114
- _step3$value = _step3.value, routev2 = _step3$value.routev2, amount = _step3$value.amount;
1220
+ for (_iterator5 = _createForOfIteratorHelperLoose(v2Routes); !(_step5 = _iterator5()).done;) {
1221
+ _step5$value = _step5.value, routev2 = _step5$value.routev2, amount = _step5$value.amount;
1115
1222
  v2Trade = new Trade$2(routev2, amount, tradeType);
1116
1223
  inputAmount = v2Trade.inputAmount, outputAmount = v2Trade.outputAmount;
1117
1224
  populatedV2Routes.push({
@@ -1121,15 +1228,15 @@ var Trade = /*#__PURE__*/function () {
1121
1228
  });
1122
1229
  }
1123
1230
 
1124
- _iterator4 = _createForOfIteratorHelperLoose(v3Routes);
1231
+ _iterator6 = _createForOfIteratorHelperLoose(v3Routes);
1125
1232
 
1126
1233
  case 4:
1127
- if ((_step4 = _iterator4()).done) {
1234
+ if ((_step6 = _iterator6()).done) {
1128
1235
  _context.next = 13;
1129
1236
  break;
1130
1237
  }
1131
1238
 
1132
- _step4$value = _step4.value, routev3 = _step4$value.routev3, _amount = _step4$value.amount;
1239
+ _step6$value = _step6.value, routev3 = _step6$value.routev3, _amount = _step6$value.amount;
1133
1240
  _context.next = 8;
1134
1241
  return Trade$1.fromRoute(routev3, _amount, tradeType);
1135
1242
 
@@ -1236,8 +1343,8 @@ var Trade = /*#__PURE__*/function () {
1236
1343
  }
1237
1344
 
1238
1345
  var inputCurrency = this.swaps[0].inputAmount.currency;
1239
- var totalInputFromRoutes = this.swaps.map(function (_ref2) {
1240
- var inputAmount = _ref2.inputAmount;
1346
+ var totalInputFromRoutes = this.swaps.map(function (_ref5) {
1347
+ var inputAmount = _ref5.inputAmount;
1241
1348
  return inputAmount;
1242
1349
  }).reduce(function (total, cur) {
1243
1350
  return total.add(cur);
@@ -1253,8 +1360,8 @@ var Trade = /*#__PURE__*/function () {
1253
1360
  }
1254
1361
 
1255
1362
  var outputCurrency = this.swaps[0].outputAmount.currency;
1256
- var totalOutputFromRoutes = this.swaps.map(function (_ref3) {
1257
- var outputAmount = _ref3.outputAmount;
1363
+ var totalOutputFromRoutes = this.swaps.map(function (_ref6) {
1364
+ var outputAmount = _ref6.outputAmount;
1258
1365
  return outputAmount;
1259
1366
  }).reduce(function (total, cur) {
1260
1367
  return total.add(cur);
@@ -1286,10 +1393,10 @@ var Trade = /*#__PURE__*/function () {
1286
1393
 
1287
1394
  var spotOutputAmount = CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0);
1288
1395
 
1289
- for (var _iterator5 = _createForOfIteratorHelperLoose(this.swaps), _step5; !(_step5 = _iterator5()).done;) {
1290
- var _step5$value = _step5.value,
1291
- route = _step5$value.route,
1292
- inputAmount = _step5$value.inputAmount;
1396
+ for (var _iterator7 = _createForOfIteratorHelperLoose(this.swaps), _step7; !(_step7 = _iterator7()).done;) {
1397
+ var _step7$value = _step7.value,
1398
+ route = _step7$value.route,
1399
+ inputAmount = _step7$value.inputAmount;
1293
1400
  var midPrice = route.midPrice;
1294
1401
  spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount));
1295
1402
  }
@@ -1314,18 +1421,16 @@ var SwapRouter = /*#__PURE__*/function () {
1314
1421
  */
1315
1422
  function SwapRouter() {}
1316
1423
 
1317
- SwapRouter.encodeV2Swap = function encodeV2Swap(trade, options, routerMustCustody) {
1424
+ SwapRouter.encodeV2Swap = function encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
1318
1425
  var amountIn = toHex(trade.maximumAmountIn(options.slippageTolerance).quotient);
1319
1426
  var amountOut = toHex(trade.minimumAmountOut(options.slippageTolerance).quotient);
1320
1427
  var path = trade.route.path.map(function (token) {
1321
1428
  return token.address;
1322
1429
  });
1323
- var recipient = routerMustCustody ? ADDRESS_THIS : options.recipient ? validateAndParseAddress(options.recipient) : MSG_SENDER;
1430
+ var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : validateAndParseAddress(options.recipient);
1324
1431
 
1325
1432
  if (trade.tradeType === TradeType.EXACT_INPUT) {
1326
- var exactInputParams = [amountIn, // save gas by only passing slippage check if we can't check it later
1327
- // not a pure win, as sometimes this will cost us more when it would have caused an earlier failure
1328
- routerMustCustody ? 0 : amountOut, path, recipient];
1433
+ var exactInputParams = [amountIn, performAggregatedSlippageCheck ? 0 : amountOut, path, recipient];
1329
1434
  return SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams);
1330
1435
  } else {
1331
1436
  var exactOutputParams = [amountOut, amountIn, path, recipient];
@@ -1333,7 +1438,7 @@ var SwapRouter = /*#__PURE__*/function () {
1333
1438
  }
1334
1439
  };
1335
1440
 
1336
- SwapRouter.encodeV3Swap = function encodeV3Swap(trade, options, routerMustCustody) {
1441
+ SwapRouter.encodeV3Swap = function encodeV3Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
1337
1442
  var calldatas = [];
1338
1443
 
1339
1444
  for (var _iterator = _createForOfIteratorHelperLoose(trade.swaps), _step; !(_step = _iterator()).done;) {
@@ -1345,7 +1450,7 @@ var SwapRouter = /*#__PURE__*/function () {
1345
1450
  var amountOut = toHex(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient); // flag for whether the trade is single hop or not
1346
1451
 
1347
1452
  var singleHop = route.pools.length === 1;
1348
- var recipient = routerMustCustody ? ADDRESS_THIS : options.recipient ? validateAndParseAddress(options.recipient) : MSG_SENDER;
1453
+ var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : validateAndParseAddress(options.recipient);
1349
1454
 
1350
1455
  if (singleHop) {
1351
1456
  if (trade.tradeType === TradeType.EXACT_INPUT) {
@@ -1355,7 +1460,7 @@ var SwapRouter = /*#__PURE__*/function () {
1355
1460
  fee: route.pools[0].fee,
1356
1461
  recipient: recipient,
1357
1462
  amountIn: amountIn,
1358
- amountOutMinimum: amountOut,
1463
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
1359
1464
  sqrtPriceLimitX96: 0
1360
1465
  };
1361
1466
  calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInputSingle', [exactInputSingleParams]));
@@ -1379,7 +1484,7 @@ var SwapRouter = /*#__PURE__*/function () {
1379
1484
  path: path,
1380
1485
  recipient: recipient,
1381
1486
  amountIn: amountIn,
1382
- amountOutMinimum: amountOut
1487
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut
1383
1488
  };
1384
1489
  calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInput', [exactInputParams]));
1385
1490
  } else {
@@ -1395,15 +1500,9 @@ var SwapRouter = /*#__PURE__*/function () {
1395
1500
  }
1396
1501
 
1397
1502
  return calldatas;
1398
- }
1399
- /**
1400
- * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
1401
- * @param trade to produce call parameters for
1402
- * @param options options for the call parameters
1403
- */
1404
- ;
1503
+ };
1405
1504
 
1406
- SwapRouter.swapCallParameters = function swapCallParameters(trades, options) {
1505
+ SwapRouter.encodeSwaps = function encodeSwaps(trades, options, isSwapAndAdd) {
1407
1506
  // If dealing with an instance of the aggregated Trade object, unbundle it to individual V2Trade and V3Trade objects.
1408
1507
  if (trades instanceof Trade) {
1409
1508
  !trades.swaps.every(function (swap) {
@@ -1436,6 +1535,9 @@ var SwapRouter = /*#__PURE__*/function () {
1436
1535
  trades = [trades];
1437
1536
  }
1438
1537
 
1538
+ var numberOfTrades = trades.reduce(function (numberOfTrades, trade) {
1539
+ return numberOfTrades + (trade instanceof Trade$1 ? trade.swaps.length : 1);
1540
+ }, 0);
1439
1541
  var sampleTrade = trades[0]; // All trades should have the same starting/ending currency and trade type
1440
1542
 
1441
1543
  !trades.every(function (trade) {
@@ -1448,25 +1550,19 @@ var SwapRouter = /*#__PURE__*/function () {
1448
1550
  return trade.tradeType === sampleTrade.tradeType;
1449
1551
  }) ? process.env.NODE_ENV !== "production" ? invariant(false, 'TRADE_TYPE_DIFF') : invariant(false) : void 0;
1450
1552
  var calldatas = [];
1451
- var ZERO_IN = CurrencyAmount.fromRawAmount(sampleTrade.inputAmount.currency, 0);
1452
- var ZERO_OUT = CurrencyAmount.fromRawAmount(sampleTrade.outputAmount.currency, 0);
1453
- var totalAmountOut = trades.reduce(function (sum, trade) {
1454
- return sum.add(trade.minimumAmountOut(options.slippageTolerance));
1455
- }, ZERO_OUT);
1456
1553
  var inputIsNative = sampleTrade.inputAmount.currency.isNative;
1457
- var outputIsNative = sampleTrade.outputAmount.currency.isNative; // flag for whether a refund needs to happen
1458
- // 1. when paying in ETH, but with an uncertain input amount
1554
+ var outputIsNative = sampleTrade.outputAmount.currency.isNative; // flag for whether we want to perform an aggregated slippage check
1555
+ // 1. when there are >2 exact input trades. this is only a heuristic,
1556
+ // as it's still more gas-expensive even in this case, but has benefits
1557
+ // in that the reversion probability is lower
1459
1558
 
1460
- var mustRefund = inputIsNative && sampleTrade.tradeType === TradeType.EXACT_OUTPUT; // flag for whether funds should be send first to the router
1559
+ var performAggregatedSlippageCheck = sampleTrade.tradeType === TradeType.EXACT_INPUT && numberOfTrades > 2; // flag for whether funds should be send first to the router
1461
1560
  // 1. when receiving ETH (which much be unwrapped from WETH)
1462
1561
  // 2. when a fee on the output is being taken
1463
- // 3. when there are >1 exact input trades. this one isn't strictly necessary,
1464
- // but typically we want to perform an aggregated slippage check
1562
+ // 3. when performing swap and add
1563
+ // 4. when performing an aggregated slippage check
1465
1564
 
1466
- var routerMustCustody = outputIsNative || !!options.fee || trades.length > 1 && sampleTrade.tradeType === TradeType.EXACT_INPUT;
1467
- var totalValue = inputIsNative ? trades.reduce(function (sum, trade) {
1468
- return sum.add(trade.maximumAmountIn(options.slippageTolerance));
1469
- }, ZERO_IN) : ZERO_IN; // encode permit if necessary
1565
+ var routerMustCustody = outputIsNative || !!options.fee || !!isSwapAndAdd || performAggregatedSlippageCheck; // encode permit if necessary
1470
1566
 
1471
1567
  if (options.inputTokenPermit) {
1472
1568
  !sampleTrade.inputAmount.currency.isToken ? process.env.NODE_ENV !== "production" ? invariant(false, 'NON_TOKEN_PERMIT') : invariant(false) : void 0;
@@ -1477,42 +1573,150 @@ var SwapRouter = /*#__PURE__*/function () {
1477
1573
  var trade = _step3.value;
1478
1574
 
1479
1575
  if (trade instanceof Trade$2) {
1480
- calldatas.push(SwapRouter.encodeV2Swap(trade, options, routerMustCustody));
1576
+ calldatas.push(SwapRouter.encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck));
1481
1577
  } else {
1482
- for (var _iterator4 = _createForOfIteratorHelperLoose(SwapRouter.encodeV3Swap(trade, options, routerMustCustody)), _step4; !(_step4 = _iterator4()).done;) {
1578
+ for (var _iterator4 = _createForOfIteratorHelperLoose(SwapRouter.encodeV3Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck)), _step4; !(_step4 = _iterator4()).done;) {
1483
1579
  var calldata = _step4.value;
1484
1580
  calldatas.push(calldata);
1485
1581
  }
1486
1582
  }
1487
- } // unwrap
1583
+ }
1488
1584
 
1585
+ var ZERO_IN = CurrencyAmount.fromRawAmount(sampleTrade.inputAmount.currency, 0);
1586
+ var ZERO_OUT = CurrencyAmount.fromRawAmount(sampleTrade.outputAmount.currency, 0);
1587
+ var totalAmountOut = trades.reduce(function (sum, trade) {
1588
+ return sum.add(trade.minimumAmountOut(options.slippageTolerance));
1589
+ }, ZERO_OUT);
1590
+ var totalAmountIn = trades.reduce(function (sum, trade) {
1591
+ return sum.add(trade.maximumAmountIn(options.slippageTolerance));
1592
+ }, ZERO_IN);
1593
+ return {
1594
+ calldatas: calldatas,
1595
+ sampleTrade: sampleTrade,
1596
+ routerMustCustody: routerMustCustody,
1597
+ inputIsNative: inputIsNative,
1598
+ outputIsNative: outputIsNative,
1599
+ totalAmountIn: totalAmountIn,
1600
+ totalAmountOut: totalAmountOut
1601
+ };
1602
+ }
1603
+ /**
1604
+ * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
1605
+ * @param trade to produce call parameters for
1606
+ * @param options options for the call parameters
1607
+ */
1608
+ ;
1609
+
1610
+ SwapRouter.swapCallParameters = function swapCallParameters(trades, options) {
1611
+ var _SwapRouter$encodeSwa = SwapRouter.encodeSwaps(trades, options),
1612
+ calldatas = _SwapRouter$encodeSwa.calldatas,
1613
+ sampleTrade = _SwapRouter$encodeSwa.sampleTrade,
1614
+ routerMustCustody = _SwapRouter$encodeSwa.routerMustCustody,
1615
+ inputIsNative = _SwapRouter$encodeSwa.inputIsNative,
1616
+ outputIsNative = _SwapRouter$encodeSwa.outputIsNative,
1617
+ totalAmountIn = _SwapRouter$encodeSwa.totalAmountIn,
1618
+ totalAmountOut = _SwapRouter$encodeSwa.totalAmountOut; // unwrap or sweep
1489
1619
 
1490
- if (routerMustCustody) {
1491
- // if all trades are exact output, we can save gas by not passing a slippage check
1492
- var canOmitSlippageCheck = sampleTrade.tradeType === TradeType.EXACT_OUTPUT;
1493
- var amountNecessary = canOmitSlippageCheck ? ZERO$1 : totalAmountOut.quotient;
1494
1620
 
1621
+ if (routerMustCustody) {
1495
1622
  if (outputIsNative) {
1496
- calldatas.push(PaymentsExtended.encodeUnwrapWETH9(amountNecessary, options.recipient, options.fee));
1623
+ calldatas.push(PaymentsExtended.encodeUnwrapWETH9(totalAmountOut.quotient, options.recipient, options.fee));
1497
1624
  } else {
1498
- calldatas.push(PaymentsExtended.encodeSweepToken(sampleTrade.outputAmount.currency.wrapped, amountNecessary, options.recipient, options.fee));
1625
+ calldatas.push(PaymentsExtended.encodeSweepToken(sampleTrade.outputAmount.currency.wrapped, totalAmountOut.quotient, options.recipient, options.fee));
1499
1626
  }
1500
- } // refund
1627
+ } // must refund when paying in ETH, but with an uncertain input amount
1501
1628
 
1502
1629
 
1503
- if (mustRefund) {
1630
+ if (inputIsNative && sampleTrade.tradeType === TradeType.EXACT_OUTPUT) {
1504
1631
  calldatas.push(Payments.encodeRefundETH());
1505
1632
  }
1506
1633
 
1507
1634
  return {
1508
1635
  calldata: MulticallExtended.encodeMulticall(calldatas, options.deadlineOrPreviousBlockhash),
1509
- value: toHex(totalValue.quotient)
1636
+ value: toHex(inputIsNative ? totalAmountIn.quotient : ZERO$1)
1637
+ };
1638
+ }
1639
+ /**
1640
+ * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
1641
+ * @param trade to produce call parameters for
1642
+ * @param options options for the call parameters
1643
+ */
1644
+ ;
1645
+
1646
+ SwapRouter.swapAndAddCallParameters = function swapAndAddCallParameters(trades, options, position, addLiquidityOptions, tokenInApprovalType, tokenOutApprovalType) {
1647
+ var _SwapRouter$encodeSwa2 = SwapRouter.encodeSwaps(trades, options, true),
1648
+ calldatas = _SwapRouter$encodeSwa2.calldatas,
1649
+ inputIsNative = _SwapRouter$encodeSwa2.inputIsNative,
1650
+ outputIsNative = _SwapRouter$encodeSwa2.outputIsNative,
1651
+ sampleTrade = _SwapRouter$encodeSwa2.sampleTrade,
1652
+ totalAmountSwapped = _SwapRouter$encodeSwa2.totalAmountIn,
1653
+ totalAmountOut = _SwapRouter$encodeSwa2.totalAmountOut;
1654
+
1655
+ var chainId = sampleTrade.route.chainId;
1656
+ var zeroForOne = position.pool.token0 === totalAmountSwapped.currency.wrapped;
1657
+
1658
+ var _SwapRouter$getPositi = SwapRouter.getPositionAmounts(position, zeroForOne),
1659
+ positionAmountIn = _SwapRouter$getPositi.positionAmountIn,
1660
+ positionAmountOut = _SwapRouter$getPositi.positionAmountOut; // if tokens are native they will be converted to WETH9
1661
+
1662
+
1663
+ var tokenIn = inputIsNative ? WETH9[chainId] : positionAmountIn.currency.wrapped;
1664
+ var tokenOut = outputIsNative ? WETH9[chainId] : positionAmountOut.currency.wrapped; // if swap output does not make up whole outputTokenBalanceDesired, pull in remaining tokens for adding liquidity
1665
+
1666
+ var amountOutRemaining = positionAmountOut.subtract(totalAmountOut.wrapped);
1667
+
1668
+ if (amountOutRemaining.greaterThan(CurrencyAmount.fromRawAmount(positionAmountOut.currency, 0))) {
1669
+ // if output is native, this means the remaining portion is included as native value in the transaction
1670
+ // and must be wrapped. Otherwise, pull in remaining ERC20 token.
1671
+ outputIsNative ? calldatas.push(PaymentsExtended.encodeWrapETH(amountOutRemaining.quotient)) : calldatas.push(PaymentsExtended.encodePull(tokenOut, amountOutRemaining.quotient));
1672
+ } // if input is native, convert to WETH9, else pull ERC20 token
1673
+
1674
+
1675
+ inputIsNative ? calldatas.push(PaymentsExtended.encodeWrapETH(positionAmountIn.quotient)) : calldatas.push(PaymentsExtended.encodePull(tokenIn, positionAmountIn.quotient)); // approve token balances to NFTManager
1676
+
1677
+ if (tokenInApprovalType !== ApprovalTypes.NOT_REQUIRED) calldatas.push(ApproveAndCall.encodeApprove(tokenIn, tokenInApprovalType));
1678
+ if (tokenOutApprovalType !== ApprovalTypes.NOT_REQUIRED) calldatas.push(ApproveAndCall.encodeApprove(tokenOut, tokenOutApprovalType)); // encode NFTManager add liquidity
1679
+
1680
+ calldatas.push(ApproveAndCall.encodeCallPositionManager([NonfungiblePositionManager.addCallParameters(position, addLiquidityOptions).calldata])); // sweep remaining tokens
1681
+
1682
+ inputIsNative ? calldatas.push(PaymentsExtended.encodeUnwrapWETH9(ZERO$1)) : calldatas.push(PaymentsExtended.encodeSweepToken(tokenIn, ZERO$1));
1683
+ outputIsNative ? calldatas.push(PaymentsExtended.encodeUnwrapWETH9(ZERO$1)) : calldatas.push(PaymentsExtended.encodeSweepToken(tokenOut, ZERO$1));
1684
+ var value;
1685
+
1686
+ if (inputIsNative) {
1687
+ value = totalAmountSwapped.wrapped.add(positionAmountIn.wrapped).quotient;
1688
+ } else if (outputIsNative) {
1689
+ value = amountOutRemaining.quotient;
1690
+ } else {
1691
+ value = ZERO$1;
1692
+ }
1693
+
1694
+ return {
1695
+ calldata: MulticallExtended.encodeMulticall(calldatas, options.deadlineOrPreviousBlockhash),
1696
+ value: value.toString()
1697
+ };
1698
+ };
1699
+
1700
+ SwapRouter.getPositionAmounts = function getPositionAmounts(position, zeroForOne) {
1701
+ var _position$mintAmounts = position.mintAmounts,
1702
+ amount0 = _position$mintAmounts.amount0,
1703
+ amount1 = _position$mintAmounts.amount1;
1704
+ var currencyAmount0 = CurrencyAmount.fromRawAmount(position.pool.token0, amount0);
1705
+ var currencyAmount1 = CurrencyAmount.fromRawAmount(position.pool.token1, amount1);
1706
+
1707
+ var _ref = zeroForOne ? [currencyAmount0, currencyAmount1] : [currencyAmount1, currencyAmount0],
1708
+ positionAmountIn = _ref[0],
1709
+ positionAmountOut = _ref[1];
1710
+
1711
+ return {
1712
+ positionAmountIn: positionAmountIn,
1713
+ positionAmountOut: positionAmountOut
1510
1714
  };
1511
1715
  };
1512
1716
 
1513
1717
  return SwapRouter;
1514
1718
  }();
1515
- SwapRouter.INTERFACE = /*#__PURE__*/new Interface(abi$2);
1719
+ SwapRouter.INTERFACE = /*#__PURE__*/new Interface(abi$3);
1516
1720
 
1517
1721
  export { ADDRESS_THIS, MSG_SENDER, MulticallExtended, ONE, PaymentsExtended, Protocol, RouteV2, RouteV3, SwapRouter, Trade, ZERO };
1518
1722
  //# sourceMappingURL=router-sdk.esm.js.map