@uniswap/universal-router-sdk 4.6.0 → 4.6.2
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/dist/entities/actions/uniswap.d.ts +3 -0
- package/dist/universal-router-sdk.cjs.development.js +76 -37
- package/dist/universal-router-sdk.cjs.development.js.map +1 -1
- package/dist/universal-router-sdk.cjs.production.min.js +1 -1
- package/dist/universal-router-sdk.cjs.production.min.js.map +1 -1
- package/dist/universal-router-sdk.esm.js +77 -38
- package/dist/universal-router-sdk.esm.js.map +1 -1
- package/dist/utils/getCurrencyAddress.d.ts +2 -0
- package/package.json +4 -4
|
@@ -3,7 +3,7 @@ import { abi } from '@uniswap/universal-router/artifacts/contracts/UniversalRout
|
|
|
3
3
|
import { Interface } from '@ethersproject/abi';
|
|
4
4
|
import { BigNumber, ethers } from 'ethers';
|
|
5
5
|
import { toHex, Trade as Trade$1, encodeRouteToPath, Pool as Pool$1, NonfungiblePositionManager, Multicall, Route as Route$1 } from '@uniswap/v3-sdk';
|
|
6
|
-
import { Pool, Trade as Trade$2, V4Planner,
|
|
6
|
+
import { Pool, Route, Trade as Trade$2, V4Planner, 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
9
|
import { Trade, Pair, Route as Route$2 } from '@uniswap/v2-sdk';
|
|
@@ -385,17 +385,13 @@ function getPathCurrency(currency, pool) {
|
|
|
385
385
|
} else if (pool.involvesToken(currency.wrapped)) {
|
|
386
386
|
return currency.wrapped;
|
|
387
387
|
// return native currency if pool involves native version of wrapped currency (only applies to V4)
|
|
388
|
-
} else if (pool instanceof Pool) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
return pool.token1;
|
|
393
|
-
}
|
|
394
|
-
// otherwise the token is invalid
|
|
388
|
+
} else if (pool instanceof Pool && pool.token0.wrapped.equals(currency)) {
|
|
389
|
+
return pool.token0;
|
|
390
|
+
} else if (pool instanceof Pool && pool.token1.wrapped.equals(currency)) {
|
|
391
|
+
return pool.token1;
|
|
395
392
|
} else {
|
|
396
393
|
throw new Error("Expected currency " + currency.symbol + " to be either " + pool.token0.symbol + " or " + pool.token1.symbol);
|
|
397
394
|
}
|
|
398
|
-
return currency; // this line needed for typescript to compile
|
|
399
395
|
}
|
|
400
396
|
|
|
401
397
|
var RouterActionType;
|
|
@@ -436,8 +432,8 @@ var CHAIN_CONFIGS = (_CHAIN_CONFIGS = {}, _CHAIN_CONFIGS[1] = {
|
|
|
436
432
|
address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
|
|
437
433
|
creationBlock: 3543575
|
|
438
434
|
}, _routerConfigs3[UniversalRouterVersion.V2_0] = {
|
|
439
|
-
address: '
|
|
440
|
-
creationBlock:
|
|
435
|
+
address: '0x4D73A4411CA1c660035e4AECC8270E5DdDEC8C17',
|
|
436
|
+
creationBlock: 6898582
|
|
441
437
|
}, _routerConfigs3)
|
|
442
438
|
}, _CHAIN_CONFIGS[137] = {
|
|
443
439
|
weth: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
|
|
@@ -612,6 +608,10 @@ var E_ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
|
|
|
612
608
|
var SENDER_AS_RECIPIENT = '0x0000000000000000000000000000000000000001';
|
|
613
609
|
var ROUTER_AS_RECIPIENT = '0x0000000000000000000000000000000000000002';
|
|
614
610
|
|
|
611
|
+
function getCurrencyAddress(currency) {
|
|
612
|
+
return currency.isNative ? ETH_ADDRESS : currency.wrapped.address;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
615
|
function encodeFeeBips(fee) {
|
|
616
616
|
return toHex(fee.multiply(10000).quotient);
|
|
617
617
|
}
|
|
@@ -625,7 +625,11 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
625
625
|
this.options = options;
|
|
626
626
|
this.tradeType = RouterActionType.UniswapTrade;
|
|
627
627
|
if (!!options.fee && !!options.flatFee) throw new Error('Only one fee option permitted');
|
|
628
|
-
if (this.inputRequiresWrap
|
|
628
|
+
if (this.inputRequiresWrap || this.inputRequiresUnwrap || this.options.useRouterBalance) {
|
|
629
|
+
this.payerIsUser = false;
|
|
630
|
+
} else {
|
|
631
|
+
this.payerIsUser = true;
|
|
632
|
+
}
|
|
629
633
|
}
|
|
630
634
|
var _proto = UniswapTrade.prototype;
|
|
631
635
|
_proto.encode = function encode(planner, _config) {
|
|
@@ -634,6 +638,10 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
634
638
|
if (this.inputRequiresWrap) {
|
|
635
639
|
// TODO: optimize if only one v2 pool we can directly send this to the pool
|
|
636
640
|
planner.addCommand(CommandType.WRAP_ETH, [ROUTER_AS_RECIPIENT, this.trade.maximumAmountIn(this.options.slippageTolerance).quotient.toString()]);
|
|
641
|
+
} else if (this.inputRequiresUnwrap) {
|
|
642
|
+
// send wrapped token to router to unwrap
|
|
643
|
+
planner.addCommand(CommandType.PERMIT2_TRANSFER_FROM, [this.trade.inputAmount.currency.address, ROUTER_AS_RECIPIENT, this.trade.maximumAmountIn(this.options.slippageTolerance).quotient.toString()]);
|
|
644
|
+
planner.addCommand(CommandType.UNWRAP_WETH, [ROUTER_AS_RECIPIENT, 0]);
|
|
637
645
|
}
|
|
638
646
|
// The overall recipient at the end of the trade, SENDER_AS_RECIPIENT uses the msg.sender
|
|
639
647
|
this.options.recipient = (_this$options$recipie = this.options.recipient) != null ? _this$options$recipie : SENDER_AS_RECIPIENT;
|
|
@@ -642,7 +650,7 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
642
650
|
// as it's still more gas-expensive even in this case, but has benefits
|
|
643
651
|
// in that the reversion probability is lower
|
|
644
652
|
var performAggregatedSlippageCheck = this.trade.tradeType === TradeType.EXACT_INPUT && this.trade.routes.length > 2;
|
|
645
|
-
var routerMustCustody = performAggregatedSlippageCheck || this.
|
|
653
|
+
var routerMustCustody = performAggregatedSlippageCheck || this.outputRequiresTransition || hasFeeOption(this.options);
|
|
646
654
|
for (var _iterator = _createForOfIteratorHelperLoose(this.trade.swaps), _step; !(_step = _iterator()).done;) {
|
|
647
655
|
var swap = _step.value;
|
|
648
656
|
switch (swap.route.protocol) {
|
|
@@ -665,11 +673,13 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
665
673
|
var minimumAmountOut = BigNumber.from(this.trade.minimumAmountOut(this.options.slippageTolerance).quotient.toString());
|
|
666
674
|
// The router custodies for 3 reasons: to unwrap, to take a fee, and/or to do a slippage check
|
|
667
675
|
if (routerMustCustody) {
|
|
676
|
+
var pools = this.trade.swaps[0].route.pools;
|
|
677
|
+
var pathOutputCurrencyAddress = getCurrencyAddress(getPathCurrency(this.trade.outputAmount.currency, pools[pools.length - 1]));
|
|
668
678
|
// If there is a fee, that percentage is sent to the fee recipient
|
|
669
679
|
// In the case where ETH is the output currency, the fee is taken in WETH (for gas reasons)
|
|
670
680
|
if (!!this.options.fee) {
|
|
671
681
|
var feeBips = encodeFeeBips(this.options.fee.fee);
|
|
672
|
-
planner.addCommand(CommandType.PAY_PORTION, [
|
|
682
|
+
planner.addCommand(CommandType.PAY_PORTION, [pathOutputCurrencyAddress, this.options.fee.recipient, feeBips]);
|
|
673
683
|
// If the trade is exact output, and a fee was taken, we must adjust the amount out to be the amount after the fee
|
|
674
684
|
// Otherwise we continue as expected with the trade's normal expected output
|
|
675
685
|
if (this.trade.tradeType === TradeType.EXACT_OUTPUT) {
|
|
@@ -681,7 +691,7 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
681
691
|
if (!!this.options.flatFee) {
|
|
682
692
|
var feeAmount = this.options.flatFee.amount;
|
|
683
693
|
if (minimumAmountOut.lt(feeAmount)) throw new Error('Flat fee amount greater than minimumAmountOut');
|
|
684
|
-
planner.addCommand(CommandType.TRANSFER, [
|
|
694
|
+
planner.addCommand(CommandType.TRANSFER, [pathOutputCurrencyAddress, this.options.flatFee.recipient, feeAmount]);
|
|
685
695
|
// If the trade is exact output, and a fee was taken, we must adjust the amount out to be the amount after the fee
|
|
686
696
|
// Otherwise we continue as expected with the trade's normal expected output
|
|
687
697
|
if (this.trade.tradeType === TradeType.EXACT_OUTPUT) {
|
|
@@ -692,14 +702,23 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
692
702
|
// by this if-else clause.
|
|
693
703
|
if (this.outputRequiresUnwrap) {
|
|
694
704
|
planner.addCommand(CommandType.UNWRAP_WETH, [this.options.recipient, minimumAmountOut]);
|
|
705
|
+
} else if (this.outputRequiresWrap) {
|
|
706
|
+
planner.addCommand(CommandType.WRAP_ETH, [this.options.recipient, CONTRACT_BALANCE]);
|
|
695
707
|
} else {
|
|
696
|
-
planner.addCommand(CommandType.SWEEP, [this.trade.outputAmount.currency
|
|
708
|
+
planner.addCommand(CommandType.SWEEP, [getCurrencyAddress(this.trade.outputAmount.currency), this.options.recipient, minimumAmountOut]);
|
|
697
709
|
}
|
|
698
710
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
711
|
+
// for exactOutput swaps with native input or that perform an inputToken transition (wrap or unwrap)
|
|
712
|
+
// we need to send back the change to the user
|
|
713
|
+
if (this.trade.tradeType === TradeType.EXACT_OUTPUT || riskOfPartialFill(this.trade)) {
|
|
714
|
+
if (this.inputRequiresWrap) {
|
|
715
|
+
planner.addCommand(CommandType.UNWRAP_WETH, [this.options.recipient, 0]);
|
|
716
|
+
} else if (this.inputRequiresUnwrap) {
|
|
717
|
+
planner.addCommand(CommandType.WRAP_ETH, [this.options.recipient, CONTRACT_BALANCE]);
|
|
718
|
+
} else if (this.trade.inputAmount.currency.isNative) {
|
|
719
|
+
// must refund extra native currency sent along for native v4 trades (no input transition)
|
|
720
|
+
planner.addCommand(CommandType.SWEEP, [ETH_ADDRESS, this.options.recipient, 0]);
|
|
721
|
+
}
|
|
703
722
|
}
|
|
704
723
|
if (this.options.safeMode) planner.addCommand(CommandType.SWEEP, [ETH_ADDRESS, this.options.recipient, 0]);
|
|
705
724
|
};
|
|
@@ -716,24 +735,42 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
716
735
|
}, {
|
|
717
736
|
key: "inputRequiresWrap",
|
|
718
737
|
get: function get() {
|
|
719
|
-
if (
|
|
720
|
-
return this.trade.inputAmount.currency.isNative;
|
|
738
|
+
if (this.isAllV4) {
|
|
739
|
+
return this.trade.inputAmount.currency.isNative && !this.trade.swaps[0].route.pathInput.isNative;
|
|
721
740
|
} else {
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
741
|
+
return this.trade.inputAmount.currency.isNative;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}, {
|
|
745
|
+
key: "inputRequiresUnwrap",
|
|
746
|
+
get: function get() {
|
|
747
|
+
if (this.isAllV4) {
|
|
748
|
+
return !this.trade.inputAmount.currency.isNative && this.trade.swaps[0].route.pathInput.isNative;
|
|
725
749
|
}
|
|
750
|
+
return false;
|
|
751
|
+
}
|
|
752
|
+
}, {
|
|
753
|
+
key: "outputRequiresWrap",
|
|
754
|
+
get: function get() {
|
|
755
|
+
if (this.isAllV4) {
|
|
756
|
+
return !this.trade.outputAmount.currency.isNative && this.trade.swaps[0].route.pathOutput.isNative;
|
|
757
|
+
}
|
|
758
|
+
return false;
|
|
726
759
|
}
|
|
727
760
|
}, {
|
|
728
761
|
key: "outputRequiresUnwrap",
|
|
729
762
|
get: function get() {
|
|
730
|
-
if (
|
|
731
|
-
return this.trade.outputAmount.currency.isNative;
|
|
763
|
+
if (this.isAllV4) {
|
|
764
|
+
return this.trade.outputAmount.currency.isNative && !this.trade.swaps[0].route.pathOutput.isNative;
|
|
732
765
|
} else {
|
|
733
|
-
|
|
734
|
-
return this.trade.outputAmount.currency.isNative && !this.trade.swaps[0].route.output.isNative;
|
|
766
|
+
return this.trade.outputAmount.currency.isNative;
|
|
735
767
|
}
|
|
736
768
|
}
|
|
769
|
+
}, {
|
|
770
|
+
key: "outputRequiresTransition",
|
|
771
|
+
get: function get() {
|
|
772
|
+
return this.outputRequiresWrap || this.outputRequiresUnwrap;
|
|
773
|
+
}
|
|
737
774
|
}]);
|
|
738
775
|
return UniswapTrade;
|
|
739
776
|
}();
|
|
@@ -777,23 +814,25 @@ function addV3Swap(planner, _ref2, tradeType, options, payerIsUser, routerMustCu
|
|
|
777
814
|
}
|
|
778
815
|
function addV4Swap(planner, _ref3, tradeType, options, payerIsUser, routerMustCustody) {
|
|
779
816
|
var _options$recipient;
|
|
780
|
-
var
|
|
781
|
-
|
|
782
|
-
|
|
817
|
+
var inputAmount = _ref3.inputAmount,
|
|
818
|
+
outputAmount = _ref3.outputAmount,
|
|
819
|
+
route = _ref3.route;
|
|
820
|
+
// create a deep copy of pools since v4Planner encoding tampers with array
|
|
821
|
+
var pools = route.pools.map(function (p) {
|
|
822
|
+
return p;
|
|
823
|
+
});
|
|
824
|
+
var v4Route = new Route(pools, inputAmount.currency, outputAmount.currency);
|
|
783
825
|
var trade = Trade$2.createUncheckedTrade({
|
|
784
|
-
route:
|
|
826
|
+
route: v4Route,
|
|
785
827
|
inputAmount: inputAmount,
|
|
786
828
|
outputAmount: outputAmount,
|
|
787
829
|
tradeType: tradeType
|
|
788
830
|
});
|
|
789
831
|
var slippageToleranceOnSwap = routerMustCustody && tradeType == TradeType.EXACT_INPUT ? undefined : options.slippageTolerance;
|
|
790
|
-
var inputWethFromRouter = inputAmount.currency.isNative && !route.input.isNative;
|
|
791
|
-
if (inputWethFromRouter && !payerIsUser) throw new Error('Inconsistent payer');
|
|
792
832
|
var v4Planner = new V4Planner();
|
|
793
833
|
v4Planner.addTrade(trade, slippageToleranceOnSwap);
|
|
794
|
-
v4Planner.addSettle(
|
|
795
|
-
|
|
796
|
-
v4Planner.addTake(outputAmount.currency, routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient);
|
|
834
|
+
v4Planner.addSettle(trade.route.pathInput, payerIsUser);
|
|
835
|
+
v4Planner.addTake(trade.route.pathOutput, routerMustCustody ? ROUTER_AS_RECIPIENT : (_options$recipient = options.recipient) != null ? _options$recipient : SENDER_AS_RECIPIENT);
|
|
797
836
|
planner.addCommand(CommandType.V4_SWAP, [v4Planner.finalize()]);
|
|
798
837
|
}
|
|
799
838
|
// encode a mixed route swap, i.e. including both v2 and v3 pools
|