@uniswap/universal-router-sdk 4.4.0 → 4.4.1

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.
@@ -2,12 +2,12 @@ import invariant from 'tiny-invariant';
2
2
  import { abi } from '@uniswap/universal-router/artifacts/contracts/UniversalRouter.sol/UniversalRouter.json';
3
3
  import { Interface } from '@ethersproject/abi';
4
4
  import { BigNumber, ethers } from 'ethers';
5
- import { toHex, Trade as Trade$1, encodeRouteToPath, Pool, NonfungiblePositionManager, Route } from '@uniswap/v3-sdk';
6
- import { Trade as Trade$2, V4Planner, V4PositionManager, V4BaseActionsParser } from '@uniswap/v4-sdk';
5
+ import { toHex, Trade as Trade$1, encodeRouteToPath, Pool as Pool$1, NonfungiblePositionManager, Route as Route$1 } from '@uniswap/v3-sdk';
6
+ import { Pool, Trade as Trade$2, V4Planner, Route, Actions, encodeRouteToPath as encodeRouteToPath$1, V4PositionManager, V4BaseActionsParser } from '@uniswap/v4-sdk';
7
7
  import { TradeType, Percent, validateAndParseAddress, CHAIN_TO_ADDRESSES_MAP, CurrencyAmount, Ether, Token } from '@uniswap/sdk-core';
8
8
  import { defaultAbiCoder } from 'ethers/lib/utils';
9
- import { Trade, Pair, Route as Route$1 } from '@uniswap/v2-sdk';
10
- import { Protocol, MixedRouteTrade, partitionMixedRouteByProtocol, getOutputOfPools, MixedRouteSDK, MixedRoute, encodeMixedRouteToPath, Trade as Trade$3 } from '@uniswap/router-sdk';
9
+ import { Trade, Pair, Route as Route$2 } from '@uniswap/v2-sdk';
10
+ import { Protocol, MixedRouteTrade, partitionMixedRouteByProtocol, getOutputOfPools, MixedRoute, MixedRouteSDK, encodeMixedRouteToPath, Trade as Trade$3 } from '@uniswap/router-sdk';
11
11
  import 'jsbi';
12
12
  import 'bignumber.js';
13
13
 
@@ -366,6 +366,27 @@ function createCommand(type, parameters) {
366
366
  }
367
367
  }
368
368
 
369
+ function getPathCurrency(currency, pool) {
370
+ // return currency if the currency matches a currency of the pool
371
+ if (pool.involvesToken(currency)) {
372
+ return currency;
373
+ // return if currency.wrapped if pool involves wrapped currency
374
+ } else if (pool.involvesToken(currency.wrapped)) {
375
+ return currency.wrapped;
376
+ // return native currency if pool involves native version of wrapped currency (only applies to V4)
377
+ } else if (pool instanceof Pool) {
378
+ if (pool.token0.wrapped.equals(currency)) {
379
+ return pool.token0;
380
+ } else if (pool.token1.wrapped.equals(currency)) {
381
+ return pool.token1;
382
+ }
383
+ // otherwise the token is invalid
384
+ } else {
385
+ throw new Error("Expected currency " + currency.symbol + " to be either " + pool.token0.symbol + " or " + pool.token1.symbol);
386
+ }
387
+ return currency; // this line needed for typescript to compile
388
+ }
389
+
369
390
  var RouterActionType;
370
391
  (function (RouterActionType) {
371
392
  RouterActionType["UniswapTrade"] = "UniswapTrade";
@@ -621,7 +642,7 @@ var UniswapTrade = /*#__PURE__*/function () {
621
642
  addV3Swap(planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
622
643
  break;
623
644
  case Protocol.V4:
624
- addV4Swap(planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody, performAggregatedSlippageCheck);
645
+ addV4Swap(planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
625
646
  break;
626
647
  case Protocol.MIXED:
627
648
  addMixedSwap(planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
@@ -743,7 +764,7 @@ function addV3Swap(planner, _ref2, tradeType, options, payerIsUser, routerMustCu
743
764
  planner.addCommand(CommandType.V3_SWAP_EXACT_OUT, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), path, payerIsUser]);
744
765
  }
745
766
  }
746
- function addV4Swap(planner, _ref3, tradeType, options, payerIsUser, routerMustCustody, performAggregatedSlippageCheck) {
767
+ function addV4Swap(planner, _ref3, tradeType, options, payerIsUser, routerMustCustody) {
747
768
  var _options$recipient;
748
769
  var route = _ref3.route,
749
770
  inputAmount = _ref3.inputAmount,
@@ -754,7 +775,7 @@ function addV4Swap(planner, _ref3, tradeType, options, payerIsUser, routerMustCu
754
775
  outputAmount: outputAmount,
755
776
  tradeType: tradeType
756
777
  });
757
- var slippageToleranceOnSwap = performAggregatedSlippageCheck ? undefined : options.slippageTolerance;
778
+ var slippageToleranceOnSwap = routerMustCustody && tradeType == TradeType.EXACT_INPUT ? undefined : options.slippageTolerance;
758
779
  var inputWethFromRouter = inputAmount.currency.isNative && !route.input.isNative;
759
780
  if (inputWethFromRouter && !payerIsUser) throw new Error('Inconsistent payer');
760
781
  var v4Planner = new V4Planner();
@@ -766,13 +787,16 @@ function addV4Swap(planner, _ref3, tradeType, options, payerIsUser, routerMustCu
766
787
  }
767
788
  // encode a mixed route swap, i.e. including both v2 and v3 pools
768
789
  function addMixedSwap(planner, swap, tradeType, options, payerIsUser, routerMustCustody) {
769
- var route = swap.route,
770
- inputAmount = swap.inputAmount,
771
- outputAmount = swap.outputAmount;
772
- var tradeRecipient = routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient;
773
- // single hop, so it can be reduced to plain v2 or v3 swap logic
790
+ var _options$recipient2;
791
+ var route = swap.route;
792
+ var inputAmount = swap.inputAmount;
793
+ var outputAmount = swap.outputAmount;
794
+ var tradeRecipient = routerMustCustody ? ROUTER_AS_RECIPIENT : (_options$recipient2 = options.recipient) != null ? _options$recipient2 : SENDER_AS_RECIPIENT;
795
+ // single hop, so it can be reduced to plain swap logic for one protocol version
774
796
  if (route.pools.length === 1) {
775
797
  if (route.pools[0] instanceof Pool) {
798
+ return addV4Swap(planner, swap, tradeType, options, payerIsUser, routerMustCustody);
799
+ } else if (route.pools[0] instanceof Pool$1) {
776
800
  return addV3Swap(planner, swap, tradeType, options, payerIsUser, routerMustCustody);
777
801
  } else if (route.pools[0] instanceof Pair) {
778
802
  return addV2Swap(planner, swap, tradeType, options, payerIsUser, routerMustCustody);
@@ -794,32 +818,53 @@ function addMixedSwap(planner, swap, tradeType, options, payerIsUser, routerMust
794
818
  var isLastSectionInRoute = function isLastSectionInRoute(i) {
795
819
  return i === sections.length - 1;
796
820
  };
797
- var outputToken;
798
- var inputToken = route.input.wrapped;
821
+ var inputToken = route.pathInput;
799
822
  for (var i = 0; i < sections.length; i++) {
800
823
  var section = sections[i];
801
- /// Now, we get output of this section
802
- outputToken = getOutputOfPools(section, inputToken);
803
- var newRouteOriginal = new MixedRouteSDK([].concat(section), section[0].token0.equals(inputToken) ? section[0].token0 : section[0].token1, outputToken);
804
- var newRoute = new MixedRoute(newRouteOriginal);
805
- /// Previous output is now input
806
- inputToken = outputToken.wrapped;
807
- var mixedRouteIsAllV3 = function mixedRouteIsAllV3(route) {
808
- return route.pools.every(function (pool) {
809
- return pool instanceof Pool;
810
- });
811
- };
812
- if (mixedRouteIsAllV3(newRoute)) {
813
- var path = encodeMixedRouteToPath(newRoute);
814
- planner.addCommand(CommandType.V3_SWAP_EXACT_IN, [
815
- // if not last section: send tokens directly to the first v2 pair of the next section
816
- // note: because of the partitioning function we can be sure that the next section is v2
817
- isLastSectionInRoute(i) ? tradeRecipient : sections[i + 1][0].liquidityToken.address, i == 0 ? amountIn : CONTRACT_BALANCE, !isLastSectionInRoute(i) ? 0 : amountOut, path, payerIsUser && i === 0]);
824
+ var routePool = section[0];
825
+ var outputToken = getOutputOfPools(section, inputToken);
826
+ var subRoute = new MixedRoute(new MixedRouteSDK([].concat(section), inputToken, outputToken));
827
+ var nextInputToken = void 0;
828
+ var swapRecipient = void 0;
829
+ if (isLastSectionInRoute(i)) {
830
+ nextInputToken = outputToken;
831
+ swapRecipient = tradeRecipient;
818
832
  } else {
819
- planner.addCommand(CommandType.V2_SWAP_EXACT_IN, [isLastSectionInRoute(i) ? tradeRecipient : ROUTER_AS_RECIPIENT, i === 0 ? amountIn : CONTRACT_BALANCE, !isLastSectionInRoute(i) ? 0 : amountOut, newRoute.path.map(function (token) {
833
+ var nextPool = sections[i + 1][0];
834
+ nextInputToken = getPathCurrency(outputToken, nextPool);
835
+ var v2PoolIsSwapRecipient = nextPool instanceof Pair && outputToken.equals(nextInputToken);
836
+ swapRecipient = v2PoolIsSwapRecipient ? nextPool.liquidityToken.address : ROUTER_AS_RECIPIENT;
837
+ }
838
+ if (routePool instanceof Pool) {
839
+ var v4Planner = new V4Planner();
840
+ var v4SubRoute = new Route(section, subRoute.input, subRoute.output);
841
+ v4Planner.addSettle(inputToken, payerIsUser && i === 0, i == 0 ? amountIn : CONTRACT_BALANCE);
842
+ v4Planner.addAction(Actions.SWAP_EXACT_IN, [{
843
+ currencyIn: inputToken.isNative ? ETH_ADDRESS : inputToken.address,
844
+ path: encodeRouteToPath$1(v4SubRoute),
845
+ amountIn: 0,
846
+ amountOutMinimum: !isLastSectionInRoute(i) ? 0 : amountOut
847
+ }]);
848
+ v4Planner.addTake(outputToken, swapRecipient);
849
+ planner.addCommand(CommandType.V4_SWAP, [v4Planner.finalize()]);
850
+ } else if (routePool instanceof Pool$1) {
851
+ planner.addCommand(CommandType.V3_SWAP_EXACT_IN, [swapRecipient, i == 0 ? amountIn : CONTRACT_BALANCE, !isLastSectionInRoute(i) ? 0 : amountOut, encodeMixedRouteToPath(subRoute), payerIsUser && i === 0]);
852
+ } else if (routePool instanceof Pair) {
853
+ planner.addCommand(CommandType.V2_SWAP_EXACT_IN, [swapRecipient, i === 0 ? amountIn : CONTRACT_BALANCE, !isLastSectionInRoute(i) ? 0 : amountOut, subRoute.path.map(function (token) {
820
854
  return token.wrapped.address;
821
855
  }), payerIsUser && i === 0]);
856
+ } else {
857
+ throw new Error('Unexpected Pool Type');
858
+ }
859
+ // perform a token transition (wrap/unwrap if necessary)
860
+ if (!isLastSectionInRoute(i)) {
861
+ if (outputToken.isNative && !nextInputToken.isNative) {
862
+ planner.addCommand(CommandType.WRAP_ETH, [ROUTER_AS_RECIPIENT, CONTRACT_BALANCE]);
863
+ } else if (!outputToken.isNative && nextInputToken.isNative) {
864
+ planner.addCommand(CommandType.UNWRAP_WETH, [ROUTER_AS_RECIPIENT, 0]);
865
+ }
822
866
  }
867
+ inputToken = nextInputToken;
823
868
  }
824
869
  }
825
870
  // if price impact is very high, there's a chance of hitting max/min prices resulting in a partial fill of the swap
@@ -977,6 +1022,7 @@ var PoolType;
977
1022
  (function (PoolType) {
978
1023
  PoolType["V2Pool"] = "v2-pool";
979
1024
  PoolType["V3Pool"] = "v3-pool";
1025
+ PoolType["V4Pool"] = "v4-pool";
980
1026
  })(PoolType || (PoolType = {}));
981
1027
  var isNativeCurrency = function isNativeCurrency(address) {
982
1028
  return address.toLowerCase() === ETH_ADDRESS.toLowerCase() || address.toLowerCase() === E_ETH_ADDRESS.toLowerCase();
@@ -1013,8 +1059,8 @@ var RouterTradeAdapter = /*#__PURE__*/function () {
1013
1059
  var isOnlyV2 = RouterTradeAdapter.isVersionedRoute(PoolType.V2Pool, subRoute);
1014
1060
  var isOnlyV3 = RouterTradeAdapter.isVersionedRoute(PoolType.V3Pool, subRoute);
1015
1061
  return {
1016
- routev3: isOnlyV3 ? new Route(subRoute.map(RouterTradeAdapter.toPool), parsedCurrencyIn, parsedCurrencyOut) : null,
1017
- routev2: isOnlyV2 ? new Route$1(subRoute.map(RouterTradeAdapter.toPair), parsedCurrencyIn, parsedCurrencyOut) : null,
1062
+ routev3: isOnlyV3 ? new Route$1(subRoute.map(RouterTradeAdapter.toPool), parsedCurrencyIn, parsedCurrencyOut) : null,
1063
+ routev2: isOnlyV2 ? new Route$2(subRoute.map(RouterTradeAdapter.toPair), parsedCurrencyIn, parsedCurrencyOut) : null,
1018
1064
  mixedRoute: !isOnlyV3 && !isOnlyV2 ? new MixedRouteSDK(subRoute.map(RouterTradeAdapter.toPoolOrPair), parsedCurrencyIn, parsedCurrencyOut) : null,
1019
1065
  inputAmount: inputAmount,
1020
1066
  outputAmount: outputAmount
@@ -1075,7 +1121,7 @@ var RouterTradeAdapter = /*#__PURE__*/function () {
1075
1121
  tickCurrent = _ref.tickCurrent,
1076
1122
  tokenIn = _ref.tokenIn,
1077
1123
  tokenOut = _ref.tokenOut;
1078
- return new Pool(RouterTradeAdapter.toToken(tokenIn), RouterTradeAdapter.toToken(tokenOut), parseInt(fee), sqrtRatioX96, liquidity, parseInt(tickCurrent));
1124
+ return new Pool$1(RouterTradeAdapter.toToken(tokenIn), RouterTradeAdapter.toToken(tokenOut), parseInt(fee), sqrtRatioX96, liquidity, parseInt(tickCurrent));
1079
1125
  };
1080
1126
  RouterTradeAdapter.isVersionedRoute = function isVersionedRoute(type, route) {
1081
1127
  return route.every(function (pool) {