@paraswap/dex-lib 4.7.20-native-insert-amount.3 → 4.7.20-native-insert-amount.4

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 (148) hide show
  1. package/build/dex/idle-dao/idle-dao.d.ts +1 -0
  2. package/build/dex/idle-dao/idle-dao.js +23 -11
  3. package/build/dex/idle-dao/idle-dao.js.map +1 -1
  4. package/build/dex/index.js +12 -15
  5. package/build/dex/index.js.map +1 -1
  6. package/build/dex/maker-psm/maker-psm.d.ts +4 -41
  7. package/build/dex/maker-psm/maker-psm.js +40 -143
  8. package/build/dex/maker-psm/maker-psm.js.map +1 -1
  9. package/build/dex/uniswap-v2/constants.js +1 -0
  10. package/build/dex/uniswap-v2/constants.js.map +1 -1
  11. package/build/executor/Executor02BytecodeBuilderMultiRoute.d.ts +101 -0
  12. package/build/executor/Executor02BytecodeBuilderMultiRoute.js +878 -0
  13. package/build/executor/Executor02BytecodeBuilderMultiRoute.js.map +1 -0
  14. package/package.json +1 -1
  15. package/build/abi/PendleRouterStatic.json +0 -19
  16. package/build/abi/apex-defi/ApexDefiFactory.abi.json +0 -1749
  17. package/build/abi/apex-defi/ApexDefiRouter.abi.json +0 -1120
  18. package/build/abi/apex-defi/ApexDefiToken.abi.json +0 -229
  19. package/build/abi/apex-defi/ApexDefiWrapper.abi.json +0 -92
  20. package/build/abi/apex-defi/ApexDefiWrapperFactory.abi.json +0 -1107
  21. package/build/abi/pangolin-v3/PangolinV3StateMulticall.abi.json +0 -796
  22. package/build/abi/pendle/pendle-deployer.abi.json +0 -520
  23. package/build/abi/pendle/pendle-oracle.abi.json +0 -413
  24. package/build/abi/ring-v2/few-wrapped-token.json +0 -587
  25. package/build/abi/ring-v2/ring-v2-factory.json +0 -125
  26. package/build/abi/ring-v2/ring-v2-pool.json +0 -461
  27. package/build/abi/ring-v2/ring-v2-router.json +0 -332
  28. package/build/abi/stabull/stabull-curve.json +0 -738
  29. package/build/abi/stabull/stabull-router.json +0 -76
  30. package/build/abi/uniswap-v4/hooks/SpotDynamicFeeManager.json +0 -26
  31. package/build/abi/uniswap-v4/hooks/SpotHook.json +0 -54
  32. package/build/abi/uniswap-v4/hooks/SpotPolicyManager.json +0 -45
  33. package/build/abi/uniswap-v4/hooks/cabalcoin-hook.abi.json +0 -682
  34. package/build/abi/uniswap-v4/hooks/fee-hook.abi.json +0 -1335
  35. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.d.ts +0 -29
  36. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.js +0 -153
  37. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.js.map +0 -1
  38. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.d.ts +0 -40
  39. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.js +0 -323
  40. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.js.map +0 -1
  41. package/build/dex/aave-pt-to-underlying/config.d.ts +0 -3
  42. package/build/dex/aave-pt-to-underlying/config.js +0 -24
  43. package/build/dex/aave-pt-to-underlying/config.js.map +0 -1
  44. package/build/dex/aave-pt-to-underlying/constants.d.ts +0 -2
  45. package/build/dex/aave-pt-to-underlying/constants.js +0 -6
  46. package/build/dex/aave-pt-to-underlying/constants.js.map +0 -1
  47. package/build/dex/aave-pt-to-underlying/types.d.ts +0 -24
  48. package/build/dex/aave-pt-to-underlying/types.js +0 -3
  49. package/build/dex/aave-pt-to-underlying/types.js.map +0 -1
  50. package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.d.ts +0 -39
  51. package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.js +0 -244
  52. package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.js.map +0 -1
  53. package/build/dex/aave-pt-to-usdc/config.d.ts +0 -3
  54. package/build/dex/aave-pt-to-usdc/config.js +0 -47
  55. package/build/dex/aave-pt-to-usdc/config.js.map +0 -1
  56. package/build/dex/aave-pt-to-usdc/constants.d.ts +0 -2
  57. package/build/dex/aave-pt-to-usdc/constants.js +0 -6
  58. package/build/dex/aave-pt-to-usdc/constants.js.map +0 -1
  59. package/build/dex/aave-pt-to-usdc/types.d.ts +0 -22
  60. package/build/dex/aave-pt-to-usdc/types.js +0 -3
  61. package/build/dex/aave-pt-to-usdc/types.js.map +0 -1
  62. package/build/dex/apex-defi/apex-defi-factory.d.ts +0 -26
  63. package/build/dex/apex-defi/apex-defi-factory.js +0 -53
  64. package/build/dex/apex-defi/apex-defi-factory.js.map +0 -1
  65. package/build/dex/apex-defi/apex-defi-pool.d.ts +0 -55
  66. package/build/dex/apex-defi/apex-defi-pool.js +0 -247
  67. package/build/dex/apex-defi/apex-defi-pool.js.map +0 -1
  68. package/build/dex/apex-defi/apex-defi-wrapper-factory.d.ts +0 -57
  69. package/build/dex/apex-defi/apex-defi-wrapper-factory.js +0 -250
  70. package/build/dex/apex-defi/apex-defi-wrapper-factory.js.map +0 -1
  71. package/build/dex/apex-defi/apex-defi.d.ts +0 -97
  72. package/build/dex/apex-defi/apex-defi.js +0 -1021
  73. package/build/dex/apex-defi/apex-defi.js.map +0 -1
  74. package/build/dex/apex-defi/config.d.ts +0 -4
  75. package/build/dex/apex-defi/config.js +0 -138
  76. package/build/dex/apex-defi/config.js.map +0 -1
  77. package/build/dex/apex-defi/types.d.ts +0 -32
  78. package/build/dex/apex-defi/types.js +0 -3
  79. package/build/dex/apex-defi/types.js.map +0 -1
  80. package/build/dex/apex-defi/utils.d.ts +0 -46
  81. package/build/dex/apex-defi/utils.js +0 -133
  82. package/build/dex/apex-defi/utils.js.map +0 -1
  83. package/build/dex/miro-migrator/miro-migrator-state.d.ts +0 -27
  84. package/build/dex/miro-migrator/miro-migrator-state.js +0 -89
  85. package/build/dex/miro-migrator/miro-migrator-state.js.map +0 -1
  86. package/build/dex/stabull/config.d.ts +0 -3
  87. package/build/dex/stabull/config.js +0 -177
  88. package/build/dex/stabull/config.js.map +0 -1
  89. package/build/dex/stabull/stabull-pool.d.ts +0 -46
  90. package/build/dex/stabull/stabull-pool.js +0 -113
  91. package/build/dex/stabull/stabull-pool.js.map +0 -1
  92. package/build/dex/stabull/stabull.d.ts +0 -55
  93. package/build/dex/stabull/stabull.js +0 -286
  94. package/build/dex/stabull/stabull.js.map +0 -1
  95. package/build/dex/stabull/types.d.ts +0 -21
  96. package/build/dex/stabull/types.js +0 -3
  97. package/build/dex/stabull/types.js.map +0 -1
  98. package/build/dex/uniswap-v3/forks/pangolin-v3/utils.d.ts +0 -4
  99. package/build/dex/uniswap-v3/forks/pangolin-v3/utils.js +0 -56
  100. package/build/dex/uniswap-v3/forks/pangolin-v3/utils.js.map +0 -1
  101. package/build/dex/uniswap-v4/hooks/arena.d.ts +0 -6
  102. package/build/dex/uniswap-v4/hooks/arena.js +0 -10
  103. package/build/dex/uniswap-v4/hooks/arena.js.map +0 -1
  104. package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.d.ts +0 -0
  105. package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.js +0 -2
  106. package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.js.map +0 -1
  107. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.d.ts +0 -7
  108. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.js +0 -28
  109. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.js.map +0 -1
  110. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.d.ts +0 -0
  111. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.js +0 -2
  112. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.js.map +0 -1
  113. package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.d.ts +0 -7
  114. package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.js +0 -28
  115. package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.js.map +0 -1
  116. package/build/dex/uniswap-v4/hooks/fee-hook/types.d.ts +0 -0
  117. package/build/dex/uniswap-v4/hooks/fee-hook/types.js +0 -2
  118. package/build/dex/uniswap-v4/hooks/fee-hook/types.js.map +0 -1
  119. package/build/dex/uniswap-v4/hooks/index.d.ts +0 -1
  120. package/build/dex/uniswap-v4/hooks/index.js +0 -18
  121. package/build/dex/uniswap-v4/hooks/index.js.map +0 -1
  122. package/build/dex/uniswap-v4/hooks/spot.d.ts +0 -15
  123. package/build/dex/uniswap-v4/hooks/spot.js +0 -109
  124. package/build/dex/uniswap-v4/hooks/spot.js.map +0 -1
  125. package/build/dex/uniswap-v4/hooks/template.d.ts +0 -150
  126. package/build/dex/uniswap-v4/hooks/template.js +0 -104
  127. package/build/dex/uniswap-v4/hooks/template.js.map +0 -1
  128. package/build/dex/usdc-transmuter/usdc-transmuter-pool.d.ts +0 -26
  129. package/build/dex/usdc-transmuter/usdc-transmuter-pool.js +0 -75
  130. package/build/dex/usdc-transmuter/usdc-transmuter-pool.js.map +0 -1
  131. package/build/dex/usual/usual-usdc-usdc.d.ts +0 -17
  132. package/build/dex/usual/usual-usdc-usdc.js +0 -59
  133. package/build/dex/usual/usual-usdc-usdc.js.map +0 -1
  134. package/build/dex/yo/config.d.ts +0 -3
  135. package/build/dex/yo/config.js +0 -21
  136. package/build/dex/yo/config.js.map +0 -1
  137. package/build/dex/yo/types.d.ts +0 -13
  138. package/build/dex/yo/types.js +0 -3
  139. package/build/dex/yo/types.js.map +0 -1
  140. package/build/dex/yo/yo-pool.d.ts +0 -13
  141. package/build/dex/yo/yo-pool.js +0 -26
  142. package/build/dex/yo/yo-pool.js.map +0 -1
  143. package/build/dex/yo/yo.d.ts +0 -39
  144. package/build/dex/yo/yo.js +0 -248
  145. package/build/dex/yo/yo.js.map +0 -1
  146. package/build/implementations/api-paraswap-sdk.d.ts +0 -25
  147. package/build/implementations/api-paraswap-sdk.js +0 -102
  148. package/build/implementations/api-paraswap-sdk.js.map +0 -1
@@ -0,0 +1,878 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Executor02BytecodeBuilderMultiRoute = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const types_1 = require("./types");
6
+ const utils_1 = require("../utils");
7
+ const ExecutorBytecodeBuilder_1 = require("./ExecutorBytecodeBuilder");
8
+ const constants_1 = require("./constants");
9
+ const utils_2 = require("./utils");
10
+ const { utils: { hexlify, hexDataLength, hexConcat, hexZeroPad, solidityPack }, } = ethers_1.ethers;
11
+ // Disclaimer: Current encoding has a lot of complexity introduced to handle wraps/unwraps inside the route
12
+ // but since RouteAdvisor release, we rely only on wrapped tokens inside the route and handle wraps/unwraps on dex level
13
+ // so in theory we can simplify a lot of this logic in the future releases
14
+ /**
15
+ * Class to build bytecode for Executor02 - simpleSwap with N DEXs (VERTICAL_BRANCH), multiSwaps (VERTICAL_BRANCH_HORIZONTAL_SEQUENCE) and megaswaps (NESTED_VERTICAL_BRANCH_HORIZONTAL_SEQUENCE)
16
+ */
17
+ class Executor02BytecodeBuilderMultiRoute extends ExecutorBytecodeBuilder_1.ExecutorBytecodeBuilder {
18
+ type = types_1.Executors.TWO;
19
+ /**
20
+ * Executor02 Flags:
21
+ * switch (flag % 4):
22
+ * case 0: don't insert fromAmount
23
+ * case 1: sendEth equal to fromAmount
24
+ * case 2: sendEth equal to fromAmount + insert fromAmount
25
+ * case 3: insert fromAmount
26
+
27
+ * switch (flag % 3):
28
+ * case 0: don't check balance after swap
29
+ * case 1: check eth balance after swap
30
+ * case 2: check destToken balance after swap
31
+ */
32
+ buildSimpleSwapFlags(params) {
33
+ const { maybeWethCallData, swapExchange, swap } = params;
34
+ const { srcToken, destToken } = swap;
35
+ const isEthSrc = (0, utils_1.isETHAddress)(srcToken);
36
+ const isEthDest = (0, utils_1.isETHAddress)(destToken);
37
+ const exchangeParam = swapExchange.build.dexParams;
38
+ const { dexFuncHasRecipient, needWrapNative, specialDexFlag, specialDexSupportsInsertFromAmount, swappedAmountNotPresentInExchangeData, preSwapUnwrapCalldata, sendEthButSupportsInsertFromAmount, } = exchangeParam;
39
+ const needWrap = needWrapNative && isEthSrc && maybeWethCallData?.deposit;
40
+ const needUnwrap = needWrapNative && isEthDest && maybeWethCallData?.withdraw;
41
+ const isSpecialDex = specialDexFlag !== undefined && specialDexFlag !== types_1.SpecialDex.DEFAULT;
42
+ const forcePreventInsertFromAmount = swappedAmountNotPresentInExchangeData ||
43
+ (isSpecialDex && !specialDexSupportsInsertFromAmount);
44
+ let dexFlag = forcePreventInsertFromAmount
45
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP
46
+ : types_1.Flag.INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 0 or 3
47
+ let approveFlag = types_1.Flag.DONT_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 0
48
+ if (isEthSrc && !needWrap) {
49
+ dexFlag = dexFuncHasRecipient
50
+ ? !sendEthButSupportsInsertFromAmount
51
+ ? types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 9
52
+ : types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_PLUS_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 18
53
+ : !sendEthButSupportsInsertFromAmount
54
+ ? types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP // 5
55
+ : types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_PLUS_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 18
56
+ }
57
+ else if (isEthDest && !needUnwrap) {
58
+ dexFlag = forcePreventInsertFromAmount
59
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_CHECK_ETH_BALANCE_AFTER_SWAP
60
+ : types_1.Flag.INSERT_FROM_AMOUNT_CHECK_ETH_BALANCE_AFTER_SWAP; // 4 or 7
61
+ }
62
+ else if (!dexFuncHasRecipient || (isEthDest && needUnwrap)) {
63
+ dexFlag = forcePreventInsertFromAmount
64
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP
65
+ : types_1.Flag.INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP; // 8 or 11
66
+ }
67
+ // Actual srcToken is eth, because we'll unwrap weth before swap.
68
+ // Need to check balance, some dexes don't have 1:1 ETH -> custom_ETH rate
69
+ if (preSwapUnwrapCalldata) {
70
+ dexFlag =
71
+ types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP;
72
+ }
73
+ return {
74
+ dexFlag,
75
+ approveFlag,
76
+ };
77
+ }
78
+ /**
79
+ * Executor02 Flags:
80
+ * switch (flag % 4):
81
+ * case 0: don't instert fromAmount
82
+ * case 1: sendEth equal to fromAmount
83
+ * case 2: sendEth equal to fromAmount + insert fromAmount
84
+ * case 3: insert fromAmount
85
+
86
+ * switch (flag % 3):
87
+ * case 0: don't check balance after swap
88
+ * case 1: check eth balance after swap
89
+ * case 2: check destToken balance after swap
90
+ */
91
+ buildMultiMegaSwapFlags(params) {
92
+ const { swaps, swap, swapExchange, maybeWethCallData, swapIndex, swapExchangeIndex, priceRouteType, } = params;
93
+ const exchangeParam = swapExchange.build.dexParams;
94
+ const { srcToken, destToken } = swap;
95
+ const applyVerticalBranching = this.doesSwapNeedToBeAsVerticalBranch(priceRouteType, swap);
96
+ const isHorizontalSequence = swaps.length > 1; // check if route is a multi-swap (horizontal sequence)
97
+ const isFirstSwap = swapIndex === 0;
98
+ const isLastSwap = !isFirstSwap && swapIndex === swaps.length - 1;
99
+ const { dexFuncHasRecipient, needWrapNative, specialDexFlag, specialDexSupportsInsertFromAmount, swappedAmountNotPresentInExchangeData, wethAddress, sendEthButSupportsInsertFromAmount, preSwapUnwrapCalldata, } = exchangeParam;
100
+ const isEthSrc = (0, utils_1.isETHAddress)(srcToken);
101
+ const isEthDest = (0, utils_1.isETHAddress)(destToken);
102
+ const isWethDest = (wethAddress && destToken.toLowerCase() === wethAddress.toLowerCase()) ||
103
+ this.dexHelper.config.isWETH(destToken);
104
+ const isSpecialDex = specialDexFlag !== undefined && specialDexFlag !== types_1.SpecialDex.DEFAULT;
105
+ const forcePreventInsertFromAmount = swappedAmountNotPresentInExchangeData ||
106
+ (isSpecialDex && !specialDexSupportsInsertFromAmount);
107
+ const forceBalanceOfCheck = (isSpecialDex &&
108
+ isHorizontalSequence &&
109
+ !applyVerticalBranching &&
110
+ !isLastSwap) ||
111
+ !dexFuncHasRecipient;
112
+ const needUnwrap = needWrapNative && isEthDest && maybeWethCallData?.withdraw;
113
+ const needSendEth = isEthSrc && !needWrapNative;
114
+ const needCheckEthBalance = isEthDest && !needWrapNative;
115
+ const anyDexOnSwapDoesntNeedWrapNative = this.anyDexOnSwapDoesntNeedWrapNative(swap);
116
+ // check if current exchange is the last with needWrapNative
117
+ const isLastExchangeWithNeedWrapNative = this.isLastExchangeWithNeedWrapNative(swap, swapExchangeIndex);
118
+ // for the first part, basically replicates the logic from `unwrap after last swap` in buildSingleSwapExchangeCallData
119
+ const needCheckSrcTokenBalanceOf = (needUnwrap &&
120
+ (!applyVerticalBranching ||
121
+ (applyVerticalBranching && anyDexOnSwapDoesntNeedWrapNative)) &&
122
+ (isLastExchangeWithNeedWrapNative || exchangeParam.wethAddress)) ||
123
+ (isHorizontalSequence && !applyVerticalBranching && !isLastSwap);
124
+ let dexFlag;
125
+ let approveFlag = types_1.Flag.DONT_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 0
126
+ if (needSendEth) {
127
+ const preventInsertForSendEth = forcePreventInsertFromAmount || !sendEthButSupportsInsertFromAmount;
128
+ dexFlag =
129
+ needCheckSrcTokenBalanceOf || forceBalanceOfCheck
130
+ ? preventInsertForSendEth
131
+ ? types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP // 5
132
+ : types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_PLUS_INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP // 14
133
+ : dexFuncHasRecipient
134
+ ? preventInsertForSendEth
135
+ ? types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 9
136
+ : types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_PLUS_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 18
137
+ : preventInsertForSendEth
138
+ ? types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP // 5
139
+ : types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_PLUS_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 18
140
+ }
141
+ else if (needCheckEthBalance) {
142
+ dexFlag =
143
+ needCheckSrcTokenBalanceOf || forceBalanceOfCheck
144
+ ? forcePreventInsertFromAmount && dexFuncHasRecipient
145
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_CHECK_ETH_BALANCE_AFTER_SWAP // 4
146
+ : types_1.Flag.INSERT_FROM_AMOUNT_CHECK_ETH_BALANCE_AFTER_SWAP // 7
147
+ : forcePreventInsertFromAmount && dexFuncHasRecipient
148
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 0
149
+ : types_1.Flag.INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 3
150
+ }
151
+ else {
152
+ dexFlag =
153
+ needCheckSrcTokenBalanceOf || forceBalanceOfCheck
154
+ ? forcePreventInsertFromAmount
155
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP // 8
156
+ : types_1.Flag.INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP // 11
157
+ : forcePreventInsertFromAmount
158
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 0
159
+ : types_1.Flag.INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 3
160
+ }
161
+ // Actual srcToken is eth, because we'll unwrap weth before swap.
162
+ // Need to check balance, some dexes don't have 1:1 ETH -> custom_ETH rate
163
+ if (preSwapUnwrapCalldata) {
164
+ dexFlag =
165
+ types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP;
166
+ }
167
+ return {
168
+ dexFlag,
169
+ approveFlag,
170
+ };
171
+ }
172
+ buildDexCallData(params) {
173
+ const { swapExchangeIndex, destToken, priceRouteType, swap, rootUnwrapEth, } = params;
174
+ const swapExchange = swap.swapExchanges[swapExchangeIndex];
175
+ const flag = swapExchange.build.dexFlag;
176
+ const exchangeParam = swap.swapExchanges[swapExchangeIndex].build.dexParams;
177
+ let { exchangeData, specialDexFlag, targetExchange, needWrapNative } = exchangeParam;
178
+ const routeNeedsRootUnwrapEth = this.doesRouteNeedsRootUnwrapEth(destToken, rootUnwrapEth);
179
+ const needUnwrap =
180
+ // check if current exchange is the last with needWrapNative
181
+ this.isLastExchangeWithNeedWrapNative(swap, swapExchangeIndex) ||
182
+ exchangeParam.wethAddress;
183
+ const needUnwrapAfterLastSwapInRoute = needUnwrap &&
184
+ (0, utils_1.isETHAddress)(swap.destToken) &&
185
+ this.anyDexOnSwapDoesntNeedWrapNative(swap);
186
+ const returnAmountPos = exchangeParam.returnAmountPos !== undefined &&
187
+ !routeNeedsRootUnwrapEth &&
188
+ !needUnwrapAfterLastSwapInRoute // prevent returnAmoutPos optimisation if route needs root unwrap eth
189
+ ? exchangeParam.returnAmountPos
190
+ : constants_1.DEFAULT_RETURN_AMOUNT_POS;
191
+ const applyVerticalBranching = this.doesSwapNeedToBeAsVerticalBranch(priceRouteType, swap);
192
+ const dontCheckBalanceAfterSwap = flag % 3 === 0;
193
+ const checkDestTokenBalanceAfterSwap = flag % 3 === 2;
194
+ const insertFromAmount = flag % 4 === 3 || flag % 4 === 2;
195
+ const srcTokenAddress = (0, utils_1.isETHAddress)(swap.srcToken) && needWrapNative
196
+ ? this.getWETHAddress(exchangeParam)
197
+ : swap.srcToken.toLowerCase();
198
+ const destTokenAddress = (0, utils_1.isETHAddress)(swap.destToken) && needWrapNative
199
+ ? this.getWETHAddress(exchangeParam)
200
+ : swap.destToken.toLowerCase();
201
+ exchangeData = this.addTokenAddressToCallData(exchangeData, srcTokenAddress);
202
+ if (applyVerticalBranching ||
203
+ (checkDestTokenBalanceAfterSwap && !dontCheckBalanceAfterSwap)) {
204
+ exchangeData = this.addTokenAddressToCallData(exchangeData, destTokenAddress);
205
+ }
206
+ let destTokenPos = 0;
207
+ if (checkDestTokenBalanceAfterSwap && !dontCheckBalanceAfterSwap) {
208
+ const destTokenAddrIndex = exchangeData
209
+ .replace('0x', '')
210
+ .indexOf(destTokenAddress.replace('0x', ''));
211
+ destTokenPos = (destTokenAddrIndex - 24) / 2;
212
+ }
213
+ let fromAmountPos = 0;
214
+ if (insertFromAmount) {
215
+ if (exchangeParam.insertFromAmountPos) {
216
+ fromAmountPos = exchangeParam.insertFromAmountPos;
217
+ }
218
+ else {
219
+ const fromAmount = ethers_1.ethers.utils.defaultAbiCoder.encode(['uint256'], [swapExchange.srcAmount]);
220
+ const fromAmountIndex = exchangeData
221
+ .replace('0x', '')
222
+ .indexOf(fromAmount.replace('0x', ''));
223
+ fromAmountPos =
224
+ (fromAmountIndex !== -1 ? fromAmountIndex : exchangeData.length) / 2;
225
+ }
226
+ }
227
+ return this.buildCallData(targetExchange, exchangeData, fromAmountPos, destTokenPos, specialDexFlag || types_1.SpecialDex.DEFAULT, flag, undefined, returnAmountPos);
228
+ }
229
+ wrapAsVerticalBranch(callData, percentage, swap, wrapWasAddedInSwapExchange, curExchangeParam = null, addedUnwrapForDexWithNoNeedWrapNative = false) {
230
+ let srcTokenAddress = swap.srcToken;
231
+ let doesAnyDexOnSwapNeedsWrapNative;
232
+ // if (exchangeParamIndex > -1) { // TODO-multi: what this case is about?
233
+ if (curExchangeParam) {
234
+ doesAnyDexOnSwapNeedsWrapNative =
235
+ (0, utils_1.isETHAddress)(srcTokenAddress) &&
236
+ (curExchangeParam.needWrapNative ||
237
+ (!curExchangeParam.needWrapNative &&
238
+ addedUnwrapForDexWithNoNeedWrapNative));
239
+ }
240
+ else {
241
+ doesAnyDexOnSwapNeedsWrapNative =
242
+ (0, utils_1.isETHAddress)(srcTokenAddress) && this.anyDexOnSwapNeedsWrapNative(swap);
243
+ }
244
+ if (doesAnyDexOnSwapNeedsWrapNative &&
245
+ (0, utils_1.isETHAddress)(srcTokenAddress) &&
246
+ !wrapWasAddedInSwapExchange) {
247
+ srcTokenAddress =
248
+ // exchangeParamIndex > -1 TODO-multi
249
+ curExchangeParam
250
+ ? this.getWETHAddress(curExchangeParam)
251
+ : this.dexHelper.config.data.wrappedNativeTokenAddress;
252
+ }
253
+ let srcTokenAddressLowered = srcTokenAddress.toLowerCase();
254
+ let srcTokenPos;
255
+ if (percentage === constants_1.SWAP_EXCHANGE_100_PERCENTAGE) {
256
+ srcTokenPos = hexZeroPad(hexlify(0), 8);
257
+ }
258
+ else if ((0, utils_1.isETHAddress)(srcTokenAddressLowered)) {
259
+ srcTokenPos = constants_1.ETH_SRC_TOKEN_POS_FOR_MULTISWAP_METADATA;
260
+ }
261
+ else {
262
+ const srcTokenAddrIndex = callData
263
+ .replace('0x', '')
264
+ .indexOf(srcTokenAddressLowered.replace('0x', ''));
265
+ srcTokenPos = hexZeroPad(hexlify(srcTokenAddrIndex / 2), 8);
266
+ }
267
+ return solidityPack(['bytes16', 'bytes8', 'bytes8', 'bytes'], [
268
+ hexZeroPad(hexlify(hexDataLength(callData)), 16), // calldata size
269
+ srcTokenPos, // srcTokenPos
270
+ hexZeroPad(hexlify(Math.round(percentage * 100)), 8), // percentage
271
+ callData, // swap calldata
272
+ ]);
273
+ }
274
+ packVerticalBranchingData(swapCallData) {
275
+ return solidityPack(['bytes28', 'bytes4', 'bytes32', 'bytes32', 'bytes'], [
276
+ constants_1.ZEROS_28_BYTES, // empty bytes28
277
+ constants_1.ZEROS_4_BYTES, // fallback selector
278
+ hexZeroPad(hexlify(32), 32), // calldata offset
279
+ hexZeroPad(hexlify(hexDataLength(swapCallData)), 32), // calldata length
280
+ swapCallData, // calldata
281
+ ]);
282
+ }
283
+ packVerticalBranchingCallData(verticalBranchingData, fromAmountPos, destTokenPos, flag) {
284
+ return solidityPack([
285
+ 'bytes20',
286
+ 'bytes4',
287
+ 'bytes2',
288
+ 'bytes2',
289
+ 'bytes1',
290
+ 'bytes1',
291
+ 'bytes2',
292
+ 'bytes',
293
+ ], [
294
+ constants_1.ZEROS_20_BYTES, // zero address. go to vertical branch, so no call is made
295
+ hexZeroPad(hexlify(hexDataLength(verticalBranchingData)), 4), // dex calldata length
296
+ hexZeroPad(hexlify(fromAmountPos), 2), // fromAmountPos
297
+ hexZeroPad(hexlify(destTokenPos), 2), // destTokenPos
298
+ hexZeroPad(hexlify(0), 1), // returnAmountPos
299
+ hexZeroPad(hexlify(types_1.SpecialDex.EXECUTE_VERTICAL_BRANCHING), 1), // special
300
+ hexZeroPad(hexlify(flag), 2), // flag
301
+ verticalBranchingData, // dexes calldata
302
+ ]);
303
+ }
304
+ buildVerticalBranchingCallData(swap, swapCallData, flag, isRoot = false, routes = []) {
305
+ const destTokenAddrLowered = swap.destToken.toLowerCase();
306
+ const isEthDest = (0, utils_1.isETHAddress)(destTokenAddrLowered);
307
+ let anyDexOnSwapNeedsWrapNative = false;
308
+ let anyDexOnSwapDoesntNeedWrapNative = false;
309
+ let destTokenPos;
310
+ if (isEthDest) {
311
+ if (!isRoot) {
312
+ anyDexOnSwapNeedsWrapNative = this.anyDexOnSwapNeedsWrapNative(swap);
313
+ anyDexOnSwapDoesntNeedWrapNative =
314
+ this.anyDexOnSwapDoesntNeedWrapNative(swap);
315
+ }
316
+ else {
317
+ const lastSwaps = (0, utils_2.getLastRouteSwaps)(routes);
318
+ anyDexOnSwapNeedsWrapNative = lastSwaps.some(swap => this.anyDexOnSwapNeedsWrapNative(swap));
319
+ anyDexOnSwapDoesntNeedWrapNative = lastSwaps.some(swap => this.anyDexOnSwapDoesntNeedWrapNative(swap));
320
+ }
321
+ }
322
+ // 'bytes28', 'bytes4', 'bytes32', 'bytes32', 'bytes'
323
+ const data = this.packVerticalBranchingData(swapCallData);
324
+ if (isEthDest &&
325
+ anyDexOnSwapDoesntNeedWrapNative &&
326
+ !anyDexOnSwapNeedsWrapNative) {
327
+ destTokenPos = 0;
328
+ }
329
+ else {
330
+ const destTokenAddrIndex = data
331
+ .replace('0x', '')
332
+ .indexOf((isEthDest
333
+ ? this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase()
334
+ : destTokenAddrLowered.toLowerCase()).replace('0x', ''));
335
+ destTokenPos = destTokenAddrIndex / 2 - 40;
336
+ }
337
+ const fromAmountPos = hexDataLength(data) - 64 - 28; // 64 (position), 28 (selector padding);
338
+ return this.packVerticalBranchingCallData(data, fromAmountPos, destTokenPos < 0 ? 0 : destTokenPos, flag);
339
+ }
340
+ buildVerticalBranchingCallDataNoEthDest(destToken, swapCallData, flag) {
341
+ const destTokenAddrLowered = destToken.toLowerCase();
342
+ let destTokenPos;
343
+ // 'bytes28', 'bytes4', 'bytes32', 'bytes32', 'bytes'
344
+ const data = this.packVerticalBranchingData(swapCallData);
345
+ const destTokenAddrIndex = data
346
+ .replace('0x', '')
347
+ .indexOf(destTokenAddrLowered.toLowerCase().replace('0x', ''));
348
+ destTokenPos = destTokenAddrIndex / 2 - 40;
349
+ const fromAmountPos = hexDataLength(data) - 64 - 28; // 64 (position), 28 (selector padding);
350
+ return this.packVerticalBranchingCallData(data, fromAmountPos, destTokenPos < 0 ? 0 : destTokenPos, flag);
351
+ }
352
+ buildSingleSwapExchangeCallData(swaps, routeIndex, swapIndex, swapExchangeIndex, addedWrapToSwapExchangeMap, allowToAddWrap = true, prevBranchWasWrapped = false, unwrapToSwapMap, srcToken, destToken, priceRouteType, rootUnwrapEth, rootWrapEth, maybeWethCallData) {
353
+ const isSimpleSwap = priceRouteType === 'simple';
354
+ let swapExchangeCallData = '';
355
+ const swap = swaps[swapIndex];
356
+ const hasMultipleSwapExchanges = swap.swapExchanges.length > 1;
357
+ const swapExchange = swap.swapExchanges[swapExchangeIndex];
358
+ const curExchangeParam = swapExchange.build.dexParams;
359
+ const approveFlag = swapExchange.build.approveFlag;
360
+ const dexCallData = this.buildDexCallData({
361
+ swap,
362
+ priceRouteType,
363
+ rootUnwrapEth,
364
+ swapExchangeIndex,
365
+ destToken,
366
+ // TODO-multi to be removed after refactoring
367
+ routes: [],
368
+ routeIndex,
369
+ swapIndex,
370
+ exchangeParams: [],
371
+ exchangeParamIndex: constants_1.NOT_EXISTING_EXCHANGE_PARAM_INDEX,
372
+ flag: types_1.Flag.DONT_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP,
373
+ });
374
+ if (curExchangeParam.preSwapUnwrapCalldata) {
375
+ const withdrawCallData = this.buildUnwrapEthCallData(this.getWETHAddress(curExchangeParam), curExchangeParam.preSwapUnwrapCalldata);
376
+ swapExchangeCallData = hexConcat([withdrawCallData, dexCallData]);
377
+ }
378
+ else {
379
+ swapExchangeCallData = hexConcat([dexCallData]);
380
+ }
381
+ const isLastSwap = swapIndex === swaps.length - 1;
382
+ if (curExchangeParam.transferSrcTokenBeforeSwap) {
383
+ const transferCallData = this.buildTransferCallData(this.erc20Interface.encodeFunctionData('transfer', [
384
+ curExchangeParam.transferSrcTokenBeforeSwap,
385
+ swapExchange.srcAmount,
386
+ ]), (0, utils_1.isETHAddress)(swap.srcToken)
387
+ ? this.getWETHAddress(curExchangeParam)
388
+ : swap.srcToken.toLowerCase());
389
+ swapExchangeCallData = hexConcat([
390
+ transferCallData,
391
+ swapExchangeCallData,
392
+ ]);
393
+ }
394
+ if (!(0, utils_1.isETHAddress)(swap.srcToken) &&
395
+ !curExchangeParam.transferSrcTokenBeforeSwap &&
396
+ !curExchangeParam.skipApproval &&
397
+ curExchangeParam.approveData) {
398
+ const approveCallData = this.buildApproveCallData(curExchangeParam.approveData.target, curExchangeParam.approveData.token, approveFlag, curExchangeParam.permit2Approval);
399
+ swapExchangeCallData = hexConcat([approveCallData, swapExchangeCallData]);
400
+ }
401
+ if (curExchangeParam.needWrapNative) {
402
+ if ((0, utils_1.isETHAddress)(swap.srcToken)) {
403
+ let approveWethCalldata = '0x';
404
+ if (curExchangeParam.approveData &&
405
+ !curExchangeParam.transferSrcTokenBeforeSwap &&
406
+ !curExchangeParam.skipApproval) {
407
+ approveWethCalldata = this.buildApproveCallData(curExchangeParam.approveData.target, curExchangeParam.approveData.token, approveFlag, curExchangeParam.permit2Approval);
408
+ }
409
+ const isNotFirstSwap = swapIndex !== 0;
410
+ let skipWrap = false;
411
+ if (isNotFirstSwap) {
412
+ const prevSwap = swaps[swapIndex - 1];
413
+ const anyDexOnSwapDoesntNeedWrapNative = this.anyDexOnSwapDoesntNeedWrapNative(prevSwap);
414
+ skipWrap = !anyDexOnSwapDoesntNeedWrapNative;
415
+ }
416
+ let depositCallData = '0x';
417
+ if (maybeWethCallData &&
418
+ maybeWethCallData.deposit &&
419
+ !this.doesRouteNeedsRootWrapEth(srcToken, rootWrapEth) &&
420
+ allowToAddWrap &&
421
+ !addedWrapToSwapExchangeMap[`${routeIndex}_${swapIndex}_${swapExchangeIndex}`] &&
422
+ !skipWrap) {
423
+ depositCallData = this.buildWrapEthCallData(this.getWETHAddress(curExchangeParam), maybeWethCallData.deposit.calldata, types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP);
424
+ addedWrapToSwapExchangeMap[`${routeIndex}_${swapIndex}_${swapExchangeIndex}`] = true;
425
+ }
426
+ swapExchangeCallData = hexConcat([
427
+ approveWethCalldata,
428
+ depositCallData,
429
+ swapExchangeCallData,
430
+ ]);
431
+ }
432
+ const needUnwrap = (priceRouteType === 'multi' || priceRouteType === 'mega') &&
433
+ hasMultipleSwapExchanges;
434
+ // unwrap after last swap
435
+ if (maybeWethCallData &&
436
+ maybeWethCallData.withdraw &&
437
+ ((!needUnwrap && (0, utils_1.isETHAddress)(swap.destToken)) ||
438
+ (needUnwrap &&
439
+ (0, utils_1.isETHAddress)(swap.destToken) &&
440
+ this.anyDexOnSwapDoesntNeedWrapNative(swap)))) {
441
+ let withdrawCallData = '0x';
442
+ const customWethAddress = curExchangeParam.wethAddress;
443
+ const nextSwap = swaps[swapIndex + 1];
444
+ const needUnwrapAll = isSimpleSwap ||
445
+ (isLastSwap
446
+ ? !this.doesRouteNeedsRootUnwrapEth(destToken, rootUnwrapEth)
447
+ : this.everyDexOnSwapNeedWrapNative(nextSwap) ||
448
+ this.everyDexOnSwapDoesntNeedWrapNative(nextSwap));
449
+ // check if current exchange is the last with needWrapNative
450
+ const needUnwrap = needUnwrapAll &&
451
+ this.isLastExchangeWithNeedWrapNative(swap, swapExchangeIndex);
452
+ if (customWethAddress || needUnwrap) {
453
+ unwrapToSwapMap[swapIndex] = true;
454
+ withdrawCallData = this.buildUnwrapEthCallData(this.getWETHAddress(curExchangeParam), maybeWethCallData.withdraw.calldata);
455
+ }
456
+ swapExchangeCallData = hexConcat([
457
+ swapExchangeCallData,
458
+ withdrawCallData,
459
+ ]);
460
+ if (isSimpleSwap && (needUnwrap || customWethAddress)) {
461
+ const finalSpecialFlagCalldata = this.buildFinalSpecialFlagCalldata();
462
+ swapExchangeCallData = hexConcat([
463
+ swapExchangeCallData,
464
+ finalSpecialFlagCalldata,
465
+ ]);
466
+ }
467
+ }
468
+ }
469
+ let addedUnwrapForDexWithNoNeedWrapNative = false;
470
+ if ((0, utils_1.isETHAddress)(swap.srcToken) &&
471
+ maybeWethCallData &&
472
+ maybeWethCallData.withdraw &&
473
+ !curExchangeParam.needWrapNative &&
474
+ !unwrapToSwapMap[swapIndex - 1]) {
475
+ const prevSwap = swaps[swapIndex - 1];
476
+ let eachDexOnPrevSwapReturnsWeth = false;
477
+ if (prevSwap && !prevBranchWasWrapped) {
478
+ eachDexOnPrevSwapReturnsWeth =
479
+ this.eachDexOnSwapNeedsWrapNative(prevSwap);
480
+ }
481
+ if (prevBranchWasWrapped || eachDexOnPrevSwapReturnsWeth) {
482
+ const withdrawCallData = this.buildUnwrapEthCallData(this.getWETHAddress(curExchangeParam), maybeWethCallData.withdraw.calldata);
483
+ swapExchangeCallData = hexConcat([
484
+ withdrawCallData,
485
+ swapExchangeCallData,
486
+ ]);
487
+ addedUnwrapForDexWithNoNeedWrapNative = true;
488
+ }
489
+ }
490
+ if (isLastSwap &&
491
+ !curExchangeParam.dexFuncHasRecipient &&
492
+ !(0, utils_1.isETHAddress)(swap.destToken) &&
493
+ destToken === swap.destToken) {
494
+ const transferCallData = this.buildTransferCallData(this.erc20Interface.encodeFunctionData('transfer', [
495
+ this.dexHelper.config.data.augustusV6Address,
496
+ swapExchange.destAmount,
497
+ ]), swap.destToken);
498
+ swapExchangeCallData = hexConcat([
499
+ swapExchangeCallData,
500
+ transferCallData,
501
+ ]);
502
+ }
503
+ if (!curExchangeParam.dexFuncHasRecipient &&
504
+ (0, utils_1.isETHAddress)(swap.destToken) &&
505
+ isLastSwap &&
506
+ // don't need to send eth without unwrapping, handling unwrap and sendEth in the end of root branch
507
+ !this.doesRouteNeedsRootUnwrapEth(destToken, rootUnwrapEth)) {
508
+ const finalSpecialFlagCalldata = this.buildFinalSpecialFlagCalldata();
509
+ swapExchangeCallData = hexConcat([
510
+ swapExchangeCallData,
511
+ finalSpecialFlagCalldata,
512
+ ]);
513
+ }
514
+ // if swap has multiple exchanges, then each exchange is executed as part of vertical branching
515
+ if (hasMultipleSwapExchanges) {
516
+ return this.wrapAsVerticalBranch(swapExchangeCallData, swapExchange.percent, swap, addedWrapToSwapExchangeMap[`${routeIndex}_${swapIndex}_${swapExchangeIndex}`], curExchangeParam, addedUnwrapForDexWithNoNeedWrapNative);
517
+ }
518
+ return swapExchangeCallData;
519
+ }
520
+ appendWrapEthCallData(calldata, maybeWethCallData, checkWethBalanceAfter = false) {
521
+ if (maybeWethCallData?.deposit) {
522
+ const callData = checkWethBalanceAfter
523
+ ? this.addTokenAddressToCallData(maybeWethCallData.deposit.calldata, this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase())
524
+ : maybeWethCallData.deposit.calldata;
525
+ const depositCallData = this.buildWrapEthCallData(this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase(), callData, checkWethBalanceAfter
526
+ ? types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP // 5
527
+ : types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP, // 9
528
+ checkWethBalanceAfter ? 4 : 0);
529
+ return hexConcat([calldata, depositCallData]);
530
+ }
531
+ return calldata;
532
+ }
533
+ eachDexOnSwapNeedsWrapNative(swap) {
534
+ return swap.swapExchanges.every(se => {
535
+ return (se.build.dexParams.needWrapNative && !se.build.dexParams.wethAddress);
536
+ });
537
+ }
538
+ anyDexOnSwapNeedsWrapNative(swap) {
539
+ return swap.swapExchanges
540
+ .map(s => s.build.dexParams.needWrapNative && !s.build.dexParams.wethAddress)
541
+ .includes(true);
542
+ }
543
+ isLastExchangeWithNeedWrapNative(swap, swapExchangeIndex) {
544
+ return (swap.swapExchanges
545
+ .map(t => t.build.dexParams.needWrapNative)
546
+ .reduceRight((acc, needWrapNative, index) => needWrapNative === true && acc === -1 ? index : acc, -1) === swapExchangeIndex);
547
+ }
548
+ anyDexOnSwapDoesntNeedWrapNative(swap) {
549
+ return swap.swapExchanges
550
+ .map(s => !s.build.dexParams.needWrapNative)
551
+ .includes(true);
552
+ }
553
+ everyDexOnSwapNeedWrapNative(swap) {
554
+ if (!swap) {
555
+ return false;
556
+ }
557
+ return swap.swapExchanges
558
+ .map(s => s.build.dexParams.needWrapNative)
559
+ .every(t => t === true);
560
+ }
561
+ everyDexOnSwapDoesntNeedWrapNative(swap) {
562
+ if (!swap) {
563
+ return false;
564
+ }
565
+ return swap.swapExchanges
566
+ .map(s => s.build.dexParams.needWrapNative)
567
+ .every(t => t === false);
568
+ }
569
+ doesSwapNeedToBeAsVerticalBranch(routeType, swap) {
570
+ return ((routeType === 'multi' || routeType === 'mega') &&
571
+ swap.swapExchanges.length > 1);
572
+ }
573
+ buildVerticalBranchingFlag(swap, destToken, isLastSwap) {
574
+ let flag = types_1.Flag.INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP; // 11
575
+ if (isLastSwap) {
576
+ const isEthDest = (0, utils_1.isETHAddress)(destToken);
577
+ const lastSwapExchanges = swap.swapExchanges;
578
+ const anyDexLastSwapNeedUnwrap = lastSwapExchanges
579
+ .map(se => se.build.dexParams.needWrapNative &&
580
+ !se.build.dexParams.wethAddress)
581
+ .includes(true);
582
+ const noNeedUnwrap = isEthDest && !anyDexLastSwapNeedUnwrap;
583
+ if (noNeedUnwrap || !isEthDest) {
584
+ flag = types_1.Flag.INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP; // 3
585
+ }
586
+ }
587
+ else {
588
+ const isEthDest = (0, utils_1.isETHAddress)(swap.destToken);
589
+ if (isEthDest) {
590
+ if (this.anyDexOnSwapDoesntNeedWrapNative(swap)) {
591
+ flag = types_1.Flag.INSERT_FROM_AMOUNT_CHECK_ETH_BALANCE_AFTER_SWAP; // 7
592
+ }
593
+ }
594
+ }
595
+ return flag;
596
+ }
597
+ buildSingleSwapCallData(params) {
598
+ const { routeIndex, swapIndex, maybeWethCallData, wrapToSwapMap, unwrapToSwapMap, wrapToSwapExchangeMap, swap, srcToken, destToken, priceRouteType, rootUnwrapEth, rootWrapEth, swaps, isLastSwapOnTheRoute, } = params;
599
+ const { swapExchanges } = swap;
600
+ const isLastSwap = swaps.length - 1 === swapIndex;
601
+ const applyVerticalBranching = this.doesSwapNeedToBeAsVerticalBranch(priceRouteType, swap);
602
+ const anyDexOnSwapDoesntNeedWrapNative = this.anyDexOnSwapDoesntNeedWrapNative(swap);
603
+ const needToAppendWrapCallData = (0, utils_1.isETHAddress)(swap.destToken) &&
604
+ anyDexOnSwapDoesntNeedWrapNative &&
605
+ !isLastSwap &&
606
+ maybeWethCallData?.deposit;
607
+ let swapCallData = swapExchanges.reduce((acc, _swapExchange, swapExchangeIndex) => {
608
+ return hexConcat([
609
+ acc,
610
+ this.buildSingleSwapExchangeCallData(swaps, routeIndex, swapIndex, swapExchangeIndex, wrapToSwapExchangeMap, !wrapToSwapMap[swapIndex - 1], wrapToSwapMap[swapIndex - 1], unwrapToSwapMap, srcToken, destToken, priceRouteType, rootUnwrapEth, rootWrapEth, maybeWethCallData),
611
+ ]);
612
+ }, '0x');
613
+ if (needToAppendWrapCallData) {
614
+ wrapToSwapMap[swapIndex] = true;
615
+ }
616
+ if (priceRouteType === 'simple') {
617
+ return needToAppendWrapCallData
618
+ ? this.appendWrapEthCallData(swapCallData, maybeWethCallData)
619
+ : swapCallData;
620
+ }
621
+ if (applyVerticalBranching) {
622
+ const vertBranchingCallData = this.buildVerticalBranchingCallData(swap, swapCallData, this.buildVerticalBranchingFlag(swap, destToken, isLastSwapOnTheRoute ?? isLastSwap));
623
+ return needToAppendWrapCallData
624
+ ? this.appendWrapEthCallData(vertBranchingCallData, maybeWethCallData, true)
625
+ : vertBranchingCallData;
626
+ }
627
+ return needToAppendWrapCallData
628
+ ? this.appendWrapEthCallData(swapCallData, maybeWethCallData)
629
+ : swapCallData;
630
+ }
631
+ buildRouteCallData(route, routeIndex, flags, sender, srcToken, destToken, priceRouteType, rootUnwrapEth, rootWrapEth, maybeWethCallData) {
632
+ const buildSingleSwap = (swaps, swapIndex, swap, wrapToSwapExchangeMap, wrapToSwapMap, unwrapToSwapMap, isLastSwapOnTheRoute) => this.buildSingleSwapCallData({
633
+ swaps,
634
+ priceRouteType,
635
+ rootUnwrapEth,
636
+ rootWrapEth,
637
+ routeIndex,
638
+ swapIndex,
639
+ flags,
640
+ sender,
641
+ wrapToSwapExchangeMap,
642
+ wrapToSwapMap,
643
+ unwrapToSwapMap,
644
+ maybeWethCallData,
645
+ swap,
646
+ index: 0,
647
+ srcToken,
648
+ destToken,
649
+ isLastSwapOnTheRoute,
650
+ // TODO-multi to be removed after refactoring
651
+ routes: [],
652
+ exchangeParams: [],
653
+ });
654
+ const wrapToSwapExchangeMap = {}; // routeIndex_swapIndex_swapExchangeIndex
655
+ const wrapToSwapMap = {}; // swapIndex
656
+ const unwrapToSwapMap = {}; // swapIndex
657
+ let callData = '';
658
+ if (route.type === 'single-route') {
659
+ callData = route.swaps.reduce((swapAcc, swap, swapIndex) => hexConcat([
660
+ swapAcc,
661
+ buildSingleSwap(route.swaps, swapIndex, swap, wrapToSwapExchangeMap, wrapToSwapMap, unwrapToSwapMap),
662
+ ]), '0x');
663
+ }
664
+ else {
665
+ route.swaps.forEach((multiRouteSwaps, routeSwapIndex) => {
666
+ if ((0, utils_2.isMultiRouteSwap)(multiRouteSwaps)) {
667
+ let multiRoutesCalldata = '0x'; // TODO-multi: do we need this prefix?
668
+ multiRouteSwaps.forEach((swaps, multiRouteIndex) => {
669
+ const mrWrapToSwapExchangeMap = {}; // routeIndex_swapIndex_swapExchangeIndex
670
+ const mrWrapToSwapMap = {}; // swapIndex
671
+ const mrUnwrapToSwapMap = {}; // swapIndex
672
+ const multiRouteSwapsCalldata = swaps.reduce((swapAcc, swap, swapIndex) => hexConcat([
673
+ swapAcc,
674
+ buildSingleSwap(swaps, swapIndex, swap, mrWrapToSwapExchangeMap, mrWrapToSwapMap, mrUnwrapToSwapMap),
675
+ ]), '0x');
676
+ const multiRouteCalldata = this.wrapAsVerticalBranch(multiRouteSwapsCalldata, route.multiRoutePercents[multiRouteIndex], swaps[0], Object.values(mrWrapToSwapMap).includes(true) ||
677
+ Object.values(mrWrapToSwapExchangeMap).includes(true), null);
678
+ multiRoutesCalldata = hexConcat([
679
+ multiRoutesCalldata,
680
+ multiRouteCalldata,
681
+ ]);
682
+ });
683
+ // should be the same for all routes in multi-route
684
+ const destToken = multiRouteSwaps[0].at(-1).destToken;
685
+ // TODO-multi: as ETH is not used as intermediate connector since RouteAdvisor release, trying to simplify here
686
+ const routeCalldata = this.buildVerticalBranchingCallDataNoEthDest(destToken, multiRoutesCalldata, types_1.Flag.INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP);
687
+ callData = hexConcat([callData, routeCalldata]);
688
+ }
689
+ else {
690
+ callData += multiRouteSwaps.reduce((swapAcc, swap, swapIndex) => hexConcat([
691
+ swapAcc,
692
+ buildSingleSwap(multiRouteSwaps, swapIndex, swap, wrapToSwapExchangeMap, wrapToSwapMap, unwrapToSwapMap, routeSwapIndex === route.swaps.length - 1 &&
693
+ swapIndex === multiRouteSwaps.length - 1),
694
+ ]), '0x');
695
+ }
696
+ });
697
+ }
698
+ if (priceRouteType === 'mega') {
699
+ let swap;
700
+ if (route.type === 'single-route') {
701
+ swap = route.swaps[0];
702
+ }
703
+ else {
704
+ // TODO-multi: as only swap.srcToken address is used (for srcToken != ETH), which is the same for multi-routes
705
+ // safe to use first route
706
+ const firstMultiRoute = route.swaps[0];
707
+ if ((0, utils_2.isMultiRouteSwap)(firstMultiRoute)) {
708
+ swap = firstMultiRoute[0][0];
709
+ }
710
+ else {
711
+ swap = firstMultiRoute[0];
712
+ }
713
+ }
714
+ return this.wrapAsVerticalBranch(callData, route.percent, swap, Object.values(wrapToSwapMap).includes(true) ||
715
+ Object.values(wrapToSwapExchangeMap).includes(true), null);
716
+ }
717
+ return callData;
718
+ }
719
+ doesRouteNeedsRootWrapEth(srcToken, rootWrapEth) {
720
+ if (!(0, utils_1.isETHAddress)(srcToken)) {
721
+ return false;
722
+ }
723
+ return rootWrapEth;
724
+ }
725
+ // (check disclaimer above)
726
+ // this method is still used to prevent changes on the legacy encoding with wrap/unwrap
727
+ // imho, this method has incorrect naming and overall misleading logic
728
+ doesRouteNeedsRootUnwrapEth(destToken, rootUnwrapEth) {
729
+ if (!(0, utils_1.isETHAddress)(destToken)) {
730
+ return false;
731
+ }
732
+ return rootUnwrapEth;
733
+ }
734
+ getAddress() {
735
+ return this.dexHelper.config.data.executorsAddresses[types_1.Executors.TWO];
736
+ }
737
+ buildByteCode(priceRoute, routes, exchangeParams, sender, maybeWethCallData) {
738
+ const needWrapEth = maybeWethCallData?.deposit && (0, utils_1.isETHAddress)(priceRoute.srcToken);
739
+ const needUnwrapEth = maybeWethCallData?.withdraw && (0, utils_1.isETHAddress)(priceRoute.destToken);
740
+ const needSendNativeEth = (0, utils_1.isETHAddress)(priceRoute.destToken);
741
+ const rootWrapEth = !(0, utils_1.isETHAddress)(priceRoute.srcToken)
742
+ ? false
743
+ : (0, utils_2.getFirstRouteSwaps)(routes).every(swap => this.eachDexOnSwapNeedsWrapNative(swap));
744
+ const rootUnwrapEth = !(0, utils_1.isETHAddress)(priceRoute.destToken)
745
+ ? false
746
+ : (0, utils_2.getLastRouteSwaps)(routes).some(swap => this.anyDexOnSwapNeedsWrapNative(swap));
747
+ const priceRouteType = (0, utils_2.getPriceRouteType)(priceRoute);
748
+ const flags = this.buildFlags(priceRoute.bestRoute, routes, exchangeParams, priceRoute.srcToken, priceRouteType, maybeWethCallData);
749
+ let swapsCalldata = routes.reduce((routeAcc, route, routeIndex) => hexConcat([
750
+ routeAcc,
751
+ this.buildRouteCallData(route, routeIndex, flags, sender, priceRoute.srcToken, priceRoute.destToken, priceRouteType, rootUnwrapEth, rootWrapEth, maybeWethCallData),
752
+ ]), '0x');
753
+ // hack to do wrap/unwrap before the priceRoute execution
754
+ // first make wrap/unwrap, then execute mega swap as vertical branch
755
+ if (priceRouteType === 'mega' && (needWrapEth || needUnwrapEth)) {
756
+ // TODO-multi: would it work? test this case
757
+ const lastSwaps = (0, utils_2.getLastRouteSwaps)(routes);
758
+ const lastSwap = lastSwaps[lastSwaps.length - 1];
759
+ swapsCalldata = this.buildVerticalBranchingCallData(lastSwap, swapsCalldata, needWrapEth
760
+ ? types_1.Flag.DONT_INSERT_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 0
761
+ : types_1.Flag.DONT_INSERT_FROM_AMOUNT_CHECK_SRC_TOKEN_BALANCE_AFTER_SWAP, // 8
762
+ true, // isRoot branch
763
+ routes);
764
+ }
765
+ // ETH wrap
766
+ if (needWrapEth && rootWrapEth) {
767
+ let depositCallData = this.buildWrapEthCallData(this.dexHelper.config.data.wrappedNativeTokenAddress, maybeWethCallData.deposit.calldata, types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP);
768
+ if (priceRouteType === 'simple') {
769
+ const swap = priceRoute.bestRoute[0].swaps[0];
770
+ const percent = exchangeParams.every(ep => ep.needWrapNative)
771
+ ? 100
772
+ : swap.swapExchanges
773
+ .filter((_se, index) => {
774
+ return exchangeParams[index].needWrapNative;
775
+ })
776
+ .reduce((acc, se) => {
777
+ acc += se.percent;
778
+ return acc;
779
+ }, 0);
780
+ depositCallData = solidityPack(['bytes16', 'bytes16', 'bytes'], [
781
+ hexZeroPad(hexlify(hexDataLength(depositCallData)), 16),
782
+ hexZeroPad(hexlify(100 * percent), 16),
783
+ depositCallData,
784
+ ]);
785
+ }
786
+ swapsCalldata = hexConcat([depositCallData, swapsCalldata]);
787
+ }
788
+ // ETH unwrap, only for multiswaps and mega swaps
789
+ if (needUnwrapEth &&
790
+ rootUnwrapEth &&
791
+ (priceRouteType === 'multi' || priceRouteType === 'mega')) {
792
+ const withdrawCallData = this.buildUnwrapEthCallData(this.dexHelper.config.data.wrappedNativeTokenAddress, maybeWethCallData.withdraw.calldata);
793
+ swapsCalldata = hexConcat([swapsCalldata, withdrawCallData]);
794
+ }
795
+ // Special flag (send native) calldata, only for multiswaps and mega swaps
796
+ if (needSendNativeEth &&
797
+ rootUnwrapEth &&
798
+ (priceRouteType === 'multi' || priceRouteType === 'mega')) {
799
+ const finalSpecialFlagCalldata = this.buildFinalSpecialFlagCalldata();
800
+ swapsCalldata = hexConcat([swapsCalldata, finalSpecialFlagCalldata]);
801
+ }
802
+ if (((needWrapEth || needUnwrapEth) && priceRouteType === 'mega') ||
803
+ priceRouteType === 'multi') {
804
+ // TODO-multi: would it work? test this case
805
+ const firstSwaps = (0, utils_2.getFirstRouteSwaps)(routes);
806
+ swapsCalldata = this.wrapAsVerticalBranch(swapsCalldata, constants_1.SWAP_EXCHANGE_100_PERCENTAGE, firstSwaps[0], false, null);
807
+ }
808
+ return solidityPack(['bytes32', 'bytes', 'bytes'], [
809
+ hexZeroPad(hexlify(32), 32), // calldata offset
810
+ hexZeroPad(hexlify(hexDataLength(swapsCalldata) + constants_1.BYTES_64_LENGTH), // calldata length (64 bytes = bytes12(0) + msg.sender)
811
+ 32),
812
+ swapsCalldata, // calldata
813
+ ]);
814
+ }
815
+ buildFlags(routes, buildRoutes, exchangeParams, srcToken, priceRouteType, maybeWethCallData) {
816
+ const buildFlagsMethod = priceRouteType === 'multi' || priceRouteType === 'mega'
817
+ ? this.buildMultiMegaSwapFlags.bind(this)
818
+ : this.buildSimpleSwapFlags.bind(this);
819
+ let flags = {
820
+ dexes: [],
821
+ approves: [],
822
+ };
823
+ const buildAndAssignFlags = (swaps, swap, swapIndex) => {
824
+ swap.swapExchanges.map((swapExchange, swapExchangeIndex) => {
825
+ const { dexFlag, approveFlag } = buildFlagsMethod({
826
+ priceRouteType,
827
+ swaps,
828
+ routes,
829
+ exchangeParams,
830
+ routeIndex: 0, // not used on Ex02MultiRoute
831
+ swapIndex,
832
+ swapExchangeIndex,
833
+ exchangeParamIndex: 0, // TODO-multi: to be removed after refactoring
834
+ maybeWethCallData,
835
+ swap,
836
+ swapExchange,
837
+ });
838
+ swapExchange.build.dexFlag = dexFlag;
839
+ swapExchange.build.approveFlag = approveFlag;
840
+ flags.dexes.push(dexFlag);
841
+ flags.approves.push(approveFlag);
842
+ });
843
+ };
844
+ buildRoutes.forEach(route => {
845
+ if (route.type === 'single-route') {
846
+ route.swaps.map((swap, swapIndex) => {
847
+ buildAndAssignFlags(route.swaps, swap, swapIndex);
848
+ });
849
+ }
850
+ else {
851
+ route.swaps.forEach(routeSwaps => {
852
+ const isMultiRoute = (0, utils_2.isMultiRouteSwap)(routeSwaps);
853
+ if (!isMultiRoute) {
854
+ // TODO-multi: should swapIndex be the index of the current multi-route, or the total route
855
+ routeSwaps.forEach((swap, swapIndex) => {
856
+ buildAndAssignFlags(routeSwaps, swap, swapIndex);
857
+ });
858
+ }
859
+ else {
860
+ routeSwaps.forEach(swaps => {
861
+ swaps.forEach((swap, swapIndex) => {
862
+ buildAndAssignFlags(swaps, swap, swapIndex);
863
+ });
864
+ });
865
+ }
866
+ });
867
+ }
868
+ });
869
+ return {
870
+ ...flags,
871
+ wrap: (0, utils_1.isETHAddress)(srcToken) && maybeWethCallData?.deposit
872
+ ? types_1.Flag.SEND_ETH_EQUAL_TO_FROM_AMOUNT_DONT_CHECK_BALANCE_AFTER_SWAP // 9
873
+ : types_1.Flag.INSERT_FROM_AMOUNT_CHECK_ETH_BALANCE_AFTER_SWAP, // 7
874
+ };
875
+ }
876
+ }
877
+ exports.Executor02BytecodeBuilderMultiRoute = Executor02BytecodeBuilderMultiRoute;
878
+ //# sourceMappingURL=Executor02BytecodeBuilderMultiRoute.js.map