@uniswap/universal-router-sdk 4.6.1 → 4.7.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.
- package/dist/entities/actions/uniswap.d.ts +3 -0
- package/dist/universal-router-sdk.cjs.development.js +84 -36
- 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 +85 -37
- package/dist/universal-router-sdk.esm.js.map +1 -1
- package/dist/utils/getCurrencyAddress.d.ts +2 -0
- package/package.json +7 -7
|
@@ -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;
|
|
@@ -404,7 +400,7 @@ var RouterActionType;
|
|
|
404
400
|
RouterActionType["UnwrapWETH"] = "UnwrapWETH";
|
|
405
401
|
})(RouterActionType || (RouterActionType = {}));
|
|
406
402
|
|
|
407
|
-
var _routerConfigs, _routerConfigs2, _routerConfigs3, _routerConfigs4, _routerConfigs5, _routerConfigs6, _routerConfigs7, _routerConfigs8, _routerConfigs9, _routerConfigs10, _routerConfigs11, _routerConfigs12, _routerConfigs13, _routerConfigs14, _routerConfigs15, _routerConfigs16, _routerConfigs17, _routerConfigs18, _routerConfigs19, _routerConfigs20, _CHAIN_CONFIGS;
|
|
403
|
+
var _routerConfigs, _routerConfigs2, _routerConfigs3, _routerConfigs4, _routerConfigs5, _routerConfigs6, _routerConfigs7, _routerConfigs8, _routerConfigs9, _routerConfigs10, _routerConfigs11, _routerConfigs12, _routerConfigs13, _routerConfigs14, _routerConfigs15, _routerConfigs16, _routerConfigs17, _routerConfigs18, _routerConfigs19, _routerConfigs20, _routerConfigs21, _CHAIN_CONFIGS;
|
|
408
404
|
var UniversalRouterVersion;
|
|
409
405
|
(function (UniversalRouterVersion) {
|
|
410
406
|
UniversalRouterVersion["V1_2"] = "1.2";
|
|
@@ -592,6 +588,15 @@ var CHAIN_CONFIGS = (_CHAIN_CONFIGS = {}, _CHAIN_CONFIGS[1] = {
|
|
|
592
588
|
address: '0xcA7577Afb670147c7b211C798B97118bd36058F3',
|
|
593
589
|
creationBlock: 1490973
|
|
594
590
|
}, _routerConfigs20)
|
|
591
|
+
}, _CHAIN_CONFIGS[130] = {
|
|
592
|
+
weth: '0x4200000000000000000000000000000000000006',
|
|
593
|
+
routerConfigs: (_routerConfigs21 = {}, _routerConfigs21[UniversalRouterVersion.V1_2] = {
|
|
594
|
+
address: '0x4D73A4411CA1c660035e4AECC8270E5DdDEC8C17',
|
|
595
|
+
creationBlock: 23678
|
|
596
|
+
}, _routerConfigs21[UniversalRouterVersion.V2_0] = {
|
|
597
|
+
address: '0x4D73A4411CA1c660035e4AECC8270E5DdDEC8C17',
|
|
598
|
+
creationBlock: 23678
|
|
599
|
+
}, _routerConfigs21)
|
|
595
600
|
}, _CHAIN_CONFIGS);
|
|
596
601
|
var UNIVERSAL_ROUTER_ADDRESS = function UNIVERSAL_ROUTER_ADDRESS(version, chainId) {
|
|
597
602
|
if (!(chainId in CHAIN_CONFIGS)) throw new Error("Universal Router not deployed on chain " + chainId);
|
|
@@ -612,6 +617,10 @@ var E_ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
|
|
|
612
617
|
var SENDER_AS_RECIPIENT = '0x0000000000000000000000000000000000000001';
|
|
613
618
|
var ROUTER_AS_RECIPIENT = '0x0000000000000000000000000000000000000002';
|
|
614
619
|
|
|
620
|
+
function getCurrencyAddress(currency) {
|
|
621
|
+
return currency.isNative ? ETH_ADDRESS : currency.wrapped.address;
|
|
622
|
+
}
|
|
623
|
+
|
|
615
624
|
function encodeFeeBips(fee) {
|
|
616
625
|
return toHex(fee.multiply(10000).quotient);
|
|
617
626
|
}
|
|
@@ -625,7 +634,11 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
625
634
|
this.options = options;
|
|
626
635
|
this.tradeType = RouterActionType.UniswapTrade;
|
|
627
636
|
if (!!options.fee && !!options.flatFee) throw new Error('Only one fee option permitted');
|
|
628
|
-
if (this.inputRequiresWrap
|
|
637
|
+
if (this.inputRequiresWrap || this.inputRequiresUnwrap || this.options.useRouterBalance) {
|
|
638
|
+
this.payerIsUser = false;
|
|
639
|
+
} else {
|
|
640
|
+
this.payerIsUser = true;
|
|
641
|
+
}
|
|
629
642
|
}
|
|
630
643
|
var _proto = UniswapTrade.prototype;
|
|
631
644
|
_proto.encode = function encode(planner, _config) {
|
|
@@ -634,6 +647,10 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
634
647
|
if (this.inputRequiresWrap) {
|
|
635
648
|
// TODO: optimize if only one v2 pool we can directly send this to the pool
|
|
636
649
|
planner.addCommand(CommandType.WRAP_ETH, [ROUTER_AS_RECIPIENT, this.trade.maximumAmountIn(this.options.slippageTolerance).quotient.toString()]);
|
|
650
|
+
} else if (this.inputRequiresUnwrap) {
|
|
651
|
+
// send wrapped token to router to unwrap
|
|
652
|
+
planner.addCommand(CommandType.PERMIT2_TRANSFER_FROM, [this.trade.inputAmount.currency.address, ROUTER_AS_RECIPIENT, this.trade.maximumAmountIn(this.options.slippageTolerance).quotient.toString()]);
|
|
653
|
+
planner.addCommand(CommandType.UNWRAP_WETH, [ROUTER_AS_RECIPIENT, 0]);
|
|
637
654
|
}
|
|
638
655
|
// The overall recipient at the end of the trade, SENDER_AS_RECIPIENT uses the msg.sender
|
|
639
656
|
this.options.recipient = (_this$options$recipie = this.options.recipient) != null ? _this$options$recipie : SENDER_AS_RECIPIENT;
|
|
@@ -642,7 +659,7 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
642
659
|
// as it's still more gas-expensive even in this case, but has benefits
|
|
643
660
|
// in that the reversion probability is lower
|
|
644
661
|
var performAggregatedSlippageCheck = this.trade.tradeType === TradeType.EXACT_INPUT && this.trade.routes.length > 2;
|
|
645
|
-
var routerMustCustody = performAggregatedSlippageCheck || this.
|
|
662
|
+
var routerMustCustody = performAggregatedSlippageCheck || this.outputRequiresTransition || hasFeeOption(this.options);
|
|
646
663
|
for (var _iterator = _createForOfIteratorHelperLoose(this.trade.swaps), _step; !(_step = _iterator()).done;) {
|
|
647
664
|
var swap = _step.value;
|
|
648
665
|
switch (swap.route.protocol) {
|
|
@@ -665,11 +682,13 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
665
682
|
var minimumAmountOut = BigNumber.from(this.trade.minimumAmountOut(this.options.slippageTolerance).quotient.toString());
|
|
666
683
|
// The router custodies for 3 reasons: to unwrap, to take a fee, and/or to do a slippage check
|
|
667
684
|
if (routerMustCustody) {
|
|
685
|
+
var pools = this.trade.swaps[0].route.pools;
|
|
686
|
+
var pathOutputCurrencyAddress = getCurrencyAddress(getPathCurrency(this.trade.outputAmount.currency, pools[pools.length - 1]));
|
|
668
687
|
// If there is a fee, that percentage is sent to the fee recipient
|
|
669
688
|
// In the case where ETH is the output currency, the fee is taken in WETH (for gas reasons)
|
|
670
689
|
if (!!this.options.fee) {
|
|
671
690
|
var feeBips = encodeFeeBips(this.options.fee.fee);
|
|
672
|
-
planner.addCommand(CommandType.PAY_PORTION, [
|
|
691
|
+
planner.addCommand(CommandType.PAY_PORTION, [pathOutputCurrencyAddress, this.options.fee.recipient, feeBips]);
|
|
673
692
|
// 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
693
|
// Otherwise we continue as expected with the trade's normal expected output
|
|
675
694
|
if (this.trade.tradeType === TradeType.EXACT_OUTPUT) {
|
|
@@ -681,7 +700,7 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
681
700
|
if (!!this.options.flatFee) {
|
|
682
701
|
var feeAmount = this.options.flatFee.amount;
|
|
683
702
|
if (minimumAmountOut.lt(feeAmount)) throw new Error('Flat fee amount greater than minimumAmountOut');
|
|
684
|
-
planner.addCommand(CommandType.TRANSFER, [
|
|
703
|
+
planner.addCommand(CommandType.TRANSFER, [pathOutputCurrencyAddress, this.options.flatFee.recipient, feeAmount]);
|
|
685
704
|
// 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
705
|
// Otherwise we continue as expected with the trade's normal expected output
|
|
687
706
|
if (this.trade.tradeType === TradeType.EXACT_OUTPUT) {
|
|
@@ -692,14 +711,23 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
692
711
|
// by this if-else clause.
|
|
693
712
|
if (this.outputRequiresUnwrap) {
|
|
694
713
|
planner.addCommand(CommandType.UNWRAP_WETH, [this.options.recipient, minimumAmountOut]);
|
|
714
|
+
} else if (this.outputRequiresWrap) {
|
|
715
|
+
planner.addCommand(CommandType.WRAP_ETH, [this.options.recipient, CONTRACT_BALANCE]);
|
|
695
716
|
} else {
|
|
696
|
-
planner.addCommand(CommandType.SWEEP, [this.trade.outputAmount.currency
|
|
717
|
+
planner.addCommand(CommandType.SWEEP, [getCurrencyAddress(this.trade.outputAmount.currency), this.options.recipient, minimumAmountOut]);
|
|
697
718
|
}
|
|
698
719
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
720
|
+
// for exactOutput swaps with native input or that perform an inputToken transition (wrap or unwrap)
|
|
721
|
+
// we need to send back the change to the user
|
|
722
|
+
if (this.trade.tradeType === TradeType.EXACT_OUTPUT || riskOfPartialFill(this.trade)) {
|
|
723
|
+
if (this.inputRequiresWrap) {
|
|
724
|
+
planner.addCommand(CommandType.UNWRAP_WETH, [this.options.recipient, 0]);
|
|
725
|
+
} else if (this.inputRequiresUnwrap) {
|
|
726
|
+
planner.addCommand(CommandType.WRAP_ETH, [this.options.recipient, CONTRACT_BALANCE]);
|
|
727
|
+
} else if (this.trade.inputAmount.currency.isNative) {
|
|
728
|
+
// must refund extra native currency sent along for native v4 trades (no input transition)
|
|
729
|
+
planner.addCommand(CommandType.SWEEP, [ETH_ADDRESS, this.options.recipient, 0]);
|
|
730
|
+
}
|
|
703
731
|
}
|
|
704
732
|
if (this.options.safeMode) planner.addCommand(CommandType.SWEEP, [ETH_ADDRESS, this.options.recipient, 0]);
|
|
705
733
|
};
|
|
@@ -716,24 +744,42 @@ var UniswapTrade = /*#__PURE__*/function () {
|
|
|
716
744
|
}, {
|
|
717
745
|
key: "inputRequiresWrap",
|
|
718
746
|
get: function get() {
|
|
719
|
-
if (
|
|
720
|
-
return this.trade.inputAmount.currency.isNative;
|
|
747
|
+
if (this.isAllV4) {
|
|
748
|
+
return this.trade.inputAmount.currency.isNative && !this.trade.swaps[0].route.pathInput.isNative;
|
|
721
749
|
} else {
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
750
|
+
return this.trade.inputAmount.currency.isNative;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}, {
|
|
754
|
+
key: "inputRequiresUnwrap",
|
|
755
|
+
get: function get() {
|
|
756
|
+
if (this.isAllV4) {
|
|
757
|
+
return !this.trade.inputAmount.currency.isNative && this.trade.swaps[0].route.pathInput.isNative;
|
|
725
758
|
}
|
|
759
|
+
return false;
|
|
760
|
+
}
|
|
761
|
+
}, {
|
|
762
|
+
key: "outputRequiresWrap",
|
|
763
|
+
get: function get() {
|
|
764
|
+
if (this.isAllV4) {
|
|
765
|
+
return !this.trade.outputAmount.currency.isNative && this.trade.swaps[0].route.pathOutput.isNative;
|
|
766
|
+
}
|
|
767
|
+
return false;
|
|
726
768
|
}
|
|
727
769
|
}, {
|
|
728
770
|
key: "outputRequiresUnwrap",
|
|
729
771
|
get: function get() {
|
|
730
|
-
if (
|
|
731
|
-
return this.trade.outputAmount.currency.isNative;
|
|
772
|
+
if (this.isAllV4) {
|
|
773
|
+
return this.trade.outputAmount.currency.isNative && !this.trade.swaps[0].route.pathOutput.isNative;
|
|
732
774
|
} else {
|
|
733
|
-
|
|
734
|
-
return this.trade.outputAmount.currency.isNative && !this.trade.swaps[0].route.output.isNative;
|
|
775
|
+
return this.trade.outputAmount.currency.isNative;
|
|
735
776
|
}
|
|
736
777
|
}
|
|
778
|
+
}, {
|
|
779
|
+
key: "outputRequiresTransition",
|
|
780
|
+
get: function get() {
|
|
781
|
+
return this.outputRequiresWrap || this.outputRequiresUnwrap;
|
|
782
|
+
}
|
|
737
783
|
}]);
|
|
738
784
|
return UniswapTrade;
|
|
739
785
|
}();
|
|
@@ -777,23 +823,25 @@ function addV3Swap(planner, _ref2, tradeType, options, payerIsUser, routerMustCu
|
|
|
777
823
|
}
|
|
778
824
|
function addV4Swap(planner, _ref3, tradeType, options, payerIsUser, routerMustCustody) {
|
|
779
825
|
var _options$recipient;
|
|
780
|
-
var
|
|
781
|
-
|
|
782
|
-
|
|
826
|
+
var inputAmount = _ref3.inputAmount,
|
|
827
|
+
outputAmount = _ref3.outputAmount,
|
|
828
|
+
route = _ref3.route;
|
|
829
|
+
// create a deep copy of pools since v4Planner encoding tampers with array
|
|
830
|
+
var pools = route.pools.map(function (p) {
|
|
831
|
+
return p;
|
|
832
|
+
});
|
|
833
|
+
var v4Route = new Route(pools, inputAmount.currency, outputAmount.currency);
|
|
783
834
|
var trade = Trade$2.createUncheckedTrade({
|
|
784
|
-
route:
|
|
835
|
+
route: v4Route,
|
|
785
836
|
inputAmount: inputAmount,
|
|
786
837
|
outputAmount: outputAmount,
|
|
787
838
|
tradeType: tradeType
|
|
788
839
|
});
|
|
789
840
|
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
841
|
var v4Planner = new V4Planner();
|
|
793
842
|
v4Planner.addTrade(trade, slippageToleranceOnSwap);
|
|
794
|
-
v4Planner.addSettle(
|
|
795
|
-
|
|
796
|
-
v4Planner.addTake(outputAmount.currency, routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient);
|
|
843
|
+
v4Planner.addSettle(trade.route.pathInput, payerIsUser);
|
|
844
|
+
v4Planner.addTake(trade.route.pathOutput, routerMustCustody ? ROUTER_AS_RECIPIENT : (_options$recipient = options.recipient) != null ? _options$recipient : SENDER_AS_RECIPIENT);
|
|
797
845
|
planner.addCommand(CommandType.V4_SWAP, [v4Planner.finalize()]);
|
|
798
846
|
}
|
|
799
847
|
// encode a mixed route swap, i.e. including both v2 and v3 pools
|