@uniswap/router-sdk 1.0.0-beta.6 → 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.
@@ -7,6 +7,8 @@ export interface IRoute<TInput extends Currency, TOutput extends Currency, TPool
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,7 +1,7 @@
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
6
  readonly routes: IRoute<TInput, TOutput, Pair | Pool>[];
7
7
  readonly tradeType: TTradeType;
@@ -6,8 +6,8 @@ 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');
10
+ var v3Sdk = require('@uniswap/v3-sdk');
11
11
  var sdkCore = require('@uniswap/sdk-core');
12
12
  var IPeripheryPaymentsWithFeeExtended_json = require('@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IPeripheryPaymentsWithFeeExtended.sol/IPeripheryPaymentsWithFeeExtended.json');
13
13
  var ISwapRouter02_json = require('@uniswap/swap-router-contracts/artifacts/contracts/interfaces/ISwapRouter02.sol/ISwapRouter02.json');
@@ -1051,7 +1051,43 @@ var Trade = /*#__PURE__*/function () {
1051
1051
  });
1052
1052
  }
1053
1053
 
1054
- 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;
1055
1091
  }
1056
1092
 
1057
1093
  var _proto = Trade.prototype;
@@ -1109,7 +1145,7 @@ var Trade = /*#__PURE__*/function () {
1109
1145
 
1110
1146
  Trade.fromRoutes = /*#__PURE__*/function () {
1111
1147
  var _fromRoutes = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(v2Routes, v3Routes, tradeType) {
1112
- 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;
1113
1149
 
1114
1150
  return runtime_1.wrap(function _callee$(_context) {
1115
1151
  while (1) {
@@ -1118,8 +1154,8 @@ var Trade = /*#__PURE__*/function () {
1118
1154
  populatedV2Routes = [];
1119
1155
  populatedV3Routes = [];
1120
1156
 
1121
- for (_iterator3 = _createForOfIteratorHelperLoose(v2Routes); !(_step3 = _iterator3()).done;) {
1122
- _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;
1123
1159
  v2Trade = new v2Sdk.Trade(routev2, amount, tradeType);
1124
1160
  inputAmount = v2Trade.inputAmount, outputAmount = v2Trade.outputAmount;
1125
1161
  populatedV2Routes.push({
@@ -1129,15 +1165,15 @@ var Trade = /*#__PURE__*/function () {
1129
1165
  });
1130
1166
  }
1131
1167
 
1132
- _iterator4 = _createForOfIteratorHelperLoose(v3Routes);
1168
+ _iterator6 = _createForOfIteratorHelperLoose(v3Routes);
1133
1169
 
1134
1170
  case 4:
1135
- if ((_step4 = _iterator4()).done) {
1171
+ if ((_step6 = _iterator6()).done) {
1136
1172
  _context.next = 13;
1137
1173
  break;
1138
1174
  }
1139
1175
 
1140
- _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;
1141
1177
  _context.next = 8;
1142
1178
  return v3Sdk.Trade.fromRoute(routev3, _amount, tradeType);
1143
1179
 
@@ -1244,8 +1280,8 @@ var Trade = /*#__PURE__*/function () {
1244
1280
  }
1245
1281
 
1246
1282
  var inputCurrency = this.swaps[0].inputAmount.currency;
1247
- var totalInputFromRoutes = this.swaps.map(function (_ref2) {
1248
- var inputAmount = _ref2.inputAmount;
1283
+ var totalInputFromRoutes = this.swaps.map(function (_ref5) {
1284
+ var inputAmount = _ref5.inputAmount;
1249
1285
  return inputAmount;
1250
1286
  }).reduce(function (total, cur) {
1251
1287
  return total.add(cur);
@@ -1261,8 +1297,8 @@ var Trade = /*#__PURE__*/function () {
1261
1297
  }
1262
1298
 
1263
1299
  var outputCurrency = this.swaps[0].outputAmount.currency;
1264
- var totalOutputFromRoutes = this.swaps.map(function (_ref3) {
1265
- var outputAmount = _ref3.outputAmount;
1300
+ var totalOutputFromRoutes = this.swaps.map(function (_ref6) {
1301
+ var outputAmount = _ref6.outputAmount;
1266
1302
  return outputAmount;
1267
1303
  }).reduce(function (total, cur) {
1268
1304
  return total.add(cur);
@@ -1294,10 +1330,10 @@ var Trade = /*#__PURE__*/function () {
1294
1330
 
1295
1331
  var spotOutputAmount = sdkCore.CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0);
1296
1332
 
1297
- for (var _iterator5 = _createForOfIteratorHelperLoose(this.swaps), _step5; !(_step5 = _iterator5()).done;) {
1298
- var _step5$value = _step5.value,
1299
- route = _step5$value.route,
1300
- 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;
1301
1337
  var midPrice = route.midPrice;
1302
1338
  spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount));
1303
1339
  }
@@ -1311,7 +1347,6 @@ var Trade = /*#__PURE__*/function () {
1311
1347
  return Trade;
1312
1348
  }();
1313
1349
 
1314
- var ZERO$1 = /*#__PURE__*/JSBI.BigInt(0);
1315
1350
  /**
1316
1351
  * Represents the Uniswap V2 + V3 SwapRouter02, and has static methods for helping execute trades.
1317
1352
  */
@@ -1322,7 +1357,7 @@ var SwapRouter = /*#__PURE__*/function () {
1322
1357
  */
1323
1358
  function SwapRouter() {}
1324
1359
 
1325
- SwapRouter.encodeV2Swap = function encodeV2Swap(trade, options, routerMustCustody) {
1360
+ SwapRouter.encodeV2Swap = function encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
1326
1361
  var amountIn = v3Sdk.toHex(trade.maximumAmountIn(options.slippageTolerance).quotient);
1327
1362
  var amountOut = v3Sdk.toHex(trade.minimumAmountOut(options.slippageTolerance).quotient);
1328
1363
  var path = trade.route.path.map(function (token) {
@@ -1331,9 +1366,7 @@ var SwapRouter = /*#__PURE__*/function () {
1331
1366
  var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : sdkCore.validateAndParseAddress(options.recipient);
1332
1367
 
1333
1368
  if (trade.tradeType === sdkCore.TradeType.EXACT_INPUT) {
1334
- var exactInputParams = [amountIn, // save gas by only passing slippage check if we can't check it later
1335
- // not a pure win, as sometimes this will cost us more when it would have caused an earlier failure
1336
- routerMustCustody ? 0 : amountOut, path, recipient, false];
1369
+ var exactInputParams = [amountIn, performAggregatedSlippageCheck ? 0 : amountOut, path, recipient];
1337
1370
  return SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams);
1338
1371
  } else {
1339
1372
  var exactOutputParams = [amountOut, amountIn, path, recipient];
@@ -1341,7 +1374,7 @@ var SwapRouter = /*#__PURE__*/function () {
1341
1374
  }
1342
1375
  };
1343
1376
 
1344
- SwapRouter.encodeV3Swap = function encodeV3Swap(trade, options, routerMustCustody) {
1377
+ SwapRouter.encodeV3Swap = function encodeV3Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
1345
1378
  var calldatas = [];
1346
1379
 
1347
1380
  for (var _iterator = _createForOfIteratorHelperLoose(trade.swaps), _step; !(_step = _iterator()).done;) {
@@ -1363,9 +1396,8 @@ var SwapRouter = /*#__PURE__*/function () {
1363
1396
  fee: route.pools[0].fee,
1364
1397
  recipient: recipient,
1365
1398
  amountIn: amountIn,
1366
- amountOutMinimum: amountOut,
1367
- sqrtPriceLimitX96: 0,
1368
- hasAlreadyPaid: false
1399
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
1400
+ sqrtPriceLimitX96: 0
1369
1401
  };
1370
1402
  calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInputSingle', [exactInputSingleParams]));
1371
1403
  } else {
@@ -1388,8 +1420,7 @@ var SwapRouter = /*#__PURE__*/function () {
1388
1420
  path: path,
1389
1421
  recipient: recipient,
1390
1422
  amountIn: amountIn,
1391
- amountOutMinimum: amountOut,
1392
- hasAlreadyPaid: false
1423
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut
1393
1424
  };
1394
1425
  calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInput', [exactInputParams]));
1395
1426
  } else {
@@ -1446,6 +1477,9 @@ var SwapRouter = /*#__PURE__*/function () {
1446
1477
  trades = [trades];
1447
1478
  }
1448
1479
 
1480
+ var numberOfTrades = trades.reduce(function (numberOfTrades, trade) {
1481
+ return numberOfTrades + (trade instanceof v3Sdk.Trade ? trade.swaps.length : 1);
1482
+ }, 0);
1449
1483
  var sampleTrade = trades[0]; // All trades should have the same starting/ending currency and trade type
1450
1484
 
1451
1485
  !trades.every(function (trade) {
@@ -1467,13 +1501,17 @@ var SwapRouter = /*#__PURE__*/function () {
1467
1501
  var outputIsNative = sampleTrade.outputAmount.currency.isNative; // flag for whether a refund needs to happen
1468
1502
  // 1. when paying in ETH, but with an uncertain input amount
1469
1503
 
1470
- 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
1471
1510
  // 1. when receiving ETH (which much be unwrapped from WETH)
1472
1511
  // 2. when a fee on the output is being taken
1473
- // 3. when there are >1 exact input trades. this one isn't strictly necessary,
1474
- // but typically we want to perform an aggregated slippage check
1512
+ // 3. when performing an aggregated slippage check
1475
1513
 
1476
- var routerMustCustody = outputIsNative || !!options.fee || trades.length > 1 && sampleTrade.tradeType === sdkCore.TradeType.EXACT_INPUT;
1514
+ var routerMustCustody = outputIsNative || !!options.fee || performAggregatedSlippageCheck;
1477
1515
  var totalValue = inputIsNative ? trades.reduce(function (sum, trade) {
1478
1516
  return sum.add(trade.maximumAmountIn(options.slippageTolerance));
1479
1517
  }, ZERO_IN) : ZERO_IN; // encode permit if necessary
@@ -1487,25 +1525,21 @@ var SwapRouter = /*#__PURE__*/function () {
1487
1525
  var trade = _step3.value;
1488
1526
 
1489
1527
  if (trade instanceof v2Sdk.Trade) {
1490
- calldatas.push(SwapRouter.encodeV2Swap(trade, options, routerMustCustody));
1528
+ calldatas.push(SwapRouter.encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck));
1491
1529
  } else {
1492
- 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;) {
1493
1531
  var calldata = _step4.value;
1494
1532
  calldatas.push(calldata);
1495
1533
  }
1496
1534
  }
1497
- } // unwrap
1535
+ } // unwrap or sweep
1498
1536
 
1499
1537
 
1500
1538
  if (routerMustCustody) {
1501
- // if all trades are exact output, we can save gas by not passing a slippage check
1502
- var canOmitSlippageCheck = sampleTrade.tradeType === sdkCore.TradeType.EXACT_OUTPUT;
1503
- var amountNecessary = canOmitSlippageCheck ? ZERO$1 : totalAmountOut.quotient;
1504
-
1505
1539
  if (outputIsNative) {
1506
- calldatas.push(PaymentsExtended.encodeUnwrapWETH9(amountNecessary, options.recipient, options.fee));
1540
+ calldatas.push(PaymentsExtended.encodeUnwrapWETH9(totalAmountOut.quotient, options.recipient, options.fee));
1507
1541
  } else {
1508
- 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));
1509
1543
  }
1510
1544
  } // refund
1511
1545