@paraswap/dex-lib 4.0.6-rfq-pub-sub.3 → 4.0.6

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 (204) hide show
  1. package/.idea/aws.xml +17 -0
  2. package/.idea/codeStyles/Project.xml +19 -0
  3. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/paraswap-dex-lib.iml +9 -0
  7. package/.idea/prettier.xml +7 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/build/abi/fluid-dex/fluid-dex.abi.json +579 -25
  10. package/build/abi/integral/factory.json +333 -0
  11. package/build/abi/integral/oracle.json +501 -0
  12. package/build/abi/{inception/inception-ineth-pool.json → integral/pool.json} +522 -543
  13. package/build/abi/{wombat/pool.json → integral/relayer.json} +720 -473
  14. package/build/dex/aave-v1/aave-v1.d.ts +1 -2
  15. package/build/dex/aave-v1/aave-v1.js +0 -23
  16. package/build/dex/aave-v1/aave-v1.js.map +1 -1
  17. package/build/dex/fluid-dex/fluid-dex-generate-pool.d.ts +49 -0
  18. package/build/dex/fluid-dex/fluid-dex-generate-pool.js +104 -0
  19. package/build/dex/fluid-dex/fluid-dex-generate-pool.js.map +1 -0
  20. package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.d.ts +1 -1
  21. package/build/dex/fluid-dex/fluid-dex-liquidity-proxy.js.map +1 -1
  22. package/build/dex/fluid-dex/fluid-dex-pool.js +1 -2
  23. package/build/dex/fluid-dex/fluid-dex-pool.js.map +1 -1
  24. package/build/dex/fluid-dex/fluid-dex.d.ts +21 -2
  25. package/build/dex/fluid-dex/fluid-dex.js +108 -37
  26. package/build/dex/fluid-dex/fluid-dex.js.map +1 -1
  27. package/build/dex/fluid-dex/types.d.ts +3 -1
  28. package/build/dex/generic-rfq/generic-rfq.js +2 -1
  29. package/build/dex/generic-rfq/generic-rfq.js.map +1 -1
  30. package/build/dex/generic-rfq/rate-fetcher.d.ts +1 -4
  31. package/build/dex/generic-rfq/rate-fetcher.js +20 -52
  32. package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
  33. package/build/dex/integral/config.d.ts +4 -0
  34. package/build/dex/integral/config.js +20 -0
  35. package/build/dex/integral/config.js.map +1 -0
  36. package/build/dex/integral/context.d.ts +40 -0
  37. package/build/dex/integral/context.js +158 -0
  38. package/build/dex/integral/context.js.map +1 -0
  39. package/build/dex/integral/integral-factory.d.ts +24 -0
  40. package/build/dex/integral/integral-factory.js +95 -0
  41. package/build/dex/integral/integral-factory.js.map +1 -0
  42. package/build/dex/integral/integral-pool.d.ts +50 -0
  43. package/build/dex/integral/integral-pool.js +149 -0
  44. package/build/dex/integral/integral-pool.js.map +1 -0
  45. package/build/dex/integral/integral-pricing.d.ts +18 -0
  46. package/build/dex/integral/integral-pricing.js +114 -0
  47. package/build/dex/integral/integral-pricing.js.map +1 -0
  48. package/build/dex/integral/integral-relayer.d.ts +42 -0
  49. package/build/dex/integral/integral-relayer.js +192 -0
  50. package/build/dex/integral/integral-relayer.js.map +1 -0
  51. package/build/dex/integral/integral-token.d.ts +27 -0
  52. package/build/dex/integral/integral-token.js +59 -0
  53. package/build/dex/integral/integral-token.js.map +1 -0
  54. package/build/dex/integral/integral.d.ts +41 -0
  55. package/build/dex/integral/integral.js +376 -0
  56. package/build/dex/integral/integral.js.map +1 -0
  57. package/build/dex/integral/types.d.ts +85 -0
  58. package/build/dex/integral/types.js +9 -0
  59. package/build/dex/integral/types.js.map +1 -0
  60. package/build/dex/integral/utils-e2e.d.ts +9 -0
  61. package/build/dex/integral/utils-e2e.js +131 -0
  62. package/build/dex/integral/utils-e2e.js.map +1 -0
  63. package/build/dex/integral/utils.d.ts +17 -0
  64. package/build/dex/integral/utils.js +94 -0
  65. package/build/dex/integral/utils.js.map +1 -0
  66. package/build/dex/jarvis.d.ts +1 -2
  67. package/build/dex/jarvis.js +0 -58
  68. package/build/dex/jarvis.js.map +1 -1
  69. package/build/dex/platypus/platypus.d.ts +1 -2
  70. package/build/dex/platypus/platypus.js +0 -45
  71. package/build/dex/platypus/platypus.js.map +1 -1
  72. package/build/dex/stable-pool.js +8 -1
  73. package/build/dex/stable-pool.js.map +1 -1
  74. package/build/dex/swaap-v1/swaap-v1.d.ts +1 -2
  75. package/build/dex/swaap-v1/swaap-v1.js +0 -14
  76. package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
  77. package/build/dex/trader-joe-v2.1/optimizer.d.ts +2 -0
  78. package/build/dex/trader-joe-v2.1/optimizer.js +47 -0
  79. package/build/dex/trader-joe-v2.1/optimizer.js.map +1 -0
  80. package/build/dex/zerox/index.d.ts +26 -4
  81. package/build/dex/zerox/index.js +42 -50
  82. package/build/dex/zerox/index.js.map +1 -1
  83. package/build/dex/zerox/types.d.ts +0 -29
  84. package/build/dex/zerox/types.js +1 -8
  85. package/build/dex/zerox/types.js.map +1 -1
  86. package/build/dex-helper/dummy-dex-helper.js +0 -7
  87. package/build/dex-helper/dummy-dex-helper.js.map +1 -1
  88. package/build/dex-helper/icache.d.ts +0 -2
  89. package/package.json +1 -1
  90. package/src/abi/fluid-dex/fluid-dex.abi.json +581 -25
  91. package/src/dex/fluid-dex/constants.ts +1 -0
  92. package/src/dex/fluid-dex/fluid-dex-e2e.test.ts +17 -0
  93. package/src/dex/fluid-dex/fluid-dex-events.test.ts +55 -5
  94. package/src/dex/fluid-dex/fluid-dex-liquidity-proxy.ts +1 -2
  95. package/src/dex/fluid-dex/fluid-dex-pool.ts +138 -0
  96. package/src/dex/fluid-dex/fluid-dex.ts +221 -69
  97. package/src/dex/fluid-dex/types.ts +3 -1
  98. package/src/dex/generic-rfq/generic-rfq.ts +6 -1
  99. package/src/dex/generic-rfq/rate-fetcher.ts +42 -77
  100. package/src/dex-helper/dummy-dex-helper.ts +0 -13
  101. package/src/dex-helper/icache.ts +0 -4
  102. package/tests/constants-e2e.ts +5 -0
  103. package/.vscode/launch.json +0 -53
  104. package/.vscode/settings.json +0 -2
  105. package/.vscode/tasks.json +0 -15
  106. package/build/abi/inception/inception-ratio-feed.json +0 -329
  107. package/build/abi/inception/inception-vault.json +0 -991
  108. package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
  109. package/build/abi/usual-m-smart-m/usualM.abi.json +0 -483
  110. package/build/abi/usual-m-usd0/usualCollateralDao.abi.json +0 -681
  111. package/build/abi/usual-m-wrapped-m/usualM.abi.json +0 -509
  112. package/build/dex/aave-v2/tokens-avalanche.json +0 -44
  113. package/build/dex/aave-v2/tokens-mainnet.json +0 -188
  114. package/build/dex/aave-v2/tokens-polygon.json +0 -44
  115. package/build/dex/balancer-v3/abi/balancerBatchRouter.d.ts +0 -729
  116. package/build/dex/balancer-v3/abi/balancerBatchRouter.js +0 -732
  117. package/build/dex/balancer-v3/abi/balancerBatchRouter.js.map +0 -1
  118. package/build/dex/balancer-v3/abi/balancerRouter.d.ts +0 -1406
  119. package/build/dex/balancer-v3/abi/balancerRouter.js +0 -1175
  120. package/build/dex/balancer-v3/abi/balancerRouter.js.map +0 -1
  121. package/build/dex/balancer-v3/abi/vaultExtension.V3.d.ts +0 -2081
  122. package/build/dex/balancer-v3/abi/vaultExtension.V3.js +0 -1851
  123. package/build/dex/balancer-v3/abi/vaultExtension.V3.js.map +0 -1
  124. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.d.ts +0 -34
  125. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js +0 -406
  126. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js.map +0 -1
  127. package/build/dex/inception/config.d.ts +0 -4
  128. package/build/dex/inception/config.js +0 -109
  129. package/build/dex/inception/config.js.map +0 -1
  130. package/build/dex/inception/inception-event-pool.d.ts +0 -16
  131. package/build/dex/inception/inception-event-pool.js +0 -49
  132. package/build/dex/inception/inception-event-pool.js.map +0 -1
  133. package/build/dex/inception/inception.d.ts +0 -43
  134. package/build/dex/inception/inception.js +0 -180
  135. package/build/dex/inception/inception.js.map +0 -1
  136. package/build/dex/inception/tokens.d.ts +0 -9
  137. package/build/dex/inception/tokens.js +0 -28
  138. package/build/dex/inception/tokens.js.map +0 -1
  139. package/build/dex/inception/types.d.ts +0 -22
  140. package/build/dex/inception/types.js +0 -3
  141. package/build/dex/inception/types.js.map +0 -1
  142. package/build/dex/inception/utils.d.ts +0 -7
  143. package/build/dex/inception/utils.js +0 -58
  144. package/build/dex/inception/utils.js.map +0 -1
  145. package/build/dex/maker-psm/scripts/gem.abi.json +0 -136
  146. package/build/dex/maker-psm/scripts/validate-state.d.ts +0 -0
  147. package/build/dex/maker-psm/scripts/validate-state.js +0 -185
  148. package/build/dex/maker-psm/scripts/validate-state.js.map +0 -1
  149. package/build/dex/maker-psm/scripts/vat.abi.json +0 -243
  150. package/build/dex/solidly-v3/scripts/check-event-pool-event.d.ts +0 -1
  151. package/build/dex/solidly-v3/scripts/check-event-pool-event.js +0 -53
  152. package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +0 -1
  153. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +0 -17
  154. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +0 -64
  155. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +0 -1
  156. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +0 -17
  157. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +0 -79
  158. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +0 -1
  159. package/build/dex/uniswap-v3/uniswap-v3-pricing.d.ts +0 -4
  160. package/build/dex/uniswap-v3/uniswap-v3-pricing.js +0 -43
  161. package/build/dex/uniswap-v3/uniswap-v3-pricing.js.map +0 -1
  162. package/build/dex/uniswap-v3/uniswap-v3-worker.d.ts +0 -1
  163. package/build/dex/uniswap-v3/uniswap-v3-worker.js +0 -10
  164. package/build/dex/uniswap-v3/uniswap-v3-worker.js.map +0 -1
  165. package/build/dex/usual/types.d.ts +0 -13
  166. package/build/dex/usual/types.js +0 -3
  167. package/build/dex/usual/types.js.map +0 -1
  168. package/build/dex/usual/usual-bond.d.ts +0 -18
  169. package/build/dex/usual/usual-bond.js +0 -52
  170. package/build/dex/usual/usual-bond.js.map +0 -1
  171. package/build/dex/usual/usual-m-smart-m.d.ts +0 -17
  172. package/build/dex/usual/usual-m-smart-m.js +0 -50
  173. package/build/dex/usual/usual-m-smart-m.js.map +0 -1
  174. package/build/dex/usual/usual-m-usd0.d.ts +0 -17
  175. package/build/dex/usual/usual-m-usd0.js +0 -51
  176. package/build/dex/usual/usual-m-usd0.js.map +0 -1
  177. package/build/dex/usual/usual-m-wrapped-m.d.ts +0 -17
  178. package/build/dex/usual/usual-m-wrapped-m.js +0 -50
  179. package/build/dex/usual/usual-m-wrapped-m.js.map +0 -1
  180. package/build/dex/usual/usual.d.ts +0 -27
  181. package/build/dex/usual/usual.js +0 -125
  182. package/build/dex/usual/usual.js.map +0 -1
  183. package/build/dex/usual-m-smart-m/config.d.ts +0 -3
  184. package/build/dex/usual-m-smart-m/config.js +0 -13
  185. package/build/dex/usual-m-smart-m/config.js.map +0 -1
  186. package/build/dex/usual-m-smart-m/types.d.ts +0 -7
  187. package/build/dex/usual-m-smart-m/types.js +0 -3
  188. package/build/dex/usual-m-smart-m/types.js.map +0 -1
  189. package/build/dex/usual-m-smart-m/usual-m-smart-m.d.ts +0 -35
  190. package/build/dex/usual-m-smart-m/usual-m-smart-m.js +0 -161
  191. package/build/dex/usual-m-smart-m/usual-m-smart-m.js.map +0 -1
  192. package/build/dex/usual-m-usd0/config.d.ts +0 -3
  193. package/build/dex/usual-m-usd0/config.js +0 -14
  194. package/build/dex/usual-m-usd0/config.js.map +0 -1
  195. package/build/dex/usual-m-usd0/types.d.ts +0 -8
  196. package/build/dex/usual-m-usd0/types.js +0 -3
  197. package/build/dex/usual-m-usd0/types.js.map +0 -1
  198. package/build/dex/usual-m-usd0/usual-m-usd0.d.ts +0 -35
  199. package/build/dex/usual-m-usd0/usual-m-usd0.js +0 -159
  200. package/build/dex/usual-m-usd0/usual-m-usd0.js.map +0 -1
  201. package/build/lib/pub-sub.d.ts +0 -39
  202. package/build/lib/pub-sub.js +0 -133
  203. package/build/lib/pub-sub.js.map +0 -1
  204. package/src/lib/pub-sub.ts +0 -174
@@ -0,0 +1 @@
1
+ export const MIN_SWAP_LIQUIDITY = 10n ** 4n;
@@ -118,6 +118,23 @@ describe('FluidDex E2E', () => {
118
118
  describe('Mainnet', () => {
119
119
  const network = Network.MAINNET;
120
120
 
121
+ describe('ETH -> INST', () => {
122
+ const tokenASymbol: string = 'ETH';
123
+ const tokenBSymbol: string = 'INST';
124
+
125
+ const tokenAAmount: string = '100000000000000';
126
+ const tokenBAmount: string = '100000000000000';
127
+
128
+ testForNetwork(
129
+ network,
130
+ dexKey,
131
+ tokenASymbol,
132
+ tokenBSymbol,
133
+ tokenAAmount,
134
+ tokenBAmount,
135
+ );
136
+ });
137
+
121
138
  describe('ETH -> wstETH', () => {
122
139
  const tokenASymbol: string = 'wstETH';
123
140
  const tokenBSymbol: string = 'ETH';
@@ -10,14 +10,16 @@ import { FluidDexLiquidityProxyState } from './types';
10
10
  import { FluidDexConfig } from './config';
11
11
  import { FluidDexLiquidityProxy } from './fluid-dex-liquidity-proxy';
12
12
  import { FluidDexFactory } from './fluid-dex-factory';
13
+ import { FluidDexEventPool } from './fluid-dex-pool';
14
+ import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
13
15
 
14
16
  jest.setTimeout(50 * 1000);
15
17
 
16
- async function fetchLiquidityProxyState(
17
- liquidityProxy: FluidDexLiquidityProxy,
18
+ async function fetchState(
19
+ statefulEventSubscriber: StatefulEventSubscriber<any>,
18
20
  blockNumber: number,
19
- ): Promise<FluidDexLiquidityProxyState> {
20
- return liquidityProxy.generateState(blockNumber);
21
+ ): Promise<any> {
22
+ return statefulEventSubscriber.generateState(blockNumber);
21
23
  }
22
24
 
23
25
  // eventName -> blockNumbers
@@ -64,7 +66,7 @@ describe('FluidDex EventPool Mainnet', function () {
64
66
  liquidityProxy,
65
67
  liquidityProxy.addressesSubscribed,
66
68
  (_blockNumber: number) =>
67
- fetchLiquidityProxyState(liquidityProxy, _blockNumber),
69
+ fetchState(liquidityProxy, _blockNumber),
68
70
  blockNumber,
69
71
  `${dexKey}_${poolAddress}`,
70
72
  dexHelper.provider,
@@ -126,4 +128,52 @@ describe('FluidDex EventPool Mainnet', function () {
126
128
  },
127
129
  );
128
130
  });
131
+
132
+ describe('Pool events', () => {
133
+ let dexPool: FluidDexEventPool;
134
+
135
+ const eventsToTest: Record<Address, EventMappings> = {
136
+ '0x8710039D5de6840EdE452A85672B32270a709aE2': {
137
+ LogPauseSwapAndArbitrage: [21337128],
138
+ },
139
+ '0x2886a01a0645390872a9eb99dae1283664b0c524': {
140
+ LogPauseSwapAndArbitrage: [21374547],
141
+ },
142
+ };
143
+
144
+ Object.entries(eventsToTest).forEach(
145
+ ([poolAddress, events]: [string, EventMappings]) => {
146
+ describe(`Events for ${poolAddress}`, () => {
147
+ beforeEach(() => {
148
+ dexPool = new FluidDexEventPool(
149
+ dexKey,
150
+ poolAddress,
151
+ network,
152
+ dexHelper,
153
+ logger,
154
+ );
155
+ });
156
+ Object.entries(events).forEach(
157
+ ([eventName, blockNumbers]: [string, number[]]) => {
158
+ describe(`${eventName}`, () => {
159
+ blockNumbers.forEach((blockNumber: number) => {
160
+ it(`State after ${blockNumber}`, async function () {
161
+ await testEventSubscriber(
162
+ dexPool,
163
+ dexPool.addressesSubscribed,
164
+ (_blockNumber: number) =>
165
+ fetchState(dexPool, _blockNumber),
166
+ blockNumber,
167
+ `${dexKey}_${poolAddress}`,
168
+ dexHelper.provider,
169
+ );
170
+ });
171
+ });
172
+ });
173
+ },
174
+ );
175
+ });
176
+ },
177
+ );
178
+ });
129
179
  });
@@ -28,7 +28,7 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu
28
28
 
29
29
  addressesSubscribed: Address[];
30
30
 
31
- protected liquidityIface = new Interface(LiquidityABI);
31
+ readonly liquidityIface = new Interface(LiquidityABI);
32
32
 
33
33
  readonly resolverIface = new Interface(ResolverABI);
34
34
 
@@ -123,7 +123,6 @@ export class FluidDexLiquidityProxy extends StatefulEventSubscriber<FluidDexLiqu
123
123
  });
124
124
 
125
125
  const convertedResult = this.convertToFluidDexPoolState(rawResult);
126
-
127
126
  this.logger.info(`${this.parentName}: ${this.name}: generating state...`);
128
127
 
129
128
  return convertedResult;
@@ -0,0 +1,138 @@
1
+ import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
2
+ import { DeepReadonly } from 'ts-essentials';
3
+ import { Address, Log, Logger } from '../../types';
4
+ import { IDexHelper } from '../../dex-helper';
5
+ import { Interface } from '@ethersproject/abi';
6
+ import FluidDexPoolABI from '../../abi/fluid-dex/fluid-dex.abi.json';
7
+ import { catchParseLogError } from '../../utils';
8
+ import { ethers } from 'ethers';
9
+ import { uint256ToBigInt } from '../../lib/decoders';
10
+ import { DecodedStateMultiCallResultWithRelativeBitmaps } from '../uniswap-v3/types';
11
+
12
+ const {
13
+ utils: { hexlify, hexZeroPad },
14
+ } = ethers;
15
+
16
+ type PoolState = {
17
+ isSwapAndArbitragePaused: boolean;
18
+ };
19
+
20
+ export class FluidDexEventPool extends StatefulEventSubscriber<PoolState> {
21
+ handlers: {
22
+ [event: string]: (
23
+ event: any,
24
+ state: DeepReadonly<PoolState>,
25
+ log: Readonly<Log>,
26
+ ) => DeepReadonly<PoolState> | null;
27
+ } = {};
28
+
29
+ logDecoder: (log: Log) => any;
30
+ addressesSubscribed: Address[];
31
+ protected poolIface = new Interface(FluidDexPoolABI);
32
+
33
+ constructor(
34
+ readonly parentName: string,
35
+ readonly poolAddress: string,
36
+ protected network: number,
37
+ protected dexHelper: IDexHelper,
38
+ logger: Logger,
39
+ ) {
40
+ super(parentName, 'pool', dexHelper, logger);
41
+
42
+ this.logDecoder = (log: Log) => this.poolIface.parseLog(log);
43
+ this.addressesSubscribed = [poolAddress];
44
+
45
+ // Add handlers
46
+ this.handlers['LogPauseSwapAndArbitrage'] =
47
+ this.handleLogPauseSwapAndArbitrage.bind(this);
48
+ this.handlers['LogUnpauseSwapAndArbitrage'] =
49
+ this.handleLogUnpauseSwapAndArbitrage.bind(this);
50
+ }
51
+
52
+ /**
53
+ * The function is called every time any of the subscribed
54
+ * addresses release log. The function accepts the current
55
+ * state, updates the state according to the log, and returns
56
+ * the updated state.
57
+ * @param state - Current state of event subscriber
58
+ * @param log - Log released by one of the subscribed addresses
59
+ * @returns Updates state of the event subscriber after the log
60
+ */
61
+ async processLog(
62
+ state: DeepReadonly<PoolState>,
63
+ log: Readonly<Log>,
64
+ ): Promise<DeepReadonly<PoolState> | null> {
65
+ try {
66
+ let event;
67
+ try {
68
+ event = this.logDecoder(log);
69
+ } catch (e) {
70
+ return null;
71
+ }
72
+
73
+ if (event.name in this.handlers) {
74
+ return this.handlers[event.name](event, state, log);
75
+ }
76
+ } catch (e) {
77
+ catchParseLogError(e, this.logger);
78
+ }
79
+
80
+ return null;
81
+ }
82
+
83
+ handleLogPauseSwapAndArbitrage(): PoolState {
84
+ return { isSwapAndArbitragePaused: true };
85
+ }
86
+
87
+ handleLogUnpauseSwapAndArbitrage(): PoolState {
88
+ return { isSwapAndArbitragePaused: false };
89
+ }
90
+
91
+ async getStateOrGenerate(
92
+ blockNumber: number,
93
+ readonly: boolean = false,
94
+ ): Promise<DeepReadonly<PoolState>> {
95
+ let state = this.getState(blockNumber);
96
+ if (!state) {
97
+ state = await this.generateState(blockNumber);
98
+ if (!readonly) this.setState(state, blockNumber);
99
+ }
100
+ return state;
101
+ }
102
+
103
+ /**
104
+ * The function generates state using on-chain calls. This
105
+ * function is called to regenerate state if the event based
106
+ * system fails to fetch events and the local state is no
107
+ * more correct.
108
+ * @param blockNumber - Blocknumber for which the state should
109
+ * should be generated
110
+ * @returns state of the event subscriber at blocknumber
111
+ */
112
+ async generateState(blockNumber: number): Promise<DeepReadonly<PoolState>> {
113
+ const multicallData = [
114
+ {
115
+ target: this.addressesSubscribed[0],
116
+ callData: this.poolIface.encodeFunctionData('readFromStorage', [
117
+ hexZeroPad(hexlify(1), 32),
118
+ ]),
119
+ decodeFunction: uint256ToBigInt,
120
+ },
121
+ ];
122
+
123
+ const storageResults = await this.dexHelper.multiWrapper.tryAggregate<
124
+ bigint | DecodedStateMultiCallResultWithRelativeBitmaps
125
+ >(
126
+ false,
127
+ multicallData,
128
+ blockNumber,
129
+ this.dexHelper.multiWrapper.defaultBatchSize,
130
+ false,
131
+ );
132
+
133
+ const isSwapAndArbitragePaused =
134
+ BigInt(storageResults[0].returnData.toString()) >> 255n === 1n;
135
+
136
+ return { isSwapAndArbitragePaused };
137
+ }
138
+ }
@@ -34,6 +34,8 @@ import { generalDecoder } from '../../lib/decoders';
34
34
  import { BigNumber } from 'ethers';
35
35
  import { sqrt } from './utils';
36
36
  import { FluidDexLiquidityProxy } from './fluid-dex-liquidity-proxy';
37
+ import { FluidDexEventPool } from './fluid-dex-pool';
38
+ import { MIN_SWAP_LIQUIDITY } from './constants';
37
39
 
38
40
  export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
39
41
  readonly hasConstantPriceLargeAmounts = false;
@@ -46,14 +48,14 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
46
48
 
47
49
  pools: FluidDexPool[] = [];
48
50
 
51
+ eventPools: FluidDexEventPool[] = [];
52
+
49
53
  readonly factory: FluidDexFactory;
50
54
 
51
55
  readonly liquidityProxy: FluidDexLiquidityProxy;
52
56
 
53
57
  readonly fluidDexPoolIface: Interface;
54
58
 
55
- FEE_100_PERCENT = BigInt(1000000);
56
-
57
59
  constructor(
58
60
  readonly network: Network,
59
61
  readonly dexKey: string,
@@ -110,6 +112,20 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
110
112
  await this.factory.initialize(blockNumber);
111
113
  this.pools = await this.fetchFluidDexPools(blockNumber);
112
114
 
115
+ this.eventPools = await Promise.all(
116
+ this.pools.map(async pool => {
117
+ const eventPool = new FluidDexEventPool(
118
+ this.dexKey,
119
+ pool.address,
120
+ this.network,
121
+ this.dexHelper,
122
+ this.logger,
123
+ );
124
+ await eventPool.initialize(blockNumber);
125
+ return eventPool;
126
+ }),
127
+ );
128
+
113
129
  await this.liquidityProxy.initialize(blockNumber);
114
130
  }
115
131
 
@@ -147,29 +163,24 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
147
163
  side: SwapSide,
148
164
  blockNumber: number,
149
165
  ): Promise<string[]> {
150
- const pool = this.getPoolByTokenPair(srcToken.address, destToken.address);
151
- return pool ? [pool.id] : [];
166
+ const pools = this.getPoolsByTokenPair(srcToken.address, destToken.address);
167
+ return pools.map(pool => pool.id);
152
168
  }
153
169
 
154
- getPoolByTokenPair(
155
- srcToken: Address,
156
- destToken: Address,
157
- ): FluidDexPool | null {
170
+ getPoolsByTokenPair(srcToken: Address, destToken: Address): FluidDexPool[] {
158
171
  const srcAddress = srcToken.toLowerCase();
159
172
  const destAddress = destToken.toLowerCase();
160
173
 
161
174
  // A pair must have 2 different tokens.
162
- if (srcAddress === destAddress) return null;
175
+ if (srcAddress === destAddress) return [];
163
176
 
164
- for (const pool of this.pools) {
165
- if (
177
+ const pools = this.pools.filter(
178
+ pool =>
166
179
  (srcAddress === pool.token0 && destAddress === pool.token1) ||
167
- (srcAddress === pool.token1 && destAddress === pool.token0)
168
- ) {
169
- return pool;
170
- }
171
- }
172
- return null;
180
+ (srcAddress === pool.token1 && destAddress === pool.token0),
181
+ );
182
+
183
+ return pools;
173
184
  }
174
185
 
175
186
  // Returns pool prices for amounts.
@@ -187,61 +198,93 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
187
198
  try {
188
199
  if (srcToken.address.toLowerCase() === destToken.address.toLowerCase())
189
200
  return null;
190
- // Get the pool to use.
191
- const pool = this.getPoolByTokenPair(srcToken.address, destToken.address);
192
- if (!pool) return null;
193
- // Make sure the pool meets the optional limitPools filter.
194
- if (limitPools && !limitPools.includes(pool.id)) return null;
201
+
202
+ // Get the pools to use.
203
+ let pools = this.getPoolsByTokenPair(srcToken.address, destToken.address);
204
+
205
+ if (limitPools) {
206
+ pools = pools.filter(pool => limitPools.includes(pool.id));
207
+ }
208
+
209
+ if (!pools.length) return null;
195
210
 
196
211
  const liquidityProxyState = await this.liquidityProxy.getStateOrGenerate(
197
212
  blockNumber,
198
213
  );
199
214
 
200
- const currentPoolReserves = liquidityProxyState.poolsReserves.find(
201
- poolReserve =>
202
- poolReserve.pool.toLowerCase() === pool.address.toLowerCase(),
203
- );
204
- if (!currentPoolReserves) {
205
- return null;
206
- }
207
- const prices = amounts.map(amount => {
208
- if (side === SwapSide.SELL) {
209
- return this.swapIn(
210
- srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
211
- amount,
212
- currentPoolReserves.collateralReserves,
213
- currentPoolReserves.debtReserves,
214
- srcToken.decimals,
215
- destToken.decimals,
216
- BigInt(currentPoolReserves.fee),
217
- currentPoolReserves.dexLimits,
218
- Math.floor(Date.now() / 1000),
215
+ const poolsPrices = await Promise.all(
216
+ pools.map(async pool => {
217
+ const currentPoolReserves = liquidityProxyState.poolsReserves.find(
218
+ poolReserve =>
219
+ poolReserve.pool.toLowerCase() === pool.address.toLowerCase(),
219
220
  );
220
- } else {
221
- return this.swapOut(
222
- srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
223
- amount,
224
- currentPoolReserves.collateralReserves,
225
- currentPoolReserves.debtReserves,
226
- srcToken.decimals,
227
- destToken.decimals,
228
- BigInt(currentPoolReserves.fee),
229
- currentPoolReserves.dexLimits,
230
- Math.floor(Date.now() / 1000),
221
+
222
+ const eventPool = this.eventPools.find(
223
+ eventPool =>
224
+ eventPool.poolAddress.toLowerCase() ===
225
+ pool.address.toLowerCase(),
231
226
  );
232
- }
233
- });
234
- return [
235
- {
236
- prices: prices,
237
- unit: getBigIntPow(destToken.decimals),
238
- data: {},
239
- exchange: this.dexKey,
240
- poolIdentifier: pool.id,
241
- gasCost: FLUID_DEX_GAS_COST,
242
- poolAddresses: [pool.address],
243
- },
244
- ];
227
+
228
+ if (!eventPool) {
229
+ this.logger.warn(
230
+ `${this.dexKey}-${this.network}: Event pool ${pool.address} was not found...`,
231
+ );
232
+ return null;
233
+ }
234
+
235
+ const state = await eventPool.getStateOrGenerate(blockNumber);
236
+
237
+ if (!currentPoolReserves || state.isSwapAndArbitragePaused === true) {
238
+ return null;
239
+ }
240
+
241
+ const prices = amounts.map(amount => {
242
+ if (side === SwapSide.SELL) {
243
+ return this.swapIn(
244
+ srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
245
+ amount,
246
+ currentPoolReserves.collateralReserves,
247
+ currentPoolReserves.debtReserves,
248
+ srcToken.decimals,
249
+ destToken.decimals,
250
+ BigInt(currentPoolReserves.fee),
251
+ currentPoolReserves.dexLimits,
252
+ Math.floor(Date.now() / 1000),
253
+ );
254
+ } else {
255
+ return this.swapOut(
256
+ srcToken.address.toLowerCase() === pool.token0.toLowerCase(),
257
+ amount,
258
+ currentPoolReserves.collateralReserves,
259
+ currentPoolReserves.debtReserves,
260
+ srcToken.decimals,
261
+ destToken.decimals,
262
+ BigInt(currentPoolReserves.fee),
263
+ currentPoolReserves.dexLimits,
264
+ Math.floor(Date.now() / 1000),
265
+ );
266
+ }
267
+ });
268
+
269
+ return {
270
+ prices: prices,
271
+ unit: getBigIntPow(destToken.decimals),
272
+ data: {
273
+ poolId: pool.id,
274
+ },
275
+ exchange: this.dexKey,
276
+ poolIdentifier: pool.id,
277
+ gasCost: FLUID_DEX_GAS_COST,
278
+ poolAddresses: [pool.address],
279
+ };
280
+ }),
281
+ );
282
+
283
+ const notNullResults = poolsPrices.filter(
284
+ res => res !== null,
285
+ ) as ExchangePrices<FluidDexData>;
286
+
287
+ return notNullResults;
245
288
  } catch (e) {
246
289
  this.logger.error(
247
290
  `Error_getPricesVolume ${srcToken.address || srcToken.symbol}, ${
@@ -272,10 +315,9 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
272
315
  ): AdapterExchangeParam {
273
316
  // Encode here the payload for adapter
274
317
  const payload = '';
275
- const pool = this.getPoolByTokenPair(srcToken, destToken);
276
318
 
277
319
  return {
278
- targetExchange: pool!.address,
320
+ targetExchange: '0x',
279
321
  payload,
280
322
  networkFee: '0',
281
323
  };
@@ -313,7 +355,11 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
313
355
  side === SwapSide.SELL ? 'amountOut_' : 'amountIn_',
314
356
  );
315
357
 
316
- const pool = this.getPoolByTokenPair(srcToken, destToken);
358
+ const pool = this.pools.find(pool => pool.id === data.poolId);
359
+ if (!pool)
360
+ throw new Error(
361
+ `${this.dexKey}-${this.network}: Pool with id: ${data.poolId} was not found`,
362
+ );
317
363
 
318
364
  if (side === SwapSide.SELL) {
319
365
  if (pool!.token0.toLowerCase() !== srcToken.toLowerCase()) {
@@ -584,11 +630,84 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
584
630
  if (priceDiff > maxAllowedDiff) {
585
631
  return 0n;
586
632
  }
633
+
634
+ if (amountInCollateral > 0) {
635
+ let reservesRatioValid = swap0To1
636
+ ? this.verifyToken1Reserves(
637
+ colReserveIn + amountInCollateral,
638
+ colReserveOut - amountOutCollateral,
639
+ oldPrice,
640
+ )
641
+ : this.verifyToken0Reserves(
642
+ colReserveOut - amountOutCollateral,
643
+ colReserveIn + amountInCollateral,
644
+ oldPrice,
645
+ );
646
+ if (!reservesRatioValid) {
647
+ return 0n;
648
+ }
649
+ }
650
+
651
+ if (amountInDebt > 0) {
652
+ let reservesRatioValid = swap0To1
653
+ ? this.verifyToken1Reserves(
654
+ debtReserveIn + amountInDebt,
655
+ debtReserveOut - amountOutDebt,
656
+ oldPrice,
657
+ )
658
+ : this.verifyToken0Reserves(
659
+ debtReserveOut - amountOutDebt,
660
+ debtReserveIn + amountInDebt,
661
+ oldPrice,
662
+ );
663
+ if (!reservesRatioValid) {
664
+ return 0n;
665
+ }
666
+ }
667
+
587
668
  const totalAmountOut = amountOutCollateral + amountOutDebt;
588
669
 
589
670
  return totalAmountOut;
590
671
  }
591
672
 
673
+ /**
674
+ * Checks if token0 reserves are sufficient compared to token1 reserves.
675
+ * This helps prevent edge cases and ensures high precision in calculations.
676
+ * @param {number} token0Reserves - The reserves of token0.
677
+ * @param {number} token1Reserves - The reserves of token1.
678
+ * @param {number} price - The current price used for calculation.
679
+ * @returns {boolean} - Returns false if token0 reserves are too low, true otherwise.
680
+ */
681
+ protected verifyToken0Reserves(
682
+ token0Reserves: bigint,
683
+ token1Reserves: bigint,
684
+ price: bigint,
685
+ ): boolean {
686
+ return (
687
+ token0Reserves >=
688
+ (token1Reserves * 10n ** 27n) / (price * MIN_SWAP_LIQUIDITY)
689
+ );
690
+ }
691
+
692
+ /**
693
+ * Checks if token1 reserves are sufficient compared to token0 reserves.
694
+ * This helps prevent edge cases and ensures high precision in calculations.
695
+ * @param {number} token0Reserves - The reserves of token0.
696
+ * @param {number} token1Reserves - The reserves of token1.
697
+ * @param {number} price - The current price used for calculation.
698
+ * @returns {boolean} - Returns false if token1 reserves are too low, true otherwise.
699
+ */
700
+ protected verifyToken1Reserves(
701
+ token0Reserves: bigint,
702
+ token1Reserves: bigint,
703
+ price: bigint,
704
+ ): boolean {
705
+ return (
706
+ token1Reserves >=
707
+ (token0Reserves * price) / (10n ** 27n * MIN_SWAP_LIQUIDITY)
708
+ );
709
+ }
710
+
592
711
  /**
593
712
  * Calculates the currently available swappable amount for a token limit considering expansion since last syncTime.
594
713
  * @param syncTime - timestamp in seconds when the limits were synced
@@ -765,7 +884,7 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
765
884
  syncTime,
766
885
  );
767
886
 
768
- if (amountIn == 2n ** 256n - 1n) {
887
+ if (amountIn === 2n ** 256n - 1n) {
769
888
  return amountIn;
770
889
  }
771
890
  const ans = (amountIn * BigInt(10 ** inDecimals)) / BigInt(10 ** 12);
@@ -985,6 +1104,39 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
985
1104
  return 2n ** 256n - 1n;
986
1105
  }
987
1106
 
1107
+ if (amountInCollateral > 0) {
1108
+ let reservesRatioValid = swap0to1
1109
+ ? this.verifyToken1Reserves(
1110
+ colReserveIn + amountInCollateral,
1111
+ colReserveOut - amountOutCollateral,
1112
+ oldPrice,
1113
+ )
1114
+ : this.verifyToken0Reserves(
1115
+ colReserveOut - amountOutCollateral,
1116
+ colReserveIn + amountInCollateral,
1117
+ oldPrice,
1118
+ );
1119
+ if (!reservesRatioValid) {
1120
+ return 0n;
1121
+ }
1122
+ }
1123
+ if (amountInDebt > 0) {
1124
+ let reservesRatioValid = swap0to1
1125
+ ? this.verifyToken1Reserves(
1126
+ debtReserveIn + amountInDebt,
1127
+ debtReserveOut - amountOutDebt,
1128
+ oldPrice,
1129
+ )
1130
+ : this.verifyToken0Reserves(
1131
+ debtReserveOut - amountOutDebt,
1132
+ debtReserveIn + amountInDebt,
1133
+ oldPrice,
1134
+ );
1135
+ if (!reservesRatioValid) {
1136
+ return 0n;
1137
+ }
1138
+ }
1139
+
988
1140
  const totalAmountIn = amountInCollateral + amountInDebt;
989
1141
 
990
1142
  return totalAmountIn;
@@ -72,7 +72,9 @@ export interface PoolWithReserves {
72
72
  debtReserves: DebtReserves;
73
73
  }
74
74
 
75
- export type FluidDexData = {};
75
+ export type FluidDexData = {
76
+ poolId: string;
77
+ };
76
78
 
77
79
  // Each pool has a contract address and token pairs.
78
80
  export type FluidDexPool = {
@@ -447,7 +447,12 @@ export class GenericRFQ extends ParaSwapLimitOrders {
447
447
  }
448
448
 
449
449
  async setBlacklist(userAddress: string): Promise<boolean> {
450
- return this.rateFetcher.setBlacklist(userAddress);
450
+ await this.dexHelper.cache.hset(
451
+ this.rateFetcher.blackListCacheKey,
452
+ userAddress.toLowerCase(),
453
+ 'true',
454
+ );
455
+ return true;
451
456
  }
452
457
 
453
458
  releaseResources(): void {