@uniswap/router-sdk 2.7.3 → 2.9.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.
Files changed (113) hide show
  1. package/dist/{approveAndCall.d.ts → cjs/src/approveAndCall.d.ts} +33 -33
  2. package/dist/cjs/src/approveAndCall.js +111 -0
  3. package/dist/cjs/src/approveAndCall.js.map +1 -0
  4. package/dist/{constants.d.ts → cjs/src/constants.d.ts} +13 -13
  5. package/dist/cjs/src/constants.js +22 -0
  6. package/dist/cjs/src/constants.js.map +1 -0
  7. package/dist/{entities → cjs/src/entities}/mixedRoute/route.d.ts +29 -29
  8. package/dist/cjs/src/entities/mixedRoute/route.js +119 -0
  9. package/dist/cjs/src/entities/mixedRoute/route.js.map +1 -0
  10. package/dist/{entities → cjs/src/entities}/mixedRoute/trade.d.ts +183 -183
  11. package/dist/cjs/src/entities/mixedRoute/trade.js +354 -0
  12. package/dist/cjs/src/entities/mixedRoute/trade.js.map +1 -0
  13. package/dist/{entities → cjs/src/entities}/protocol.d.ts +6 -6
  14. package/dist/cjs/src/entities/protocol.js +11 -0
  15. package/dist/cjs/src/entities/protocol.js.map +1 -0
  16. package/dist/{entities → cjs/src/entities}/route.d.ts +40 -40
  17. package/dist/cjs/src/entities/route.js +63 -0
  18. package/dist/cjs/src/entities/route.js.map +1 -0
  19. package/dist/{entities → cjs/src/entities}/trade.d.ts +136 -127
  20. package/dist/cjs/src/entities/trade.js +370 -0
  21. package/dist/cjs/src/entities/trade.js.map +1 -0
  22. package/dist/{index.d.ts → cjs/src/index.d.ts} +14 -14
  23. package/dist/cjs/src/index.js +18 -0
  24. package/dist/cjs/src/index.js.map +1 -0
  25. package/dist/{multicallExtended.d.ts → cjs/src/multicallExtended.d.ts} +11 -11
  26. package/dist/cjs/src/multicallExtended.js +44 -0
  27. package/dist/cjs/src/multicallExtended.js.map +1 -0
  28. package/dist/{paymentsExtended.d.ts → cjs/src/paymentsExtended.d.ts} +15 -15
  29. package/dist/cjs/src/paymentsExtended.js +66 -0
  30. package/dist/cjs/src/paymentsExtended.js.map +1 -0
  31. package/dist/{swapRouter.d.ts → cjs/src/swapRouter.d.ts} +95 -95
  32. package/dist/cjs/src/swapRouter.js +439 -0
  33. package/dist/cjs/src/swapRouter.js.map +1 -0
  34. package/dist/{utils → cjs/src/utils}/TPool.d.ts +4 -4
  35. package/dist/cjs/src/utils/TPool.js +3 -0
  36. package/dist/cjs/src/utils/TPool.js.map +1 -0
  37. package/dist/{utils → cjs/src/utils}/encodeMixedRouteToPath.d.ts +10 -10
  38. package/dist/cjs/src/utils/encodeMixedRouteToPath.js +91 -0
  39. package/dist/cjs/src/utils/encodeMixedRouteToPath.js.map +1 -0
  40. package/dist/{utils → cjs/src/utils}/index.d.ts +16 -16
  41. package/dist/cjs/src/utils/index.js +51 -0
  42. package/dist/cjs/src/utils/index.js.map +1 -0
  43. package/dist/{utils → cjs/src/utils}/pathCurrency.d.ts +4 -4
  44. package/dist/cjs/src/utils/pathCurrency.js +35 -0
  45. package/dist/cjs/src/utils/pathCurrency.js.map +1 -0
  46. package/dist/esm/src/approveAndCall.d.ts +33 -0
  47. package/dist/esm/src/approveAndCall.js +105 -0
  48. package/dist/esm/src/approveAndCall.js.map +1 -0
  49. package/dist/esm/src/constants.d.ts +13 -0
  50. package/dist/esm/src/constants.js +18 -0
  51. package/dist/esm/src/constants.js.map +1 -0
  52. package/dist/esm/src/entities/mixedRoute/route.d.ts +29 -0
  53. package/dist/esm/src/entities/mixedRoute/route.js +114 -0
  54. package/dist/esm/src/entities/mixedRoute/route.js.map +1 -0
  55. package/dist/esm/src/entities/mixedRoute/trade.d.ts +183 -0
  56. package/dist/esm/src/entities/mixedRoute/trade.js +348 -0
  57. package/dist/esm/src/entities/mixedRoute/trade.js.map +1 -0
  58. package/dist/esm/src/entities/protocol.d.ts +6 -0
  59. package/dist/esm/src/entities/protocol.js +8 -0
  60. package/dist/esm/src/entities/protocol.js.map +1 -0
  61. package/dist/esm/src/entities/route.d.ts +40 -0
  62. package/dist/esm/src/entities/route.js +55 -0
  63. package/dist/esm/src/entities/route.js.map +1 -0
  64. package/dist/esm/src/entities/trade.d.ts +136 -0
  65. package/dist/esm/src/entities/trade.js +365 -0
  66. package/dist/esm/src/entities/trade.js.map +1 -0
  67. package/dist/esm/src/index.d.ts +14 -0
  68. package/dist/esm/src/index.js +15 -0
  69. package/dist/esm/src/index.js.map +1 -0
  70. package/dist/esm/src/multicallExtended.d.ts +11 -0
  71. package/dist/esm/src/multicallExtended.js +39 -0
  72. package/dist/esm/src/multicallExtended.js.map +1 -0
  73. package/dist/esm/src/paymentsExtended.d.ts +15 -0
  74. package/dist/esm/src/paymentsExtended.js +61 -0
  75. package/dist/esm/src/paymentsExtended.js.map +1 -0
  76. package/dist/esm/src/swapRouter.d.ts +95 -0
  77. package/dist/esm/src/swapRouter.js +434 -0
  78. package/dist/esm/src/swapRouter.js.map +1 -0
  79. package/dist/esm/src/utils/TPool.d.ts +4 -0
  80. package/dist/esm/src/utils/TPool.js +2 -0
  81. package/dist/esm/src/utils/TPool.js.map +1 -0
  82. package/dist/esm/src/utils/encodeMixedRouteToPath.d.ts +10 -0
  83. package/dist/esm/src/utils/encodeMixedRouteToPath.js +87 -0
  84. package/dist/esm/src/utils/encodeMixedRouteToPath.js.map +1 -0
  85. package/dist/esm/src/utils/index.d.ts +16 -0
  86. package/dist/esm/src/utils/index.js +46 -0
  87. package/dist/esm/src/utils/index.js.map +1 -0
  88. package/dist/esm/src/utils/pathCurrency.d.ts +4 -0
  89. package/dist/esm/src/utils/pathCurrency.js +30 -0
  90. package/dist/esm/src/utils/pathCurrency.js.map +1 -0
  91. package/dist/types/src/approveAndCall.d.ts +33 -0
  92. package/dist/types/src/constants.d.ts +13 -0
  93. package/dist/types/src/entities/mixedRoute/route.d.ts +29 -0
  94. package/dist/types/src/entities/mixedRoute/trade.d.ts +183 -0
  95. package/dist/types/src/entities/protocol.d.ts +6 -0
  96. package/dist/types/src/entities/route.d.ts +40 -0
  97. package/dist/types/src/entities/trade.d.ts +136 -0
  98. package/dist/types/src/index.d.ts +14 -0
  99. package/dist/types/src/multicallExtended.d.ts +11 -0
  100. package/dist/types/src/paymentsExtended.d.ts +15 -0
  101. package/dist/types/src/swapRouter.d.ts +95 -0
  102. package/dist/types/src/utils/TPool.d.ts +4 -0
  103. package/dist/types/src/utils/encodeMixedRouteToPath.d.ts +10 -0
  104. package/dist/types/src/utils/index.d.ts +16 -0
  105. package/dist/types/src/utils/pathCurrency.d.ts +4 -0
  106. package/package.json +31 -12
  107. package/dist/index.js +0 -8
  108. package/dist/router-sdk.cjs.development.js +0 -2250
  109. package/dist/router-sdk.cjs.development.js.map +0 -1
  110. package/dist/router-sdk.cjs.production.min.js +0 -2
  111. package/dist/router-sdk.cjs.production.min.js.map +0 -1
  112. package/dist/router-sdk.esm.js +0 -2217
  113. package/dist/router-sdk.esm.js.map +0 -1
@@ -0,0 +1,39 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import IMulticallExtended from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IMulticallExtended.sol/IMulticallExtended.json';
3
+ import { Multicall, toHex } from '@uniswap/v3-sdk';
4
+ function validateAndParseBytes32(bytes32) {
5
+ if (!bytes32.match(/^0x[0-9a-fA-F]{64}$/)) {
6
+ throw new Error(`${bytes32} is not valid bytes32.`);
7
+ }
8
+ return bytes32.toLowerCase();
9
+ }
10
+ export class MulticallExtended {
11
+ /**
12
+ * Cannot be constructed.
13
+ */
14
+ constructor() { }
15
+ static encodeMulticall(calldatas, validation) {
16
+ // if there's no validation, we can just fall back to regular multicall
17
+ if (typeof validation === 'undefined') {
18
+ return Multicall.encodeMulticall(calldatas);
19
+ }
20
+ // if there is validation, we have to normalize calldatas
21
+ if (!Array.isArray(calldatas)) {
22
+ calldatas = [calldatas];
23
+ }
24
+ // this means the validation value should be a previousBlockhash
25
+ if (typeof validation === 'string' && validation.startsWith('0x')) {
26
+ const previousBlockhash = validateAndParseBytes32(validation);
27
+ return MulticallExtended.INTERFACE.encodeFunctionData('multicall(bytes32,bytes[])', [
28
+ previousBlockhash,
29
+ calldatas,
30
+ ]);
31
+ }
32
+ else {
33
+ const deadline = toHex(validation);
34
+ return MulticallExtended.INTERFACE.encodeFunctionData('multicall(uint256,bytes[])', [deadline, calldatas]);
35
+ }
36
+ }
37
+ }
38
+ MulticallExtended.INTERFACE = new Interface(IMulticallExtended.abi);
39
+ //# sourceMappingURL=multicallExtended.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multicallExtended.js","sourceRoot":"","sources":["../../../src/multicallExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,kBAAkB,MAAM,8GAA8G,CAAA;AAC7I,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAKlD,SAAS,uBAAuB,CAAC,OAAe;IAC9C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,EAAE;QACzC,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,wBAAwB,CAAC,CAAA;KACpD;IAED,OAAO,OAAO,CAAC,WAAW,EAAE,CAAA;AAC9B,CAAC;AAED,MAAM,OAAgB,iBAAiB;IAGrC;;OAEG;IACH,gBAAuB,CAAC;IAEjB,MAAM,CAAC,eAAe,CAAC,SAA4B,EAAE,UAAuB;QACjF,uEAAuE;QACvE,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE;YACrC,OAAO,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;SAC5C;QAED,yDAAyD;QACzD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC7B,SAAS,GAAG,CAAC,SAAS,CAAC,CAAA;SACxB;QAED,gEAAgE;QAChE,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YACjE,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAA;YAC7D,OAAO,iBAAiB,CAAC,SAAS,CAAC,kBAAkB,CAAC,4BAA4B,EAAE;gBAClF,iBAAiB;gBACjB,SAAS;aACV,CAAC,CAAA;SACH;aAAM;YACL,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;YAClC,OAAO,iBAAiB,CAAC,SAAS,CAAC,kBAAkB,CAAC,4BAA4B,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;SAC3G;IACH,CAAC;;AA7Ba,2BAAS,GAAc,IAAI,SAAS,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAA"}
@@ -0,0 +1,15 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import { Token } from '@uniswap/sdk-core';
3
+ import { FeeOptions } from '@uniswap/v3-sdk';
4
+ import JSBI from 'jsbi';
5
+ export declare abstract class PaymentsExtended {
6
+ static INTERFACE: Interface;
7
+ /**
8
+ * Cannot be constructed.
9
+ */
10
+ private constructor();
11
+ static encodeUnwrapWETH9(amountMinimum: JSBI, recipient?: string, feeOptions?: FeeOptions): string;
12
+ static encodeSweepToken(token: Token, amountMinimum: JSBI, recipient?: string, feeOptions?: FeeOptions): string;
13
+ static encodePull(token: Token, amount: JSBI): string;
14
+ static encodeWrapETH(amount: JSBI): string;
15
+ }
@@ -0,0 +1,61 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import { validateAndParseAddress } from '@uniswap/sdk-core';
3
+ import IPeripheryPaymentsWithFeeExtended from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IPeripheryPaymentsWithFeeExtended.sol/IPeripheryPaymentsWithFeeExtended.json';
4
+ import { Payments, toHex } from '@uniswap/v3-sdk';
5
+ function encodeFeeBips(fee) {
6
+ return toHex(fee.multiply(10000).quotient);
7
+ }
8
+ export class PaymentsExtended {
9
+ /**
10
+ * Cannot be constructed.
11
+ */
12
+ constructor() { }
13
+ static encodeUnwrapWETH9(amountMinimum, recipient, feeOptions) {
14
+ // if there's a recipient, just pass it along
15
+ if (typeof recipient === 'string') {
16
+ return Payments.encodeUnwrapWETH9(amountMinimum, recipient, feeOptions);
17
+ }
18
+ if (!!feeOptions) {
19
+ const feeBips = encodeFeeBips(feeOptions.fee);
20
+ const feeRecipient = validateAndParseAddress(feeOptions.recipient);
21
+ return PaymentsExtended.INTERFACE.encodeFunctionData('unwrapWETH9WithFee(uint256,uint256,address)', [
22
+ toHex(amountMinimum),
23
+ feeBips,
24
+ feeRecipient,
25
+ ]);
26
+ }
27
+ else {
28
+ return PaymentsExtended.INTERFACE.encodeFunctionData('unwrapWETH9(uint256)', [toHex(amountMinimum)]);
29
+ }
30
+ }
31
+ static encodeSweepToken(token, amountMinimum, recipient, feeOptions) {
32
+ // if there's a recipient, just pass it along
33
+ if (typeof recipient === 'string') {
34
+ return Payments.encodeSweepToken(token, amountMinimum, recipient, feeOptions);
35
+ }
36
+ if (!!feeOptions) {
37
+ const feeBips = encodeFeeBips(feeOptions.fee);
38
+ const feeRecipient = validateAndParseAddress(feeOptions.recipient);
39
+ return PaymentsExtended.INTERFACE.encodeFunctionData('sweepTokenWithFee(address,uint256,uint256,address)', [
40
+ token.address,
41
+ toHex(amountMinimum),
42
+ feeBips,
43
+ feeRecipient,
44
+ ]);
45
+ }
46
+ else {
47
+ return PaymentsExtended.INTERFACE.encodeFunctionData('sweepToken(address,uint256)', [
48
+ token.address,
49
+ toHex(amountMinimum),
50
+ ]);
51
+ }
52
+ }
53
+ static encodePull(token, amount) {
54
+ return PaymentsExtended.INTERFACE.encodeFunctionData('pull', [token.address, toHex(amount)]);
55
+ }
56
+ static encodeWrapETH(amount) {
57
+ return PaymentsExtended.INTERFACE.encodeFunctionData('wrapETH', [toHex(amount)]);
58
+ }
59
+ }
60
+ PaymentsExtended.INTERFACE = new Interface(IPeripheryPaymentsWithFeeExtended.abi);
61
+ //# sourceMappingURL=paymentsExtended.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paymentsExtended.js","sourceRoot":"","sources":["../../../src/paymentsExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAkB,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAC3E,OAAO,iCAAiC,MAAM,4IAA4I,CAAA;AAC1L,OAAO,EAAc,QAAQ,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAG7D,SAAS,aAAa,CAAC,GAAY;IACjC,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAM,CAAC,CAAC,QAAQ,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,OAAgB,gBAAgB;IAGpC;;OAEG;IACH,gBAAuB,CAAC;IAEjB,MAAM,CAAC,iBAAiB,CAAC,aAAmB,EAAE,SAAkB,EAAE,UAAuB;QAC9F,6CAA6C;QAC7C,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;YACjC,OAAO,QAAQ,CAAC,iBAAiB,CAAC,aAAa,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;SACxE;QAED,IAAI,CAAC,CAAC,UAAU,EAAE;YAChB,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YAC7C,MAAM,YAAY,GAAG,uBAAuB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;YAElE,OAAO,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,CAAC,6CAA6C,EAAE;gBAClG,KAAK,CAAC,aAAa,CAAC;gBACpB,OAAO;gBACP,YAAY;aACb,CAAC,CAAA;SACH;aAAM;YACL,OAAO,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,CAAC,sBAAsB,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;SACrG;IACH,CAAC;IAEM,MAAM,CAAC,gBAAgB,CAC5B,KAAY,EACZ,aAAmB,EACnB,SAAkB,EAClB,UAAuB;QAEvB,6CAA6C;QAC7C,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;YACjC,OAAO,QAAQ,CAAC,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;SAC9E;QAED,IAAI,CAAC,CAAC,UAAU,EAAE;YAChB,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YAC7C,MAAM,YAAY,GAAG,uBAAuB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;YAElE,OAAO,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,CAAC,oDAAoD,EAAE;gBACzG,KAAK,CAAC,OAAO;gBACb,KAAK,CAAC,aAAa,CAAC;gBACpB,OAAO;gBACP,YAAY;aACb,CAAC,CAAA;SACH;aAAM;YACL,OAAO,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,CAAC,6BAA6B,EAAE;gBAClF,KAAK,CAAC,OAAO;gBACb,KAAK,CAAC,aAAa,CAAC;aACrB,CAAC,CAAA;SACH;IACH,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,KAAY,EAAE,MAAY;QACjD,OAAO,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAC9F,CAAC;IAEM,MAAM,CAAC,aAAa,CAAC,MAAY;QACtC,OAAO,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAClF,CAAC;;AA9Da,0BAAS,GAAc,IAAI,SAAS,CAAC,iCAAiC,CAAC,GAAG,CAAC,CAAA"}
@@ -0,0 +1,95 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import { Currency, Percent, TradeType } from '@uniswap/sdk-core';
3
+ import { Trade as V2Trade } from '@uniswap/v2-sdk';
4
+ import { FeeOptions, MethodParameters, PermitOptions, Position, Trade as V3Trade } from '@uniswap/v3-sdk';
5
+ import { ApprovalTypes, CondensedAddLiquidityOptions } from './approveAndCall';
6
+ import { Trade } from './entities/trade';
7
+ import { Validation } from './multicallExtended';
8
+ import { MixedRouteTrade } from './entities/mixedRoute/trade';
9
+ /**
10
+ * Options for producing the arguments to send calls to the router.
11
+ */
12
+ export interface SwapOptions {
13
+ /**
14
+ * How much the execution price is allowed to move unfavorably from the trade execution price.
15
+ */
16
+ slippageTolerance: Percent;
17
+ /**
18
+ * The account that should receive the output. If omitted, output is sent to msg.sender.
19
+ */
20
+ recipient?: string;
21
+ /**
22
+ * Either deadline (when the transaction expires, in epoch seconds), or previousBlockhash.
23
+ */
24
+ deadlineOrPreviousBlockhash?: Validation;
25
+ /**
26
+ * The optional permit parameters for spending the input.
27
+ */
28
+ inputTokenPermit?: PermitOptions;
29
+ /**
30
+ * Optional information for taking a fee on output.
31
+ */
32
+ fee?: FeeOptions;
33
+ }
34
+ export interface SwapAndAddOptions extends SwapOptions {
35
+ /**
36
+ * The optional permit parameters for pulling in remaining output token.
37
+ */
38
+ outputTokenPermit?: PermitOptions;
39
+ }
40
+ type AnyTradeType = Trade<Currency, Currency, TradeType> | V2Trade<Currency, Currency, TradeType> | V3Trade<Currency, Currency, TradeType> | MixedRouteTrade<Currency, Currency, TradeType> | (V2Trade<Currency, Currency, TradeType> | V3Trade<Currency, Currency, TradeType> | MixedRouteTrade<Currency, Currency, TradeType>)[];
41
+ /**
42
+ * Represents the Uniswap V2 + V3 SwapRouter02, and has static methods for helping execute trades.
43
+ */
44
+ export declare abstract class SwapRouter {
45
+ static INTERFACE: Interface;
46
+ /**
47
+ * Cannot be constructed.
48
+ */
49
+ private constructor();
50
+ /**
51
+ * @notice Generates the calldata for a Swap with a V2 Route.
52
+ * @param trade The V2Trade to encode.
53
+ * @param options SwapOptions to use for the trade.
54
+ * @param routerMustCustody Flag for whether funds should be sent to the router
55
+ * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
56
+ * @returns A string array of calldatas for the trade.
57
+ */
58
+ private static encodeV2Swap;
59
+ /**
60
+ * @notice Generates the calldata for a Swap with a V3 Route.
61
+ * @param trade The V3Trade to encode.
62
+ * @param options SwapOptions to use for the trade.
63
+ * @param routerMustCustody Flag for whether funds should be sent to the router
64
+ * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
65
+ * @returns A string array of calldatas for the trade.
66
+ */
67
+ private static encodeV3Swap;
68
+ /**
69
+ * @notice Generates the calldata for a MixedRouteSwap. Since single hop routes are not MixedRoutes, we will instead generate
70
+ * them via the existing encodeV3Swap and encodeV2Swap methods.
71
+ * @param trade The MixedRouteTrade to encode.
72
+ * @param options SwapOptions to use for the trade.
73
+ * @param routerMustCustody Flag for whether funds should be sent to the router
74
+ * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
75
+ * @returns A string array of calldatas for the trade.
76
+ */
77
+ private static encodeMixedRouteSwap;
78
+ private static encodeSwaps;
79
+ /**
80
+ * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
81
+ * @param trades to produce call parameters for
82
+ * @param options options for the call parameters
83
+ */
84
+ static swapCallParameters(trades: Trade<Currency, Currency, TradeType> | V2Trade<Currency, Currency, TradeType> | V3Trade<Currency, Currency, TradeType> | MixedRouteTrade<Currency, Currency, TradeType> | (V2Trade<Currency, Currency, TradeType> | V3Trade<Currency, Currency, TradeType> | MixedRouteTrade<Currency, Currency, TradeType>)[], options: SwapOptions): MethodParameters;
85
+ /**
86
+ * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
87
+ * @param trades to produce call parameters for
88
+ * @param options options for the call parameters
89
+ */
90
+ static swapAndAddCallParameters(trades: AnyTradeType, options: SwapAndAddOptions, position: Position, addLiquidityOptions: CondensedAddLiquidityOptions, tokenInApprovalType: ApprovalTypes, tokenOutApprovalType: ApprovalTypes): MethodParameters;
91
+ private static riskOfPartialFill;
92
+ private static v3TradeWithHighPriceImpact;
93
+ private static getPositionAmounts;
94
+ }
95
+ export {};
@@ -0,0 +1,434 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import { CurrencyAmount, Percent, TradeType, validateAndParseAddress, WETH9 } from '@uniswap/sdk-core';
3
+ import ISwapRouter02 from '@uniswap/swap-router-contracts/artifacts/contracts/interfaces/ISwapRouter02.sol/ISwapRouter02.json';
4
+ import { Trade as V2Trade } from '@uniswap/v2-sdk';
5
+ import { encodeRouteToPath, Payments, Pool as V3Pool, Position, SelfPermit, toHex, Trade as V3Trade, } from '@uniswap/v3-sdk';
6
+ import { Pool as V4Pool } from '@uniswap/v4-sdk';
7
+ import invariant from 'tiny-invariant';
8
+ import JSBI from 'jsbi';
9
+ import { ADDRESS_THIS, MSG_SENDER } from './constants';
10
+ import { ApproveAndCall, ApprovalTypes } from './approveAndCall';
11
+ import { Trade } from './entities/trade';
12
+ import { Protocol } from './entities/protocol';
13
+ import { MixedRoute } from './entities/route';
14
+ import { MulticallExtended } from './multicallExtended';
15
+ import { PaymentsExtended } from './paymentsExtended';
16
+ import { MixedRouteTrade } from './entities/mixedRoute/trade';
17
+ import { encodeMixedRouteToPath } from './utils/encodeMixedRouteToPath';
18
+ import { MixedRouteSDK } from './entities/mixedRoute/route';
19
+ import { partitionMixedRouteByProtocol, getOutputOfPools } from './utils';
20
+ const ZERO = JSBI.BigInt(0);
21
+ const REFUND_ETH_PRICE_IMPACT_THRESHOLD = new Percent(JSBI.BigInt(50), JSBI.BigInt(100));
22
+ /**
23
+ * Represents the Uniswap V2 + V3 SwapRouter02, and has static methods for helping execute trades.
24
+ */
25
+ export class SwapRouter {
26
+ /**
27
+ * Cannot be constructed.
28
+ */
29
+ constructor() { }
30
+ /**
31
+ * @notice Generates the calldata for a Swap with a V2 Route.
32
+ * @param trade The V2Trade to encode.
33
+ * @param options SwapOptions to use for the trade.
34
+ * @param routerMustCustody Flag for whether funds should be sent to the router
35
+ * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
36
+ * @returns A string array of calldatas for the trade.
37
+ */
38
+ static encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
39
+ const amountIn = toHex(trade.maximumAmountIn(options.slippageTolerance).quotient);
40
+ const amountOut = toHex(trade.minimumAmountOut(options.slippageTolerance).quotient);
41
+ const path = trade.route.path.map((token) => token.address);
42
+ const recipient = routerMustCustody
43
+ ? ADDRESS_THIS
44
+ : typeof options.recipient === 'undefined'
45
+ ? MSG_SENDER
46
+ : validateAndParseAddress(options.recipient);
47
+ if (trade.tradeType === TradeType.EXACT_INPUT) {
48
+ const exactInputParams = [amountIn, performAggregatedSlippageCheck ? 0 : amountOut, path, recipient];
49
+ return SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams);
50
+ }
51
+ else {
52
+ const exactOutputParams = [amountOut, amountIn, path, recipient];
53
+ return SwapRouter.INTERFACE.encodeFunctionData('swapTokensForExactTokens', exactOutputParams);
54
+ }
55
+ }
56
+ /**
57
+ * @notice Generates the calldata for a Swap with a V3 Route.
58
+ * @param trade The V3Trade to encode.
59
+ * @param options SwapOptions to use for the trade.
60
+ * @param routerMustCustody Flag for whether funds should be sent to the router
61
+ * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
62
+ * @returns A string array of calldatas for the trade.
63
+ */
64
+ static encodeV3Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
65
+ const calldatas = [];
66
+ for (const { route, inputAmount, outputAmount } of trade.swaps) {
67
+ const amountIn = toHex(trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient);
68
+ const amountOut = toHex(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient);
69
+ // flag for whether the trade is single hop or not
70
+ const singleHop = route.pools.length === 1;
71
+ const recipient = routerMustCustody
72
+ ? ADDRESS_THIS
73
+ : typeof options.recipient === 'undefined'
74
+ ? MSG_SENDER
75
+ : validateAndParseAddress(options.recipient);
76
+ if (singleHop) {
77
+ if (trade.tradeType === TradeType.EXACT_INPUT) {
78
+ const exactInputSingleParams = {
79
+ tokenIn: route.tokenPath[0].address,
80
+ tokenOut: route.tokenPath[1].address,
81
+ fee: route.pools[0].fee,
82
+ recipient,
83
+ amountIn,
84
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
85
+ sqrtPriceLimitX96: 0,
86
+ };
87
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInputSingle', [exactInputSingleParams]));
88
+ }
89
+ else {
90
+ const exactOutputSingleParams = {
91
+ tokenIn: route.tokenPath[0].address,
92
+ tokenOut: route.tokenPath[1].address,
93
+ fee: route.pools[0].fee,
94
+ recipient,
95
+ amountOut,
96
+ amountInMaximum: amountIn,
97
+ sqrtPriceLimitX96: 0,
98
+ };
99
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactOutputSingle', [exactOutputSingleParams]));
100
+ }
101
+ }
102
+ else {
103
+ const path = encodeRouteToPath(route, trade.tradeType === TradeType.EXACT_OUTPUT);
104
+ if (trade.tradeType === TradeType.EXACT_INPUT) {
105
+ const exactInputParams = {
106
+ path,
107
+ recipient,
108
+ amountIn,
109
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
110
+ };
111
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInput', [exactInputParams]));
112
+ }
113
+ else {
114
+ const exactOutputParams = {
115
+ path,
116
+ recipient,
117
+ amountOut,
118
+ amountInMaximum: amountIn,
119
+ };
120
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactOutput', [exactOutputParams]));
121
+ }
122
+ }
123
+ }
124
+ return calldatas;
125
+ }
126
+ /**
127
+ * @notice Generates the calldata for a MixedRouteSwap. Since single hop routes are not MixedRoutes, we will instead generate
128
+ * them via the existing encodeV3Swap and encodeV2Swap methods.
129
+ * @param trade The MixedRouteTrade to encode.
130
+ * @param options SwapOptions to use for the trade.
131
+ * @param routerMustCustody Flag for whether funds should be sent to the router
132
+ * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
133
+ * @returns A string array of calldatas for the trade.
134
+ */
135
+ static encodeMixedRouteSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
136
+ const calldatas = [];
137
+ invariant(trade.tradeType === TradeType.EXACT_INPUT, 'TRADE_TYPE');
138
+ for (const { route, inputAmount, outputAmount } of trade.swaps) {
139
+ if (route.pools.some((pool) => pool instanceof V4Pool))
140
+ throw new Error('Encoding mixed routes with V4 not supported');
141
+ const amountIn = toHex(trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient);
142
+ const amountOut = toHex(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient);
143
+ // flag for whether the trade is single hop or not
144
+ const singleHop = route.pools.length === 1;
145
+ const recipient = routerMustCustody
146
+ ? ADDRESS_THIS
147
+ : typeof options.recipient === 'undefined'
148
+ ? MSG_SENDER
149
+ : validateAndParseAddress(options.recipient);
150
+ const mixedRouteIsAllV3 = (route) => {
151
+ return route.pools.every((pool) => pool instanceof V3Pool);
152
+ };
153
+ if (singleHop) {
154
+ /// For single hop, since it isn't really a mixedRoute, we'll just mimic behavior of V3 or V2
155
+ /// We don't use encodeV3Swap() or encodeV2Swap() because casting the trade to a V3Trade or V2Trade is overcomplex
156
+ if (mixedRouteIsAllV3(route)) {
157
+ const exactInputSingleParams = {
158
+ tokenIn: route.path[0].wrapped.address,
159
+ tokenOut: route.path[1].wrapped.address,
160
+ fee: route.pools[0].fee,
161
+ recipient,
162
+ amountIn,
163
+ amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
164
+ sqrtPriceLimitX96: 0,
165
+ };
166
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInputSingle', [exactInputSingleParams]));
167
+ }
168
+ else {
169
+ const path = route.path.map((token) => token.wrapped.address);
170
+ const exactInputParams = [amountIn, performAggregatedSlippageCheck ? 0 : amountOut, path, recipient];
171
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams));
172
+ }
173
+ }
174
+ else {
175
+ const sections = partitionMixedRouteByProtocol(route);
176
+ const isLastSectionInRoute = (i) => {
177
+ return i === sections.length - 1;
178
+ };
179
+ let outputToken;
180
+ let inputToken = route.input.wrapped;
181
+ for (let i = 0; i < sections.length; i++) {
182
+ const section = sections[i];
183
+ /// Now, we get output of this section
184
+ outputToken = getOutputOfPools(section, inputToken);
185
+ const newRouteOriginal = new MixedRouteSDK([...section], section[0].token0.equals(inputToken) ? section[0].token0 : section[0].token1, outputToken);
186
+ const newRoute = new MixedRoute(newRouteOriginal);
187
+ /// Previous output is now input
188
+ inputToken = outputToken.wrapped;
189
+ if (mixedRouteIsAllV3(newRoute)) {
190
+ const path = encodeMixedRouteToPath(newRoute);
191
+ const exactInputParams = {
192
+ path,
193
+ // By default router holds funds until the last swap, then it is sent to the recipient
194
+ // special case exists where we are unwrapping WETH output, in which case `routerMustCustody` is set to true
195
+ // and router still holds the funds. That logic bundled into how the value of `recipient` is calculated
196
+ recipient: isLastSectionInRoute(i) ? recipient : ADDRESS_THIS,
197
+ amountIn: i === 0 ? amountIn : 0,
198
+ amountOutMinimum: !isLastSectionInRoute(i) ? 0 : amountOut,
199
+ };
200
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInput', [exactInputParams]));
201
+ }
202
+ else {
203
+ const exactInputParams = [
204
+ i === 0 ? amountIn : 0,
205
+ !isLastSectionInRoute(i) ? 0 : amountOut,
206
+ newRoute.path.map((token) => token.wrapped.address),
207
+ isLastSectionInRoute(i) ? recipient : ADDRESS_THIS, // to
208
+ ];
209
+ calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams));
210
+ }
211
+ }
212
+ }
213
+ }
214
+ return calldatas;
215
+ }
216
+ static encodeSwaps(trades, options, isSwapAndAdd) {
217
+ // If dealing with an instance of the aggregated Trade object, unbundle it to individual trade objects.
218
+ if (trades instanceof Trade) {
219
+ invariant(trades.swaps.every((swap) => swap.route.protocol === Protocol.V3 ||
220
+ swap.route.protocol === Protocol.V2 ||
221
+ swap.route.protocol === Protocol.MIXED), 'UNSUPPORTED_PROTOCOL (encoding routes with v4 not supported)');
222
+ let individualTrades = [];
223
+ for (const { route, inputAmount, outputAmount } of trades.swaps) {
224
+ if (route.protocol === Protocol.V2) {
225
+ individualTrades.push(new V2Trade(route, trades.tradeType === TradeType.EXACT_INPUT ? inputAmount : outputAmount, trades.tradeType));
226
+ }
227
+ else if (route.protocol === Protocol.V3) {
228
+ individualTrades.push(V3Trade.createUncheckedTrade({
229
+ route: route,
230
+ inputAmount,
231
+ outputAmount,
232
+ tradeType: trades.tradeType,
233
+ }));
234
+ }
235
+ else if (route.protocol === Protocol.MIXED) {
236
+ individualTrades.push(
237
+ /// we can change the naming of this function on MixedRouteTrade if needed
238
+ MixedRouteTrade.createUncheckedTrade({
239
+ route: route,
240
+ inputAmount,
241
+ outputAmount,
242
+ tradeType: trades.tradeType,
243
+ }));
244
+ }
245
+ else {
246
+ throw new Error('UNSUPPORTED_TRADE_PROTOCOL');
247
+ }
248
+ }
249
+ trades = individualTrades;
250
+ }
251
+ if (!Array.isArray(trades)) {
252
+ trades = [trades];
253
+ }
254
+ const numberOfTrades = trades.reduce((numberOfTrades, trade) => numberOfTrades + (trade instanceof V3Trade || trade instanceof MixedRouteTrade ? trade.swaps.length : 1), 0);
255
+ const sampleTrade = trades[0];
256
+ // All trades should have the same starting/ending currency and trade type
257
+ invariant(trades.every((trade) => trade.inputAmount.currency.equals(sampleTrade.inputAmount.currency)), 'TOKEN_IN_DIFF');
258
+ invariant(trades.every((trade) => trade.outputAmount.currency.equals(sampleTrade.outputAmount.currency)), 'TOKEN_OUT_DIFF');
259
+ invariant(trades.every((trade) => trade.tradeType === sampleTrade.tradeType), 'TRADE_TYPE_DIFF');
260
+ const calldatas = [];
261
+ const inputIsNative = sampleTrade.inputAmount.currency.isNative;
262
+ const outputIsNative = sampleTrade.outputAmount.currency.isNative;
263
+ // flag for whether we want to perform an aggregated slippage check
264
+ // 1. when there are >2 exact input trades. this is only a heuristic,
265
+ // as it's still more gas-expensive even in this case, but has benefits
266
+ // in that the reversion probability is lower
267
+ const performAggregatedSlippageCheck = sampleTrade.tradeType === TradeType.EXACT_INPUT && numberOfTrades > 2;
268
+ // flag for whether funds should be send first to the router
269
+ // 1. when receiving ETH (which much be unwrapped from WETH)
270
+ // 2. when a fee on the output is being taken
271
+ // 3. when performing swap and add
272
+ // 4. when performing an aggregated slippage check
273
+ const routerMustCustody = outputIsNative || !!options.fee || !!isSwapAndAdd || performAggregatedSlippageCheck;
274
+ // encode permit if necessary
275
+ if (options.inputTokenPermit) {
276
+ invariant(sampleTrade.inputAmount.currency.isToken, 'NON_TOKEN_PERMIT');
277
+ calldatas.push(SelfPermit.encodePermit(sampleTrade.inputAmount.currency, options.inputTokenPermit));
278
+ }
279
+ for (const trade of trades) {
280
+ if (trade instanceof V2Trade) {
281
+ calldatas.push(SwapRouter.encodeV2Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck));
282
+ }
283
+ else if (trade instanceof V3Trade) {
284
+ for (const calldata of SwapRouter.encodeV3Swap(trade, options, routerMustCustody, performAggregatedSlippageCheck)) {
285
+ calldatas.push(calldata);
286
+ }
287
+ }
288
+ else if (trade instanceof MixedRouteTrade) {
289
+ for (const calldata of SwapRouter.encodeMixedRouteSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck)) {
290
+ calldatas.push(calldata);
291
+ }
292
+ }
293
+ else {
294
+ throw new Error('Unsupported trade object');
295
+ }
296
+ }
297
+ const ZERO_IN = CurrencyAmount.fromRawAmount(sampleTrade.inputAmount.currency, 0);
298
+ const ZERO_OUT = CurrencyAmount.fromRawAmount(sampleTrade.outputAmount.currency, 0);
299
+ const minimumAmountOut = trades.reduce((sum, trade) => sum.add(trade.minimumAmountOut(options.slippageTolerance)), ZERO_OUT);
300
+ const quoteAmountOut = trades.reduce((sum, trade) => sum.add(trade.outputAmount), ZERO_OUT);
301
+ const totalAmountIn = trades.reduce((sum, trade) => sum.add(trade.maximumAmountIn(options.slippageTolerance)), ZERO_IN);
302
+ return {
303
+ calldatas,
304
+ sampleTrade,
305
+ routerMustCustody,
306
+ inputIsNative,
307
+ outputIsNative,
308
+ totalAmountIn,
309
+ minimumAmountOut,
310
+ quoteAmountOut,
311
+ };
312
+ }
313
+ /**
314
+ * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
315
+ * @param trades to produce call parameters for
316
+ * @param options options for the call parameters
317
+ */
318
+ static swapCallParameters(trades, options) {
319
+ const { calldatas, sampleTrade, routerMustCustody, inputIsNative, outputIsNative, totalAmountIn, minimumAmountOut, } = SwapRouter.encodeSwaps(trades, options);
320
+ // unwrap or sweep
321
+ if (routerMustCustody) {
322
+ if (outputIsNative) {
323
+ calldatas.push(PaymentsExtended.encodeUnwrapWETH9(minimumAmountOut.quotient, options.recipient, options.fee));
324
+ }
325
+ else {
326
+ calldatas.push(PaymentsExtended.encodeSweepToken(sampleTrade.outputAmount.currency.wrapped, minimumAmountOut.quotient, options.recipient, options.fee));
327
+ }
328
+ }
329
+ // must refund when paying in ETH: either with an uncertain input amount OR if there's a chance of a partial fill.
330
+ // unlike ERC20's, the full ETH value must be sent in the transaction, so the rest must be refunded.
331
+ if (inputIsNative && (sampleTrade.tradeType === TradeType.EXACT_OUTPUT || SwapRouter.riskOfPartialFill(trades))) {
332
+ calldatas.push(Payments.encodeRefundETH());
333
+ }
334
+ return {
335
+ calldata: MulticallExtended.encodeMulticall(calldatas, options.deadlineOrPreviousBlockhash),
336
+ value: toHex(inputIsNative ? totalAmountIn.quotient : ZERO),
337
+ };
338
+ }
339
+ /**
340
+ * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
341
+ * @param trades to produce call parameters for
342
+ * @param options options for the call parameters
343
+ */
344
+ static swapAndAddCallParameters(trades, options, position, addLiquidityOptions, tokenInApprovalType, tokenOutApprovalType) {
345
+ const { calldatas, inputIsNative, outputIsNative, sampleTrade, totalAmountIn: totalAmountSwapped, quoteAmountOut, minimumAmountOut, } = SwapRouter.encodeSwaps(trades, options, true);
346
+ // encode output token permit if necessary
347
+ if (options.outputTokenPermit) {
348
+ invariant(quoteAmountOut.currency.isToken, 'NON_TOKEN_PERMIT_OUTPUT');
349
+ calldatas.push(SelfPermit.encodePermit(quoteAmountOut.currency, options.outputTokenPermit));
350
+ }
351
+ const chainId = sampleTrade.route.chainId;
352
+ const zeroForOne = position.pool.token0.wrapped.address === totalAmountSwapped.currency.wrapped.address;
353
+ const { positionAmountIn, positionAmountOut } = SwapRouter.getPositionAmounts(position, zeroForOne);
354
+ // if tokens are native they will be converted to WETH9
355
+ const tokenIn = inputIsNative ? WETH9[chainId] : positionAmountIn.currency.wrapped;
356
+ const tokenOut = outputIsNative ? WETH9[chainId] : positionAmountOut.currency.wrapped;
357
+ // if swap output does not make up whole outputTokenBalanceDesired, pull in remaining tokens for adding liquidity
358
+ const amountOutRemaining = positionAmountOut.subtract(quoteAmountOut.wrapped);
359
+ if (amountOutRemaining.greaterThan(CurrencyAmount.fromRawAmount(positionAmountOut.currency, 0))) {
360
+ // if output is native, this means the remaining portion is included as native value in the transaction
361
+ // and must be wrapped. Otherwise, pull in remaining ERC20 token.
362
+ outputIsNative
363
+ ? calldatas.push(PaymentsExtended.encodeWrapETH(amountOutRemaining.quotient))
364
+ : calldatas.push(PaymentsExtended.encodePull(tokenOut, amountOutRemaining.quotient));
365
+ }
366
+ // if input is native, convert to WETH9, else pull ERC20 token
367
+ inputIsNative
368
+ ? calldatas.push(PaymentsExtended.encodeWrapETH(positionAmountIn.quotient))
369
+ : calldatas.push(PaymentsExtended.encodePull(tokenIn, positionAmountIn.quotient));
370
+ // approve token balances to NFTManager
371
+ if (tokenInApprovalType !== ApprovalTypes.NOT_REQUIRED)
372
+ calldatas.push(ApproveAndCall.encodeApprove(tokenIn, tokenInApprovalType));
373
+ if (tokenOutApprovalType !== ApprovalTypes.NOT_REQUIRED)
374
+ calldatas.push(ApproveAndCall.encodeApprove(tokenOut, tokenOutApprovalType));
375
+ // represents a position with token amounts resulting from a swap with maximum slippage
376
+ // hence the minimal amount out possible.
377
+ const minimalPosition = Position.fromAmounts({
378
+ pool: position.pool,
379
+ tickLower: position.tickLower,
380
+ tickUpper: position.tickUpper,
381
+ amount0: zeroForOne ? position.amount0.quotient.toString() : minimumAmountOut.quotient.toString(),
382
+ amount1: zeroForOne ? minimumAmountOut.quotient.toString() : position.amount1.quotient.toString(),
383
+ useFullPrecision: false,
384
+ });
385
+ // encode NFTManager add liquidity
386
+ calldatas.push(ApproveAndCall.encodeAddLiquidity(position, minimalPosition, addLiquidityOptions, options.slippageTolerance));
387
+ // sweep remaining tokens
388
+ inputIsNative
389
+ ? calldatas.push(PaymentsExtended.encodeUnwrapWETH9(ZERO))
390
+ : calldatas.push(PaymentsExtended.encodeSweepToken(tokenIn, ZERO));
391
+ outputIsNative
392
+ ? calldatas.push(PaymentsExtended.encodeUnwrapWETH9(ZERO))
393
+ : calldatas.push(PaymentsExtended.encodeSweepToken(tokenOut, ZERO));
394
+ let value;
395
+ if (inputIsNative) {
396
+ value = totalAmountSwapped.wrapped.add(positionAmountIn.wrapped).quotient;
397
+ }
398
+ else if (outputIsNative) {
399
+ value = amountOutRemaining.quotient;
400
+ }
401
+ else {
402
+ value = ZERO;
403
+ }
404
+ return {
405
+ calldata: MulticallExtended.encodeMulticall(calldatas, options.deadlineOrPreviousBlockhash),
406
+ value: value.toString(),
407
+ };
408
+ }
409
+ // if price impact is very high, there's a chance of hitting max/min prices resulting in a partial fill of the swap
410
+ static riskOfPartialFill(trades) {
411
+ if (Array.isArray(trades)) {
412
+ return trades.some((trade) => {
413
+ return SwapRouter.v3TradeWithHighPriceImpact(trade);
414
+ });
415
+ }
416
+ else {
417
+ return SwapRouter.v3TradeWithHighPriceImpact(trades);
418
+ }
419
+ }
420
+ static v3TradeWithHighPriceImpact(trade) {
421
+ return !(trade instanceof V2Trade) && trade.priceImpact.greaterThan(REFUND_ETH_PRICE_IMPACT_THRESHOLD);
422
+ }
423
+ static getPositionAmounts(position, zeroForOne) {
424
+ const { amount0, amount1 } = position.mintAmounts;
425
+ const currencyAmount0 = CurrencyAmount.fromRawAmount(position.pool.token0, amount0);
426
+ const currencyAmount1 = CurrencyAmount.fromRawAmount(position.pool.token1, amount1);
427
+ const [positionAmountIn, positionAmountOut] = zeroForOne
428
+ ? [currencyAmount0, currencyAmount1]
429
+ : [currencyAmount1, currencyAmount0];
430
+ return { positionAmountIn, positionAmountOut };
431
+ }
432
+ }
433
+ SwapRouter.INTERFACE = new Interface(ISwapRouter02.abi);
434
+ //# sourceMappingURL=swapRouter.js.map