@paraswap/dex-lib 3.8.1 → 3.8.3-integral-dex

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 (262) hide show
  1. package/.vscode/launch.json +9 -49
  2. package/.vscode/settings.json +2 -1
  3. package/build/abi/Uncompressor.json +250 -0
  4. package/build/abi/integral/factory.json +333 -0
  5. package/build/abi/integral/oracle.json +501 -0
  6. package/build/abi/integral/pool.json +1041 -0
  7. package/build/abi/{wombat/pool.json → integral/relayer.json} +720 -473
  8. package/build/abi/oswap/oswap.abi.json +452 -0
  9. package/build/config.js +1 -1
  10. package/build/dex/aave-v1/aave-v1.d.ts +1 -2
  11. package/build/dex/aave-v1/aave-v1.js +0 -23
  12. package/build/dex/aave-v1/aave-v1.js.map +1 -1
  13. package/build/dex/compound.js +1 -1
  14. package/build/dex/compound.js.map +1 -1
  15. package/build/dex/curve-v1-factory/config.js +10 -47
  16. package/build/dex/curve-v1-factory/config.js.map +1 -1
  17. package/build/dex/curve-v1-factory/curve-v1-factory.d.ts +2 -2
  18. package/build/dex/curve-v1-factory/curve-v1-factory.js +36 -96
  19. package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
  20. package/build/dex/curve-v1-factory/price-handlers/functions/constants.js.map +1 -1
  21. package/build/dex/curve-v1-factory/price-handlers/functions/get_dx.js +1 -13
  22. package/build/dex/curve-v1-factory/price-handlers/functions/get_dx.js.map +1 -1
  23. package/build/dex/curve-v1-factory/state-polling-pools/custom-pool-polling.d.ts +2 -2
  24. package/build/dex/curve-v1-factory/state-polling-pools/custom-pool-polling.js +1 -1
  25. package/build/dex/curve-v1-factory/state-polling-pools/custom-pool-polling.js.map +1 -1
  26. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js +1 -1
  27. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
  28. package/build/dex/curve-v1-factory/state-polling-pools/pool-polling-base.d.ts +3 -4
  29. package/build/dex/curve-v1-factory/state-polling-pools/pool-polling-base.js +9 -24
  30. package/build/dex/curve-v1-factory/state-polling-pools/pool-polling-base.js.map +1 -1
  31. package/build/dex/curve-v1-factory/types.d.ts +4 -20
  32. package/build/dex/curve-v1-factory/types.js +3 -11
  33. package/build/dex/curve-v1-factory/types.js.map +1 -1
  34. package/build/dex/curve-v1-stable-ng/config.js +0 -18
  35. package/build/dex/curve-v1-stable-ng/config.js.map +1 -1
  36. package/build/dex/etherfi/etherfi.d.ts +26 -0
  37. package/build/dex/etherfi/etherfi.js +96 -0
  38. package/build/dex/etherfi/etherfi.js.map +1 -0
  39. package/build/dex/index.js +21 -3
  40. package/build/dex/index.js.map +1 -1
  41. package/build/dex/integral/config.d.ts +4 -0
  42. package/build/dex/integral/config.js +20 -0
  43. package/build/dex/integral/config.js.map +1 -0
  44. package/build/dex/integral/context.d.ts +40 -0
  45. package/build/dex/integral/context.js +158 -0
  46. package/build/dex/integral/context.js.map +1 -0
  47. package/build/dex/integral/helpers.d.ts +17 -0
  48. package/build/dex/integral/helpers.js +157 -0
  49. package/build/dex/integral/helpers.js.map +1 -0
  50. package/build/dex/integral/integral-factory.d.ts +21 -0
  51. package/build/dex/integral/integral-factory.js +92 -0
  52. package/build/dex/integral/integral-factory.js.map +1 -0
  53. package/build/dex/integral/integral-pool.d.ts +46 -0
  54. package/build/dex/integral/integral-pool.js +143 -0
  55. package/build/dex/integral/integral-pool.js.map +1 -0
  56. package/build/dex/integral/integral-pricing.d.ts +18 -0
  57. package/build/dex/integral/integral-pricing.js +114 -0
  58. package/build/dex/integral/integral-pricing.js.map +1 -0
  59. package/build/dex/integral/integral-relayer.d.ts +39 -0
  60. package/build/dex/integral/integral-relayer.js +189 -0
  61. package/build/dex/integral/integral-relayer.js.map +1 -0
  62. package/build/dex/integral/integral-token.d.ts +24 -0
  63. package/build/dex/integral/integral-token.js +56 -0
  64. package/build/dex/integral/integral-token.js.map +1 -0
  65. package/build/dex/integral/integral.d.ts +41 -0
  66. package/build/dex/integral/integral.js +377 -0
  67. package/build/dex/integral/integral.js.map +1 -0
  68. package/build/dex/integral/types.d.ts +84 -0
  69. package/build/dex/integral/types.js +9 -0
  70. package/build/dex/integral/types.js.map +1 -0
  71. package/build/dex/integral/utils-e2e.d.ts +9 -0
  72. package/build/dex/integral/utils-e2e.js +131 -0
  73. package/build/dex/integral/utils-e2e.js.map +1 -0
  74. package/build/dex/integral/utils.d.ts +17 -0
  75. package/build/dex/integral/utils.js +94 -0
  76. package/build/dex/integral/utils.js.map +1 -0
  77. package/build/dex/oswap/config.d.ts +5 -0
  78. package/build/dex/oswap/config.js +31 -0
  79. package/build/dex/oswap/config.js.map +1 -0
  80. package/build/dex/oswap/oswap-pool.d.ts +51 -0
  81. package/build/dex/oswap/oswap-pool.js +150 -0
  82. package/build/dex/oswap/oswap-pool.js.map +1 -0
  83. package/build/dex/oswap/oswap.d.ts +46 -0
  84. package/build/dex/oswap/oswap.js +266 -0
  85. package/build/dex/oswap/oswap.js.map +1 -0
  86. package/build/dex/oswap/types.d.ts +20 -0
  87. package/build/dex/oswap/types.js +3 -0
  88. package/build/dex/oswap/types.js.map +1 -0
  89. package/build/dex/platypus/platypus.d.ts +1 -2
  90. package/build/dex/platypus/platypus.js +0 -45
  91. package/build/dex/platypus/platypus.js.map +1 -1
  92. package/build/dex/sdai/config.d.ts +11 -0
  93. package/build/dex/sdai/config.js +21 -0
  94. package/build/dex/sdai/config.js.map +1 -0
  95. package/build/dex/sdai/constants.d.ts +2 -0
  96. package/build/dex/sdai/constants.js +6 -0
  97. package/build/dex/sdai/constants.js.map +1 -0
  98. package/build/dex/sdai/scripts/validate-state.js +102 -0
  99. package/build/dex/sdai/scripts/validate-state.js.map +1 -0
  100. package/build/dex/sdai/sdai-pool.d.ts +16 -0
  101. package/build/dex/sdai/sdai-pool.js +85 -0
  102. package/build/dex/sdai/sdai-pool.js.map +1 -0
  103. package/build/dex/sdai/sdai.d.ts +51 -0
  104. package/build/dex/sdai/sdai.js +172 -0
  105. package/build/dex/sdai/sdai.js.map +1 -0
  106. package/build/dex/sdai/types.d.ts +21 -0
  107. package/build/dex/sdai/types.js +11 -0
  108. package/build/dex/sdai/types.js.map +1 -0
  109. package/build/dex/sdai/utils.d.ts +4 -0
  110. package/build/dex/sdai/utils.js +39 -0
  111. package/build/dex/sdai/utils.js.map +1 -0
  112. package/build/dex/stable-pool.js +8 -1
  113. package/build/dex/stable-pool.js.map +1 -1
  114. package/build/dex/swaap-v1/swaap-v1.d.ts +1 -2
  115. package/build/dex/swaap-v1/swaap-v1.js +0 -14
  116. package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
  117. package/build/dex/uniswap-v3/contract-math/Oracle.js +4 -4
  118. package/build/dex/uniswap-v3/contract-math/Oracle.js.map +1 -1
  119. package/build/executor/compressor/Compressor.d.ts +23 -0
  120. package/build/executor/compressor/Compressor.js +144 -0
  121. package/build/executor/compressor/Compressor.js.map +1 -0
  122. package/build/executor/compressor/compress.d.ts +17 -0
  123. package/build/executor/compressor/compress.js +187 -0
  124. package/build/executor/compressor/compress.js.map +1 -0
  125. package/build/executor/compressor/compress_functions/addressSubstitution.d.ts +6 -0
  126. package/build/executor/compressor/compress_functions/addressSubstitution.js +29 -0
  127. package/build/executor/compressor/compress_functions/addressSubstitution.js.map +1 -0
  128. package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.d.ts +10 -0
  129. package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.js +40 -0
  130. package/build/executor/compressor/compress_functions/addressSubstitutionFromObject.js.map +1 -0
  131. package/build/executor/compressor/compress_functions/byteSubstitution.d.ts +11 -0
  132. package/build/executor/compressor/compress_functions/byteSubstitution.js +64 -0
  133. package/build/executor/compressor/compress_functions/byteSubstitution.js.map +1 -0
  134. package/build/executor/compressor/compress_functions/ffSubstitution.d.ts +7 -0
  135. package/build/executor/compressor/compress_functions/ffSubstitution.js +54 -0
  136. package/build/executor/compressor/compress_functions/ffSubstitution.js.map +1 -0
  137. package/build/executor/compressor/compress_functions/findLongestAndSubstitute.d.ts +8 -0
  138. package/build/executor/compressor/compress_functions/findLongestAndSubstitute.js +67 -0
  139. package/build/executor/compressor/compress_functions/findLongestAndSubstitute.js.map +1 -0
  140. package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.d.ts +8 -0
  141. package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.js +61 -0
  142. package/build/executor/compressor/compress_functions/findLongestAndSubstitute_old.js.map +1 -0
  143. package/build/executor/compressor/compress_functions/reverseAddressSubstitution.d.ts +6 -0
  144. package/build/executor/compressor/compress_functions/reverseAddressSubstitution.js +37 -0
  145. package/build/executor/compressor/compress_functions/reverseAddressSubstitution.js.map +1 -0
  146. package/build/executor/compressor/compress_functions/searchUnusedBytes.d.ts +9 -0
  147. package/build/executor/compressor/compress_functions/searchUnusedBytes.js +33 -0
  148. package/build/executor/compressor/compress_functions/searchUnusedBytes.js.map +1 -0
  149. package/build/executor/compressor/fetchSaved.js +17 -0
  150. package/build/executor/compressor/fetchSaved.js.map +1 -0
  151. package/build/executor/compressor/utils/computeCostL2.d.ts +2 -0
  152. package/build/executor/compressor/utils/computeCostL2.js +14 -0
  153. package/build/executor/compressor/utils/computeCostL2.js.map +1 -0
  154. package/build/executor/compressor/utils/findLongestDuplicatedString.d.ts +2 -0
  155. package/build/executor/compressor/utils/findLongestDuplicatedString.js +30 -0
  156. package/build/executor/compressor/utils/findLongestDuplicatedString.js.map +1 -0
  157. package/build/executor/compressor/utils/getAllIndexes.d.ts +2 -0
  158. package/build/executor/compressor/utils/getAllIndexes.js +12 -0
  159. package/build/executor/compressor/utils/getAllIndexes.js.map +1 -0
  160. package/build/executor/compressor/utils/getByteForAddress.d.ts +2 -0
  161. package/build/executor/compressor/utils/getByteForAddress.js +14 -0
  162. package/build/executor/compressor/utils/getByteForAddress.js.map +1 -0
  163. package/build/executor/compressor/utils/intTo2Bytes.d.ts +2 -0
  164. package/build/executor/compressor/utils/intTo2Bytes.js +14 -0
  165. package/build/executor/compressor/utils/intTo2Bytes.js.map +1 -0
  166. package/build/executor/compressor/utils/intTo3Bytes.d.ts +2 -0
  167. package/build/executor/compressor/utils/intTo3Bytes.js +18 -0
  168. package/build/executor/compressor/utils/intTo3Bytes.js.map +1 -0
  169. package/build/executor/compressor/utils/intToByte.d.ts +2 -0
  170. package/build/executor/compressor/utils/intToByte.js +10 -0
  171. package/build/executor/compressor/utils/intToByte.js.map +1 -0
  172. package/build/generic-swap-transaction-builder.js +3 -1
  173. package/build/generic-swap-transaction-builder.js.map +1 -1
  174. package/build/router/simpleswap.js +3 -1
  175. package/build/router/simpleswap.js.map +1 -1
  176. package/package.json +2 -2
  177. package/src/abi/BProtocol.json +1155 -0
  178. package/src/abi/Jarvis.json +1172 -0
  179. package/src/abi/MStableAsset.json +1545 -0
  180. package/src/abi/OneInchLp.json +1304 -0
  181. package/src/abi/Onebit.json +736 -0
  182. package/src/abi/Shell.json +1294 -0
  183. package/src/abi/TraderJoeV2Router.json +50 -0
  184. package/src/abi/integral/factory.json +333 -0
  185. package/src/abi/integral/oracle.json +501 -0
  186. package/src/abi/integral/pool.json +1041 -0
  187. package/src/abi/integral/relayer.json +1536 -0
  188. package/src/abi/zrx.v2.json +1967 -0
  189. package/src/abi/zrx.v3.json +3454 -0
  190. package/src/abi/zrx.v4.json +2193 -0
  191. package/src/config.ts +1 -1
  192. package/src/dex/OneInchLp.ts +84 -0
  193. package/src/dex/bProtocol/bProtocol-e2e.test.ts +93 -0
  194. package/src/dex/bProtocol/bProtocol.ts +108 -0
  195. package/src/dex/bProtocol/types.ts +13 -0
  196. package/src/dex/curve-v1-factory/config.ts +10 -47
  197. package/src/dex/curve-v1-factory/curve-v1-factory-e2e.test.ts +16 -92
  198. package/src/dex/curve-v1-factory/curve-v1-factory-integration.test.ts +5 -125
  199. package/src/dex/curve-v1-factory/curve-v1-factory.ts +45 -137
  200. package/src/dex/curve-v1-factory/price-handlers/functions/constants.ts +2 -0
  201. package/src/dex/curve-v1-factory/price-handlers/functions/get_dx.ts +1 -24
  202. package/src/dex/curve-v1-factory/state-polling-pools/custom-pool-polling.ts +2 -3
  203. package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +0 -1
  204. package/src/dex/curve-v1-factory/state-polling-pools/pool-polling-base.ts +10 -31
  205. package/src/dex/curve-v1-factory/types.ts +6 -22
  206. package/src/dex/curve-v1-stable-ng/config.ts +0 -18
  207. package/src/dex/curve-v1-stable-ng/curve-v1-stable-ng-e2e.test.ts +0 -17
  208. package/src/dex/index.ts +20 -3
  209. package/src/dex/integral/config.ts +20 -0
  210. package/src/dex/integral/context.ts +287 -0
  211. package/src/dex/integral/integral-e2e.test.ts +86 -0
  212. package/src/dex/integral/integral-events.test.ts +412 -0
  213. package/src/dex/integral/integral-factory.ts +146 -0
  214. package/src/dex/integral/integral-integration.test.ts +221 -0
  215. package/src/dex/integral/integral-pool.ts +198 -0
  216. package/src/dex/integral/integral-pricing.ts +190 -0
  217. package/src/dex/integral/integral-relayer.ts +285 -0
  218. package/src/dex/integral/integral-token.ts +95 -0
  219. package/src/dex/integral/integral.ts +523 -0
  220. package/src/dex/integral/test-artifacts/configs.json +1 -0
  221. package/src/dex/integral/test-artifacts/logs.json +1 -0
  222. package/src/dex/integral/test-artifacts/states.json +1 -0
  223. package/src/dex/integral/types.ts +88 -0
  224. package/src/dex/integral/utils-e2e.ts +194 -0
  225. package/src/dex/integral/utils.ts +146 -0
  226. package/src/dex/jarvis.ts +262 -0
  227. package/src/dex/mStable.ts +147 -0
  228. package/src/dex/onebit/onebit.ts +113 -0
  229. package/src/dex/onebit/types.ts +17 -0
  230. package/src/dex/shell.ts +84 -0
  231. package/src/dex/trader-joe-v2.ts +148 -0
  232. package/src/dex/uniswap-v3/contract-math/Oracle.ts +5 -4
  233. package/src/dex/zerox/config.ts +31 -0
  234. package/src/dex/zerox/index.ts +328 -0
  235. package/src/dex/zerox/order.ts +62 -0
  236. package/src/dex/zerox/types.ts +82 -0
  237. package/src/dex/zerox/zerox-e2e.test.ts +110 -0
  238. package/src/generic-swap-transaction-builder.ts +3 -1
  239. package/src/router/simpleswap.ts +3 -1
  240. package/tests/constants-e2e.ts +1 -1
  241. package/tests/utils-e2e.ts +0 -2
  242. package/.vscode/tasks.json +0 -15
  243. package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
  244. package/build/dex/aave-v2/tokens-avalanche.json +0 -44
  245. package/build/dex/aave-v2/tokens-mainnet.json +0 -188
  246. package/build/dex/aave-v2/tokens-polygon.json +0 -44
  247. package/build/dex/maker-psm/scripts/gem.abi.json +0 -136
  248. package/build/dex/maker-psm/scripts/validate-state.js +0 -185
  249. package/build/dex/maker-psm/scripts/validate-state.js.map +0 -1
  250. package/build/dex/maker-psm/scripts/vat.abi.json +0 -243
  251. package/build/dex/solidly-v3/scripts/check-event-pool-event.js +0 -53
  252. package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +0 -1
  253. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +0 -17
  254. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +0 -64
  255. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +0 -1
  256. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +0 -17
  257. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +0 -79
  258. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +0 -1
  259. package/src/abi/curve-v1-factory/CurveV1Router.abi.json +0 -331
  260. package/src/dex/curve-v1-factory/optimizer.ts +0 -61
  261. /package/build/dex/{solidly-v3/scripts/check-event-pool-event.d.ts → sdai/scripts/validate-state.d.ts} +0 -0
  262. /package/build/{dex/maker-psm/scripts/validate-state.d.ts → executor/compressor/fetchSaved.d.ts} +0 -0
@@ -0,0 +1,221 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ dotenv.config();
4
+
5
+ import { DummyDexHelper } from '../../dex-helper/index';
6
+ import { Network, SwapSide } from '../../constants';
7
+ import { BI_POWS } from '../../bigint-constants';
8
+ import { Integral } from './integral';
9
+ import {
10
+ checkPoolPrices,
11
+ checkPoolsLiquidity,
12
+ checkConstantPoolPrices,
13
+ } from '../../../tests/utils';
14
+ import { Tokens } from '../../../tests/constants-e2e';
15
+ import { Token } from '../../types';
16
+ import { IntegralConfig } from './config';
17
+ import IntegralRelayerABI from '../../abi/integral/relayer.json';
18
+ import { Interface } from '@ethersproject/abi';
19
+ import { uint256ToBigInt } from '../../lib/decoders';
20
+ import { MultiCallParams } from '../../lib/multi-wrapper';
21
+
22
+ jest.setTimeout(50 * 1000);
23
+ const network = Network.MAINNET;
24
+ const testDatas: {
25
+ tokenA: Token;
26
+ tokenB: Token;
27
+ block: number;
28
+ data: number[];
29
+ }[] = [
30
+ {
31
+ tokenA: { symbol: 'USDC' } as Token,
32
+ tokenB: { symbol: 'USDT' } as Token,
33
+ block: 19608294,
34
+ data: [
35
+ 0, 5100, 10200, 15300, 20400, 25500, 30600, 35700, 40800, 45900, 51000,
36
+ ],
37
+ },
38
+ {
39
+ tokenA: { symbol: 'USDT' } as Token,
40
+ tokenB: { symbol: 'WETH' } as Token,
41
+ block: 19831195,
42
+ data: [0, 1.7, 3.4, 5.1, 6.8, 8.5, 10.2, 11.9, 13.6, 15.3, 17],
43
+ },
44
+ ];
45
+ initializeTokens();
46
+
47
+ const dexHelper = new DummyDexHelper(network);
48
+ const dexKey = 'Integral';
49
+
50
+ function initializeTokens() {
51
+ for (const [i, testData] of testDatas.entries()) {
52
+ const tokenA = Tokens[network][testData.tokenA.symbol!];
53
+ const tokenB = Tokens[network][testData.tokenB.symbol!];
54
+ tokenA.symbol = testData.tokenA.symbol;
55
+ tokenB.symbol = testData.tokenB.symbol;
56
+ testDatas[i].tokenA = tokenA;
57
+ testDatas[i].tokenB = tokenB;
58
+ }
59
+ }
60
+
61
+ function initializeAmounts(token: Token, units: number[]) {
62
+ const precision = 10 ** 18;
63
+ return units.map(
64
+ unit =>
65
+ (BigInt(unit * precision) * BI_POWS[token.decimals]) / BigInt(precision),
66
+ );
67
+ }
68
+
69
+ async function checkOnChainPricing(
70
+ relayerAddress: string,
71
+ funcName: string,
72
+ blockNumber: number,
73
+ prices: bigint[],
74
+ TokenA: Token,
75
+ TokenB: Token,
76
+ expectedAmounts: bigint[],
77
+ ) {
78
+ const relayerInterface = new Interface(IntegralRelayerABI);
79
+ const callData = expectedAmounts
80
+ .slice(1)
81
+ .map<MultiCallParams<bigint>>(amount => ({
82
+ target: relayerAddress,
83
+ callData: relayerInterface.encodeFunctionData(funcName, [
84
+ TokenA.address,
85
+ TokenB.address,
86
+ amount,
87
+ ]),
88
+ decodeFunction: uint256ToBigInt,
89
+ }));
90
+ const results = await dexHelper.multiWrapper.tryAggregate(
91
+ false,
92
+ callData,
93
+ blockNumber,
94
+ dexHelper.multiWrapper.defaultBatchSize,
95
+ false,
96
+ );
97
+
98
+ const expectedPrices = [0n].concat(results.map(result => result.returnData));
99
+ expect(prices).toEqual(expectedPrices);
100
+ }
101
+
102
+ for (const { tokenA, tokenB, data, block } of testDatas) {
103
+ describe(`Integral Pool ${tokenB.symbol}-${tokenA.symbol}`, function () {
104
+ let integral: Integral;
105
+
106
+ beforeAll(async () => {
107
+ integral = new Integral(network, dexKey, dexHelper);
108
+ await integral.initializePricing(block);
109
+ });
110
+
111
+ it(`getPoolIdentifiers and getPricesVolume SELL [${tokenB.symbol}, ${tokenA.symbol}]`, async function () {
112
+ const amounts = initializeAmounts(tokenB, data);
113
+ const pools = await integral.getPoolIdentifiers(
114
+ tokenB,
115
+ tokenA,
116
+ SwapSide.SELL,
117
+ block,
118
+ );
119
+ console.log(
120
+ `${tokenA.symbol} <> ${tokenB.symbol} Pool Identifiers: `,
121
+ pools,
122
+ );
123
+
124
+ expect(pools.length).toBeGreaterThan(0);
125
+
126
+ const poolPrices = await integral.getPricesVolume(
127
+ tokenB,
128
+ tokenA,
129
+ amounts,
130
+ SwapSide.SELL,
131
+ block,
132
+ pools,
133
+ );
134
+ console.log(
135
+ `${tokenA.symbol} <> ${tokenB.symbol} Pool Prices, SELL: `,
136
+ poolPrices,
137
+ );
138
+
139
+ expect(poolPrices).not.toBeNull();
140
+ if (integral.hasConstantPriceLargeAmounts) {
141
+ checkConstantPoolPrices(poolPrices!, amounts, dexKey);
142
+ } else {
143
+ checkPoolPrices(poolPrices!, amounts, SwapSide.SELL, dexKey);
144
+ }
145
+
146
+ // Check if onchain pricing equals to calculated ones
147
+ await checkOnChainPricing(
148
+ IntegralConfig[dexKey][network].relayerAddress,
149
+ 'quoteSell',
150
+ block,
151
+ poolPrices![0].prices,
152
+ tokenB,
153
+ tokenA,
154
+ amounts,
155
+ );
156
+ });
157
+
158
+ it(`getPoolIdentifiers and getPricesVolume BUY [${tokenA.symbol}, ${tokenB.symbol}]`, async function () {
159
+ const amounts = initializeAmounts(tokenB, data);
160
+ const pools = await integral.getPoolIdentifiers(
161
+ tokenA,
162
+ tokenB,
163
+ SwapSide.BUY,
164
+ block,
165
+ );
166
+ console.log(
167
+ `${tokenA.symbol} <> ${tokenB.symbol} Pool Identifiers: `,
168
+ pools,
169
+ );
170
+
171
+ expect(pools.length).toBeGreaterThan(0);
172
+
173
+ const poolPrices = await integral.getPricesVolume(
174
+ tokenA,
175
+ tokenB,
176
+ amounts,
177
+ SwapSide.BUY,
178
+ block,
179
+ pools,
180
+ );
181
+ console.log(
182
+ `${tokenA.symbol} <> ${tokenB.symbol} Pool Prices, Buy: `,
183
+ poolPrices,
184
+ );
185
+
186
+ expect(poolPrices).not.toBeNull();
187
+ if (integral.hasConstantPriceLargeAmounts) {
188
+ checkConstantPoolPrices(poolPrices!, amounts, dexKey);
189
+ } else {
190
+ checkPoolPrices(poolPrices!, amounts, SwapSide.BUY, dexKey);
191
+ }
192
+
193
+ // Check if onchain pricing equals to calculated ones
194
+ await checkOnChainPricing(
195
+ IntegralConfig[dexKey][network].relayerAddress,
196
+ 'quoteBuy',
197
+ block,
198
+ poolPrices![0].prices,
199
+ tokenA,
200
+ tokenB,
201
+ amounts,
202
+ );
203
+ });
204
+ });
205
+ }
206
+
207
+ describe('Integral Top Pools', function () {
208
+ const integral = new Integral(network, dexKey, dexHelper);
209
+ const { tokenA } = testDatas[0];
210
+ it(`getTopPoolsForToken [${tokenA.symbol}]`, async function () {
211
+ const poolLiquidity = await integral.getTopPoolsForToken(
212
+ tokenA.address,
213
+ 10,
214
+ );
215
+ console.log(`${tokenA.symbol} Top Pools:`, poolLiquidity);
216
+
217
+ if (!integral.hasConstantPriceLargeAmounts) {
218
+ checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey);
219
+ }
220
+ });
221
+ });
@@ -0,0 +1,198 @@
1
+ import _ from 'lodash';
2
+ import { Interface } from '@ethersproject/abi';
3
+ import { LogDescription } from 'ethers/lib/utils';
4
+ import { AsyncOrSync } from 'ts-essentials';
5
+ import { BlockHeader, Log, Logger } from '../../types';
6
+ import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
7
+ import { IDexHelper } from '../../dex-helper/idex-helper';
8
+ import { PoolState } from './types';
9
+ import IntegralPoolABI from '../../abi/integral/pool.json';
10
+ import IntegralOracleABI from '../../abi/integral/oracle.json';
11
+ import UniswapV3PoolABI from '../../abi/uniswap-v3/UniswapV3Pool.abi.json';
12
+ import { Address } from '../../types';
13
+ import { MultiCallParams } from '../../lib/multi-wrapper';
14
+ import {
15
+ addressDecode,
16
+ uint256ToBigInt,
17
+ uint8ToNumber,
18
+ } from '../../lib/decoders';
19
+ import { AbiItem } from 'web3-utils';
20
+ import { BigNumber } from 'ethers';
21
+
22
+ export class IntegralEventPool extends StatefulEventSubscriber<PoolState> {
23
+ handlers: {
24
+ [event: string]: (
25
+ event: any,
26
+ pool: PoolState,
27
+ blockHeader: Readonly<BlockHeader>,
28
+ ) => AsyncOrSync<PoolState>;
29
+ } = {};
30
+
31
+ logDecoder: (log: Log) => any;
32
+
33
+ addressesSubscribed: string[];
34
+
35
+ readonly poolAddress: Address;
36
+ readonly token0: Address;
37
+ readonly token1: Address;
38
+
39
+ constructor(
40
+ public parentName: string,
41
+ protected network: number,
42
+ protected dexHelper: IDexHelper,
43
+ poolAddress: Address,
44
+ token0: Address,
45
+ token1: Address,
46
+ logger: Logger,
47
+ protected poolIface = new Interface(IntegralPoolABI),
48
+ ) {
49
+ super(parentName, `${token0}_${token1}`, dexHelper, logger);
50
+ this.token0 = token0.toLowerCase();
51
+ this.token1 = token1.toLowerCase();
52
+ this.poolAddress = poolAddress.toLowerCase();
53
+
54
+ this.logDecoder = (log: Log) => this.poolIface.parseLog(log);
55
+ this.addressesSubscribed = [this.poolAddress];
56
+ this.handlers['SetSwapFee'] = this.handleSetSwapFee.bind(this);
57
+ this.handlers['SetMintFee'] = this.handleSetMintFee.bind(this);
58
+ this.handlers['SetBurnFee'] = this.handleSetBurnFee.bind(this);
59
+ }
60
+
61
+ /**
62
+ * The function is called every time any of the subscribed
63
+ * addresses release log. The function accepts the current
64
+ * state, updates the state according to the log, and returns
65
+ * the updated state.
66
+ * @param state - Current state of event subscriber
67
+ * @param log - Log released by one of the subscribed addresses
68
+ * @returns Updates state of the event subscriber after the log
69
+ */
70
+ protected async processLog(
71
+ state: PoolState,
72
+ log: Readonly<Log>,
73
+ blockHeader: Readonly<BlockHeader>,
74
+ ): Promise<PoolState | null> {
75
+ try {
76
+ const event = this.logDecoder(log);
77
+ if (event.name in this.handlers) {
78
+ return await this.handlers[event.name](event, state, blockHeader);
79
+ }
80
+ return state;
81
+ } catch (e) {
82
+ this.logger.error(
83
+ `Error_${this.parentName}_processLog could not parse the log with topic ${log.topics}:`,
84
+ e,
85
+ );
86
+ return null;
87
+ }
88
+ }
89
+
90
+ /**
91
+ * The function generates state using on-chain calls. This
92
+ * function is called to regenerate state if the event based
93
+ * system fails to fetch events and the local state is no
94
+ * more correct.
95
+ * @param blockNumber - Blocknumber for which the state should
96
+ * should be generated
97
+ * @returns state of the event subscriber at blocknumber
98
+ */
99
+ async generateState(blockNumber: number): Promise<Readonly<PoolState>> {
100
+ const state = {} as PoolState;
101
+ const pool = new this.dexHelper.web3Provider.eth.Contract(
102
+ IntegralPoolABI as AbiItem[],
103
+ this.poolAddress,
104
+ );
105
+ const poolInfoCallDatas: MultiCallParams<string | bigint>[] = [
106
+ {
107
+ target: this.poolAddress,
108
+ callData: pool.methods.oracle().encodeABI(),
109
+ decodeFunction: addressDecode,
110
+ },
111
+ {
112
+ target: this.poolAddress,
113
+ callData: pool.methods.mintFee().encodeABI(),
114
+ decodeFunction: uint256ToBigInt,
115
+ },
116
+ {
117
+ target: this.poolAddress,
118
+ callData: pool.methods.burnFee().encodeABI(),
119
+ decodeFunction: uint256ToBigInt,
120
+ },
121
+ {
122
+ target: this.poolAddress,
123
+ callData: pool.methods.swapFee().encodeABI(),
124
+ decodeFunction: uint256ToBigInt,
125
+ },
126
+ ];
127
+ const poolInfos = await this.dexHelper.multiWrapper.aggregate<
128
+ string | bigint
129
+ >(poolInfoCallDatas, blockNumber);
130
+ const oracleAddress = poolInfos[0].toString();
131
+
132
+ state.mintFee = BigInt(poolInfos[1]);
133
+ state.burnFee = BigInt(poolInfos[2]);
134
+ state.swapFee = BigInt(poolInfos[3]);
135
+ state.oracle = oracleAddress;
136
+
137
+ const historyState = this.getStaleState();
138
+ if (!historyState) {
139
+ const oracle = new this.dexHelper.web3Provider.eth.Contract(
140
+ IntegralOracleABI as AbiItem[],
141
+ oracleAddress,
142
+ );
143
+ const oracleInfosCallDatas: MultiCallParams<number | string>[] = [
144
+ {
145
+ target: oracleAddress,
146
+ callData: oracle.methods.xDecimals().encodeABI(),
147
+ decodeFunction: uint8ToNumber,
148
+ },
149
+ {
150
+ target: oracleAddress,
151
+ callData: oracle.methods.yDecimals().encodeABI(),
152
+ decodeFunction: uint8ToNumber,
153
+ },
154
+ {
155
+ target: oracleAddress,
156
+ callData: oracle.methods.uniswapPair().encodeABI(),
157
+ decodeFunction: addressDecode,
158
+ },
159
+ ];
160
+ const oracleInfos = await this.dexHelper.multiWrapper.aggregate<
161
+ number | string
162
+ >(oracleInfosCallDatas, blockNumber);
163
+
164
+ state.uniswapPool = oracleInfos[2].toString();
165
+ state.decimals0 = Number(oracleInfos[0]);
166
+ state.decimals1 = Number(oracleInfos[1]);
167
+
168
+ const uniswapPool = new this.dexHelper.web3Provider.eth.Contract(
169
+ UniswapV3PoolABI as AbiItem[],
170
+ state.uniswapPool,
171
+ );
172
+ const fee = await uniswapPool.methods.fee().call(undefined, blockNumber);
173
+ state.uniswapPoolFee = BigInt(fee);
174
+ } else {
175
+ state.uniswapPool = historyState.uniswapPool;
176
+ state.decimals0 = historyState.decimals0;
177
+ state.decimals1 = historyState.decimals1;
178
+ state.uniswapPoolFee = historyState.uniswapPoolFee;
179
+ }
180
+
181
+ return state;
182
+ }
183
+
184
+ handleSetSwapFee(event: LogDescription, pool: PoolState) {
185
+ pool.swapFee = BigInt(BigNumber.from(event.args.fee).toString());
186
+ return pool;
187
+ }
188
+
189
+ handleSetMintFee(event: LogDescription, pool: PoolState) {
190
+ pool.mintFee = BigInt(BigNumber.from(event.args.fee).toString());
191
+ return pool;
192
+ }
193
+
194
+ handleSetBurnFee(event: LogDescription, pool: PoolState) {
195
+ pool.burnFee = BigInt(BigNumber.from(event.args.fee).toString());
196
+ return pool;
197
+ }
198
+ }
@@ -0,0 +1,190 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import { IDexHelper } from '../../dex-helper';
3
+ import { Address, Logger } from '../../types';
4
+ import { UniswapV3EventPool } from '../uniswap-v3/uniswap-v3-pool';
5
+ import { UniswapV3Config } from '../uniswap-v3/config';
6
+ import UniswapV3StateMulticallABI from '../../abi/uniswap-v3/UniswapV3StateMulticall.abi.json';
7
+ import { Network } from '../../constants';
8
+ import { AbiItem } from 'web3-utils';
9
+ import {
10
+ DecodedStateMultiCallResultWithRelativeBitmaps,
11
+ OracleObservation,
12
+ PoolState,
13
+ } from '../uniswap-v3/types';
14
+ import {
15
+ _reduceTickBitmap,
16
+ _reduceTicks,
17
+ } from '../uniswap-v3/contract-math/utils';
18
+ import { bigIntify } from '../../utils';
19
+ import { TickBitMap } from '../uniswap-v3/contract-math/TickBitMap';
20
+ import { Observation } from './types';
21
+ import { MultiResult } from '../../lib/multi-wrapper';
22
+ import { BytesLike, ethers } from 'ethers';
23
+ import { extractSuccessAndValue } from '../../lib/decoders';
24
+
25
+ export function decodeStateMultiCallResultWithObservation(
26
+ result: MultiResult<BytesLike> | BytesLike,
27
+ ): Observation {
28
+ const [isSuccess, toDecode] = extractSuccessAndValue(result);
29
+
30
+ if (!isSuccess || toDecode === '0x')
31
+ throw new Error(
32
+ `decodeStateMultiCallResultWithRelativeBitmaps failed to get decodable result: ${result}`,
33
+ );
34
+
35
+ const decoded = ethers.utils.defaultAbiCoder.decode(
36
+ [
37
+ `
38
+ tuple(
39
+ uint32 blockTimestamp,
40
+ int56 tickCumulative,
41
+ uint160 secondsPerLiquidityCumulativeX128,
42
+ bool initialized,
43
+ )
44
+ `,
45
+ ],
46
+ toDecode,
47
+ )[0];
48
+ return decoded as Observation;
49
+ }
50
+
51
+ export class IntegralPricing extends UniswapV3EventPool {
52
+ private readonly providedPoolAddress: Address;
53
+ constructor(
54
+ readonly dexHelper: IDexHelper,
55
+ parentName: string,
56
+ erc20Interface: Interface,
57
+ poolAddress: Address,
58
+ token0: Address,
59
+ token1: Address,
60
+ feeCode: bigint,
61
+ logger: Logger,
62
+ network: Network,
63
+ mapKey: string = '',
64
+ ) {
65
+ const uniswapConfig = UniswapV3Config['UniswapV3'][network];
66
+ const stateMultiContract = new dexHelper.web3Provider.eth.Contract(
67
+ uniswapConfig.stateMultiCallAbi !== undefined
68
+ ? uniswapConfig.stateMultiCallAbi
69
+ : (UniswapV3StateMulticallABI as AbiItem[]),
70
+ uniswapConfig.stateMulticall,
71
+ );
72
+ super(
73
+ dexHelper,
74
+ parentName,
75
+ stateMultiContract,
76
+ undefined,
77
+ erc20Interface,
78
+ uniswapConfig.factory,
79
+ feeCode,
80
+ token0,
81
+ token1,
82
+ logger,
83
+ mapKey,
84
+ uniswapConfig.initHash,
85
+ );
86
+ this.providedPoolAddress = poolAddress;
87
+ }
88
+
89
+ get poolAddress() {
90
+ return this.providedPoolAddress;
91
+ }
92
+
93
+ set poolAddress(_address: Address) {}
94
+
95
+ async generateState(blockNumber: number): Promise<Readonly<PoolState>> {
96
+ const callData = this._getStateRequestCallData();
97
+
98
+ const [resBalance0, resBalance1, resState] =
99
+ await this.dexHelper.multiWrapper.tryAggregate<
100
+ bigint | DecodedStateMultiCallResultWithRelativeBitmaps
101
+ >(
102
+ false,
103
+ callData,
104
+ blockNumber,
105
+ this.dexHelper.multiWrapper.defaultBatchSize,
106
+ false,
107
+ );
108
+
109
+ if (!resState.success) throw new Error('Pool does not exist');
110
+
111
+ const [balance0, balance1, _state] = [
112
+ resBalance0.returnData,
113
+ resBalance1.returnData,
114
+ resState.returnData,
115
+ ] as [bigint, bigint, DecodedStateMultiCallResultWithRelativeBitmaps];
116
+
117
+ const observationsCallData = [
118
+ ...Array(_state.slot0.observationCardinality),
119
+ ].map((_, i) => {
120
+ return {
121
+ target: this.poolAddress,
122
+ callData: this.poolIface.encodeFunctionData('observations', [i]),
123
+ decodeFunction: decodeStateMultiCallResultWithObservation,
124
+ };
125
+ });
126
+
127
+ const resObservations =
128
+ await this.dexHelper.multiWrapper.tryAggregate<Observation>(
129
+ false,
130
+ observationsCallData,
131
+ blockNumber,
132
+ 13107,
133
+ false,
134
+ );
135
+ const observations = resObservations.reduce((memo, obs, i) => {
136
+ memo[i] = {
137
+ blockTimestamp: BigInt(obs.returnData.blockTimestamp),
138
+ tickCumulative: BigInt(obs.returnData.tickCumulative.toString()),
139
+ secondsPerLiquidityCumulativeX128: BigInt(
140
+ obs.returnData.secondsPerLiquidityCumulativeX128.toString(),
141
+ ),
142
+ initialized: obs.returnData.initialized,
143
+ };
144
+ return memo;
145
+ }, {} as { [index: number]: OracleObservation });
146
+
147
+ const tickBitmap = {};
148
+ const ticks = {};
149
+
150
+ _reduceTickBitmap(tickBitmap, _state.tickBitmap);
151
+ _reduceTicks(ticks, _state.ticks);
152
+
153
+ const currentTick = bigIntify(_state.slot0.tick);
154
+ const tickSpacing = bigIntify(_state.tickSpacing);
155
+
156
+ const startTickBitmap = TickBitMap.position(currentTick / tickSpacing)[0];
157
+ const requestedRange = this.getBitmapRangeToRequest();
158
+
159
+ return {
160
+ pool: _state.pool,
161
+ blockTimestamp: bigIntify(_state.blockTimestamp),
162
+ slot0: {
163
+ sqrtPriceX96: bigIntify(_state.slot0.sqrtPriceX96),
164
+ tick: currentTick,
165
+ observationIndex: +_state.slot0.observationIndex,
166
+ observationCardinality: +_state.slot0.observationCardinality,
167
+ observationCardinalityNext: +_state.slot0.observationCardinalityNext,
168
+ feeProtocol: bigIntify(_state.slot0.feeProtocol),
169
+ },
170
+ liquidity: bigIntify(_state.liquidity),
171
+ fee: this.feeCode,
172
+ tickSpacing,
173
+ maxLiquidityPerTick: bigIntify(_state.maxLiquidityPerTick),
174
+ tickBitmap,
175
+ ticks,
176
+ observations,
177
+ isValid: true,
178
+ startTickBitmap,
179
+ lowestKnownTick:
180
+ (BigInt.asIntN(24, startTickBitmap - requestedRange) << 8n) *
181
+ tickSpacing,
182
+ highestKnownTick:
183
+ ((BigInt.asIntN(24, startTickBitmap + requestedRange) << 8n) +
184
+ BigInt.asIntN(24, 255n)) *
185
+ tickSpacing,
186
+ balance0,
187
+ balance1,
188
+ };
189
+ }
190
+ }