@paraswap/dex-lib 2.30.1 → 2.30.2

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 (149) hide show
  1. package/build/abi/uniswap-v3/pancakeswap-v3/PancakeswapV3QuoterV2.abi.json +285 -0
  2. package/build/abi/uniswap-v3/pancakeswap-v3/PancakeswapV3Router.abi.json +583 -0
  3. package/build/abi/woo-fi/WooFeeManager.abi.json +318 -0
  4. package/build/abi/woo-fi/WooPP.abi.json +548 -0
  5. package/build/abi/woo-fi/Wooracle.abi.json +260 -0
  6. package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
  7. package/build/dex/aave-v3/tokens/avalanche.json +74 -0
  8. package/build/dex/aave-v3/tokens/fantom.json +62 -0
  9. package/build/dex/aave-v3/tokens/optimism.json +50 -0
  10. package/build/dex/aave-v3/tokens/polygon.json +116 -0
  11. package/build/dex/balancer-v2/LinearMath.d.ts +19 -0
  12. package/build/dex/balancer-v2/LinearMath.js +179 -0
  13. package/build/dex/balancer-v2/LinearMath.js.map +1 -0
  14. package/build/dex/balancer-v2/LinearPool.d.ts +47 -0
  15. package/build/dex/balancer-v2/LinearPool.js +324 -0
  16. package/build/dex/balancer-v2/LinearPool.js.map +1 -0
  17. package/build/dex/balancer-v2/PhantomStablePool.d.ts +47 -0
  18. package/build/dex/balancer-v2/PhantomStablePool.js +294 -0
  19. package/build/dex/balancer-v2/PhantomStablePool.js.map +1 -0
  20. package/build/dex/balancer-v2/StableMath.d.ts +9 -0
  21. package/build/dex/balancer-v2/StableMath.js +272 -0
  22. package/build/dex/balancer-v2/StableMath.js.map +1 -0
  23. package/build/dex/balancer-v2/balancer-v2-pool.d.ts +75 -0
  24. package/build/dex/balancer-v2/balancer-v2-pool.js +417 -0
  25. package/build/dex/balancer-v2/balancer-v2-pool.js.map +1 -0
  26. package/build/dex/curve-v1-factory/config.js +17 -9
  27. package/build/dex/curve-v1-factory/config.js.map +1 -1
  28. package/build/dex/curve-v1-factory/curve-v1-factory.d.ts +1 -1
  29. package/build/dex/curve-v1-factory/curve-v1-factory.js +192 -177
  30. package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
  31. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js +4 -1
  32. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js.map +1 -1
  33. package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js +1 -0
  34. package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js.map +1 -1
  35. package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js +1 -0
  36. package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js.map +1 -1
  37. package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js +1 -0
  38. package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js.map +1 -1
  39. package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js +1 -0
  40. package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js.map +1 -1
  41. package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js +1 -0
  42. package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js.map +1 -1
  43. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js +73 -1
  44. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js.map +1 -1
  45. package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js +1 -0
  46. package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js.map +1 -1
  47. package/build/dex/curve-v1-factory/price-handlers/functions/constants.js +10 -0
  48. package/build/dex/curve-v1-factory/price-handlers/functions/constants.js.map +1 -1
  49. package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js +1 -0
  50. package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js.map +1 -1
  51. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js +1 -0
  52. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js.map +1 -1
  53. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js +1 -0
  54. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js.map +1 -1
  55. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js +1 -0
  56. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js.map +1 -1
  57. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js +1 -0
  58. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js.map +1 -1
  59. package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js +1 -0
  60. package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js.map +1 -1
  61. package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js +1 -0
  62. package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js.map +1 -1
  63. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.d.ts +1 -1
  64. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js +2 -2
  65. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
  66. package/build/dex/curve-v1-factory/types.d.ts +4 -1
  67. package/build/dex/curve-v1-factory/types.js +1 -0
  68. package/build/dex/curve-v1-factory/types.js.map +1 -1
  69. package/build/dex/quickswap-v3.d.ts +21 -0
  70. package/build/dex/quickswap-v3.js +40 -0
  71. package/build/dex/quickswap-v3.js.map +1 -0
  72. package/build/dex/solidly/forks-override/ramses.js +20 -8
  73. package/build/dex/solidly/forks-override/ramses.js.map +1 -1
  74. package/build/dex/solidly/solidly.js +1 -1
  75. package/build/dex/test-dex/config.d.ts +4 -0
  76. package/build/dex/test-dex/config.js +15 -0
  77. package/build/dex/test-dex/config.js.map +1 -0
  78. package/build/dex/test-dex/test-dex-pool.d.ts +39 -0
  79. package/build/dex/test-dex/test-dex-pool.js +63 -0
  80. package/build/dex/test-dex/test-dex-pool.js.map +1 -0
  81. package/build/dex/test-dex/test-dex.d.ts +37 -0
  82. package/build/dex/test-dex/test-dex.js +126 -0
  83. package/build/dex/test-dex/test-dex.js.map +1 -0
  84. package/build/dex/test-dex/types.d.ts +6 -0
  85. package/build/dex/test-dex/types.js +3 -0
  86. package/build/dex/test-dex/types.js.map +1 -0
  87. package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.d.ts +12 -0
  88. package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.js +23 -0
  89. package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.js.map +1 -0
  90. package/build/dex/uniswap-v3/types.js.map +1 -1
  91. package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
  92. package/build/dex/uniswap-v3/uniswap-v3.js +1 -1
  93. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  94. package/build/dex/woo-fi/config.d.ts +4 -0
  95. package/build/dex/woo-fi/config.js +141 -0
  96. package/build/dex/woo-fi/config.js.map +1 -0
  97. package/build/dex/woo-fi/constants.d.ts +5 -0
  98. package/build/dex/woo-fi/constants.js +20 -0
  99. package/build/dex/woo-fi/constants.js.map +1 -0
  100. package/build/dex/woo-fi/types.d.ts +48 -0
  101. package/build/dex/woo-fi/types.js +3 -0
  102. package/build/dex/woo-fi/types.js.map +1 -0
  103. package/build/dex/woo-fi/woo-fi-decimal-math.d.ts +14 -0
  104. package/build/dex/woo-fi/woo-fi-decimal-math.js +42 -0
  105. package/build/dex/woo-fi/woo-fi-decimal-math.js.map +1 -0
  106. package/build/dex/woo-fi/woo-fi-math.d.ts +31 -0
  107. package/build/dex/woo-fi/woo-fi-math.js +300 -0
  108. package/build/dex/woo-fi/woo-fi-math.js.map +1 -0
  109. package/build/dex/woo-fi/woo-fi.d.ts +65 -0
  110. package/build/dex/woo-fi/woo-fi.js +480 -0
  111. package/build/dex/woo-fi/woo-fi.js.map +1 -0
  112. package/build/dex/woo-fi-v2/woo-fi-math.d.ts +16 -0
  113. package/build/dex/woo-fi-v2/woo-fi-math.js +137 -0
  114. package/build/dex/woo-fi-v2/woo-fi-math.js.map +1 -0
  115. package/package.json +1 -1
  116. package/src/dex/curve-v1-factory/config.ts +17 -9
  117. package/src/dex/curve-v1-factory/curve-v1-factory-e2e.test.ts +19 -0
  118. package/src/dex/curve-v1-factory/curve-v1-factory-integration.test.ts +108 -45
  119. package/src/dex/curve-v1-factory/curve-v1-factory.ts +415 -367
  120. package/src/dex/curve-v1-factory/curve-v1-pool-manager.ts +4 -1
  121. package/src/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.ts +1 -0
  122. package/src/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.ts +1 -0
  123. package/src/dex/curve-v1-factory/price-handlers/functions/_rates.ts +1 -0
  124. package/src/dex/curve-v1-factory/price-handlers/functions/_xp.ts +1 -0
  125. package/src/dex/curve-v1-factory/price-handlers/functions/_xp_mem.ts +1 -0
  126. package/src/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.ts +91 -1
  127. package/src/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.ts +1 -0
  128. package/src/dex/curve-v1-factory/price-handlers/functions/constants.ts +11 -0
  129. package/src/dex/curve-v1-factory/price-handlers/functions/get_D.ts +2 -0
  130. package/src/dex/curve-v1-factory/price-handlers/functions/get_D_mem.ts +1 -0
  131. package/src/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.ts +1 -0
  132. package/src/dex/curve-v1-factory/price-handlers/functions/get_dy.ts +1 -0
  133. package/src/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.ts +1 -0
  134. package/src/dex/curve-v1-factory/price-handlers/functions/get_y.ts +1 -0
  135. package/src/dex/curve-v1-factory/price-handlers/functions/get_y_D.ts +1 -0
  136. package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +2 -1
  137. package/src/dex/curve-v1-factory/types.ts +3 -1
  138. package/src/dex/solidly/forks-override/ramses.ts +105 -76
  139. package/src/dex/solidly/solidly.ts +1 -1
  140. package/src/dex/uniswap-v3/types.ts +4 -2
  141. package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +50 -46
  142. package/src/dex/uniswap-v3/uniswap-v3-integration.test.ts +2 -15
  143. package/src/dex/uniswap-v3/uniswap-v3-pool.ts +5 -2
  144. package/src/dex/uniswap-v3/uniswap-v3.ts +1 -1
  145. package/tests/constants-e2e.ts +10 -0
  146. package/build/abi/algebra/AlgebraPool.abi.json +0 -727
  147. package/build/dex/algebra/algebra-pool.d.ts +0 -46
  148. package/build/dex/algebra/algebra-pool.js +0 -336
  149. package/build/dex/algebra/algebra-pool.js.map +0 -1
@@ -127,7 +127,7 @@ export class CurveV1Factory
127
127
  private coinsTypeTemplate: AbiItem = DefaultCoinsABI,
128
128
  ) {
129
129
  super(dexHelper, dexKey);
130
- this.logger = dexHelper.getLogger(dexKey);
130
+ this.logger = dexHelper.getLogger(`${this.dexKey}-${this.network}`);
131
131
  this.ifaces = {
132
132
  exchangeRouter: new Interface(CurveABI),
133
133
  factory: new Interface(FactoryCurveV1ABI as JsonFragment[]),
@@ -185,6 +185,7 @@ export class CurveV1Factory
185
185
  }
186
186
 
187
187
  async initializeCustomPollingPools(
188
+ factoryAddresses: string[],
188
189
  blockNumber?: number,
189
190
  // We don't want to initialize state for PoolTracker. It doesn't make any sense
190
191
  initializeInitialState: boolean = true,
@@ -193,131 +194,144 @@ export class CurveV1Factory
193
194
  return;
194
195
  }
195
196
 
196
- const { factoryAddress } = this.config;
197
- if (!factoryAddress) {
198
- this.logger.warn(
199
- `${this.dexKey}: No factory address specified for ${this.network}`,
200
- );
201
- return;
202
- }
203
-
204
197
  await Promise.all(
205
- Object.values(this.config.customPools).map(async customPool => {
206
- const poolIdentifier = this.getPoolIdentifier(
207
- customPool.address,
208
- false,
209
- );
210
-
211
- const poolContextConstants = ImplementationConstants[customPool.name];
212
- const {
213
- N_COINS: nCoins,
214
- USE_LENDING: useLending,
215
- isLending,
216
- } = poolContextConstants;
217
-
218
- const coinsAndImplementations =
219
- await this.dexHelper.multiWrapper.aggregate(
220
- _.range(0, nCoins)
221
- .map(i => ({
222
- target: customPool.address,
223
- callData: this.abiCoder.encodeFunctionCall(
224
- this._getCoinsABI(customPool.coinsInputType),
225
- [i.toString()],
226
- ),
227
- decodeFunction: addressDecode,
228
- }))
229
- .concat([
230
- {
231
- target: factoryAddress,
232
- callData: this.ifaces.factory.encodeFunctionData(
233
- 'get_implementation_address',
234
- [customPool.address],
235
- ),
236
- decodeFunction: addressDecode,
237
- },
238
- ]),
239
- );
240
- const COINS = coinsAndImplementations.slice(0, -1);
241
- const implementationAddress = coinsAndImplementations.slice(-1)[0];
242
-
243
- const coins_decimals = (
244
- await this.dexHelper.multiWrapper.tryAggregate(
245
- true,
246
- COINS.map(c => ({
247
- target: c,
248
- callData: this.ifaces.erc20.encodeFunctionData('decimals', []),
249
- decodeFunction: uint8ToNumber,
250
- })),
251
- )
252
- ).map(r => r.returnData);
253
-
254
- const poolConstants: PoolConstants = {
255
- COINS,
256
- coins_decimals,
257
- rate_multipliers: this._calcRateMultipliers(coins_decimals),
258
- lpTokenAddress: customPool.lpTokenAddress,
259
- };
260
-
261
- let newPool: PoolPollingBase;
262
- if (
263
- Object.values<ImplementationNames>(
264
- CustomImplementationNames,
265
- ).includes(customPool.name)
266
- ) {
267
- // We don't want custom pools to be used for pricing, unless explicitly specified
268
- newPool = new CustomBasePoolForFactory(
269
- this.logger,
270
- this.dexKey,
271
- this.dexHelper.config.data.network,
272
- this.cacheStateKey,
273
- customPool.name,
274
- implementationAddress,
275
- customPool.address,
276
- this.config.stateUpdatePeriodMs,
277
- poolIdentifier,
278
- poolConstants,
279
- poolContextConstants,
280
- customPool.liquidityApiSlug,
281
- customPool.lpTokenAddress,
282
- isLending,
283
- customPool.balancesInputType,
284
- useLending,
285
- customPool.useForPricing,
286
- );
287
- } else {
288
- // Use for pricing pools from factory
289
- newPool = new CustomBasePoolForFactory(
290
- this.logger,
291
- this.dexKey,
292
- this.dexHelper.config.data.network,
293
- this.cacheStateKey,
294
- customPool.name,
295
- implementationAddress,
296
- customPool.address,
297
- this.config.stateUpdatePeriodMs,
298
- poolIdentifier,
299
- poolConstants,
300
- poolContextConstants,
301
- customPool.liquidityApiSlug,
302
- customPool.lpTokenAddress,
303
- isLending,
304
- customPool.balancesInputType,
305
- useLending,
306
- true,
198
+ factoryAddresses.map(async factoryAddress => {
199
+ try {
200
+ await Promise.all(
201
+ Object.values(this.config.customPools).map(async customPool => {
202
+ const poolIdentifier = this.getPoolIdentifier(
203
+ customPool.address,
204
+ false,
205
+ );
206
+
207
+ const poolContextConstants =
208
+ ImplementationConstants[customPool.name];
209
+ const {
210
+ N_COINS: nCoins,
211
+ USE_LENDING: useLending,
212
+ isLending,
213
+ } = poolContextConstants;
214
+
215
+ const coinsAndImplementations =
216
+ await this.dexHelper.multiWrapper.aggregate(
217
+ _.range(0, nCoins)
218
+ .map(i => ({
219
+ target: customPool.address,
220
+ callData: this.abiCoder.encodeFunctionCall(
221
+ this._getCoinsABI(customPool.coinsInputType),
222
+ [i.toString()],
223
+ ),
224
+ decodeFunction: addressDecode,
225
+ }))
226
+ .concat([
227
+ {
228
+ target: factoryAddress,
229
+ callData: this.ifaces.factory.encodeFunctionData(
230
+ 'get_implementation_address',
231
+ [customPool.address],
232
+ ),
233
+ decodeFunction: addressDecode,
234
+ },
235
+ ]),
236
+ );
237
+ const COINS = coinsAndImplementations.slice(0, -1);
238
+ const implementationAddress =
239
+ coinsAndImplementations.slice(-1)[0];
240
+
241
+ const coins_decimals = (
242
+ await this.dexHelper.multiWrapper.tryAggregate(
243
+ true,
244
+ COINS.map(c => ({
245
+ target: c,
246
+ callData: this.ifaces.erc20.encodeFunctionData(
247
+ 'decimals',
248
+ [],
249
+ ),
250
+ decodeFunction: uint8ToNumber,
251
+ })),
252
+ )
253
+ ).map(r => r.returnData);
254
+
255
+ const poolConstants: PoolConstants = {
256
+ COINS,
257
+ coins_decimals,
258
+ rate_multipliers: this._calcRateMultipliers(coins_decimals),
259
+ lpTokenAddress: customPool.lpTokenAddress,
260
+ };
261
+
262
+ let newPool: PoolPollingBase;
263
+ if (
264
+ Object.values<ImplementationNames>(
265
+ CustomImplementationNames,
266
+ ).includes(customPool.name)
267
+ ) {
268
+ // We don't want custom pools to be used for pricing, unless explicitly specified
269
+ newPool = new CustomBasePoolForFactory(
270
+ this.logger,
271
+ this.dexKey,
272
+ this.dexHelper.config.data.network,
273
+ this.cacheStateKey,
274
+ customPool.name,
275
+ implementationAddress,
276
+ customPool.address,
277
+ this.config.stateUpdatePeriodMs,
278
+ poolIdentifier,
279
+ poolConstants,
280
+ poolContextConstants,
281
+ customPool.liquidityApiSlug,
282
+ customPool.lpTokenAddress,
283
+ isLending,
284
+ customPool.balancesInputType,
285
+ useLending,
286
+ customPool.useForPricing,
287
+ );
288
+ } else {
289
+ // Use for pricing pools from factory
290
+ newPool = new CustomBasePoolForFactory(
291
+ this.logger,
292
+ this.dexKey,
293
+ this.dexHelper.config.data.network,
294
+ this.cacheStateKey,
295
+ customPool.name,
296
+ implementationAddress,
297
+ customPool.address,
298
+ this.config.stateUpdatePeriodMs,
299
+ poolIdentifier,
300
+ poolConstants,
301
+ poolContextConstants,
302
+ customPool.liquidityApiSlug,
303
+ customPool.lpTokenAddress,
304
+ isLending,
305
+ customPool.balancesInputType,
306
+ useLending,
307
+ true,
308
+ );
309
+ }
310
+
311
+ this.poolManager.initializeNewPoolForState(
312
+ poolIdentifier,
313
+ newPool,
314
+ );
315
+
316
+ if (initializeInitialState) {
317
+ await this.poolManager.initializeIndividualPollingPoolState(
318
+ poolIdentifier,
319
+ CustomBasePoolForFactory.IS_SRC_FEE_ON_TRANSFER_SUPPORTED,
320
+ blockNumber,
321
+ );
322
+ }
323
+ }),
307
324
  );
308
- }
309
-
310
- this.poolManager.initializeNewPoolForState(poolIdentifier, newPool);
311
-
312
- if (initializeInitialState) {
313
- await this.poolManager.initializeIndividualPollingPoolState(
314
- poolIdentifier,
315
- CustomBasePoolForFactory.IS_SRC_FEE_ON_TRANSFER_SUPPORTED,
316
- blockNumber,
325
+ } catch (e) {
326
+ this.logger.error(
327
+ `Error initializing custom polling pools for factory ${factoryAddress}: `,
328
+ e,
317
329
  );
330
+ throw e;
318
331
  }
319
332
  }),
320
333
  );
334
+
321
335
  this.areCustomPoolsFetched = true;
322
336
  }
323
337
 
@@ -332,277 +346,311 @@ export class CurveV1Factory
332
346
  return;
333
347
  }
334
348
 
349
+ if (
350
+ !this.config.factoryAddresses ||
351
+ this.config.factoryAddresses.length == 0
352
+ ) {
353
+ this.logger.warn(`No factory address specified in configs`);
354
+ return;
355
+ }
356
+
335
357
  // There is no scenario when we need to call initialize custom pools without factory pools
336
358
  // So I put it here to not forget call, because custom pools must be initialised before factory pools
337
359
  // This function may be called multiple times, but will execute only once
338
360
  await this.initializeCustomPollingPools(
361
+ this.config.factoryAddresses,
339
362
  blockNumber,
340
363
  initializeInitialState,
341
364
  );
342
365
 
343
- const { factoryAddress } = this.config;
344
- if (!factoryAddress) {
345
- this.logger.warn(
346
- `${this.dexKey}: No factory address specified for ${this.network}`,
347
- );
348
- return;
349
- }
350
-
351
- const poolCountResult = await this.dexHelper.multiWrapper!.tryAggregate(
352
- true,
353
- [
354
- {
355
- target: factoryAddress,
356
- callData: this.ifaces.factory.encodeFunctionData('pool_count'),
357
- decodeFunction: uint256DecodeToNumber,
358
- },
359
- // This is used later to request all available implementations. In particular meta implementations
360
- {
361
- target: factoryAddress,
362
- callData: this.ifaces.factory.encodeFunctionData('base_pool_count'),
363
- decodeFunction: uint256DecodeToNumber,
364
- },
365
- ],
366
- );
367
-
368
- const poolCount = poolCountResult[0].returnData;
369
- const basePoolCount = poolCountResult[1].returnData;
370
-
371
- const calldataGetPoolAddresses = _.range(0, poolCount).map(i => ({
372
- target: factoryAddress,
373
- callData: this.ifaces.factory.encodeFunctionData('pool_list', [i]),
374
- decodeFunction: addressDecode,
375
- }));
376
-
377
- const calldataGetBasePoolAddresses = _.range(0, basePoolCount).map(i => ({
378
- target: factoryAddress,
379
- callData: this.ifaces.factory.encodeFunctionData('base_pool_list', [i]),
380
- decodeFunction: addressDecode,
381
- }));
382
-
383
- const allPoolAddresses = (
384
- await this.dexHelper.multiWrapper.tryAggregate(
385
- true,
386
- calldataGetPoolAddresses.concat(calldataGetBasePoolAddresses),
387
- )
388
- ).map(e => e.returnData);
389
-
390
- const poolAddresses = allPoolAddresses.slice(0, poolCount);
391
- const basePoolAddresses = allPoolAddresses.slice(poolCount);
392
-
393
- const customPoolAddresses = Object.values(this.config.customPools).map(
394
- customPool => customPool.address,
395
- );
396
- basePoolAddresses.forEach(basePool => {
397
- if (
398
- !customPoolAddresses.includes(basePool) &&
399
- !this.config.disabledPools.has(basePool)
400
- ) {
401
- this._reportForUnspecifiedCustomPool(basePool);
402
- }
403
- });
404
-
405
- let callDataFromFactoryPools: MultiCallParams<
406
- string[] | number[] | string
407
- >[] = poolAddresses
408
- .map(p => [
409
- {
410
- target: factoryAddress,
411
- callData: this.ifaces.factory.encodeFunctionData(
412
- 'get_implementation_address',
413
- [p],
414
- ),
415
- decodeFunction: addressDecode,
416
- },
417
- {
418
- target: factoryAddress,
419
- callData: this.ifaces.factory.encodeFunctionData('get_coins', [p]),
420
- decodeFunction: (
421
- result: MultiResult<BytesLike> | BytesLike,
422
- ): string[] =>
423
- generalDecoder<string[]>(
424
- result,
425
- ['address[4]'],
426
- new Array(4).fill(NULL_ADDRESS),
427
- parsed => parsed[0].map((p: string) => p.toLowerCase()),
428
- ),
429
- },
430
- {
431
- target: factoryAddress,
432
- callData: this.ifaces.factory.encodeFunctionData('get_decimals', [p]),
433
- decodeFunction: (
434
- result: MultiResult<BytesLike> | BytesLike,
435
- ): number[] =>
436
- generalDecoder<number[]>(
437
- result,
438
- ['uint256[4]'],
439
- [0, 0, 0, 0],
440
- parsed => parsed[0].map((p: BigNumber) => Number(p.toString())),
441
- ),
442
- },
443
- ])
444
- .flat();
445
-
446
- // This is divider between pools related results and implementations
447
- const factoryResultsDivider = callDataFromFactoryPools.length;
448
-
449
- // Implementations must be requested from factory, but it accepts as arg basePool address
450
- // for metaPools
451
- callDataFromFactoryPools = callDataFromFactoryPools.concat(
452
- ...basePoolAddresses.map(basePoolAddress => ({
453
- target: factoryAddress,
454
- callData: this.ifaces.factory.encodeFunctionData(
455
- 'metapool_implementations',
456
- [basePoolAddress],
457
- ),
458
- decodeFunction: (
459
- result: MultiResult<BytesLike> | BytesLike,
460
- ): string[] =>
461
- generalDecoder<string[]>(
462
- result,
463
- ['address[10]'],
464
- new Array(10).fill(NULL_ADDRESS),
465
- parsed => parsed[0].map((p: string) => p.toLowerCase()),
466
- ),
467
- })),
468
- // To receive plain pool implementation address, you have to call plain_implementations
469
- // with two variables: N_COINS and implementations_index
470
- // N_COINS is between 2-4. Currently more than 4 coins is not supported
471
- // as for implementation index, there are only 0-9 indexes
472
- ..._.flattenDeep(
473
- _.range(2, FACTORY_MAX_PLAIN_COINS + 1).map(coinNumber =>
474
- _.range(FACTORY_MAX_PLAIN_IMPLEMENTATIONS_FOR_COIN).map(implInd => ({
366
+ await Promise.all(
367
+ this.config.factoryAddresses.map(async factoryAddress => {
368
+ try {
369
+ const poolCountResult =
370
+ await this.dexHelper.multiWrapper!.tryAggregate(true, [
371
+ {
372
+ target: factoryAddress,
373
+ callData: this.ifaces.factory.encodeFunctionData('pool_count'),
374
+ decodeFunction: uint256DecodeToNumber,
375
+ },
376
+ // This is used later to request all available implementations. In particular meta implementations
377
+ {
378
+ target: factoryAddress,
379
+ callData:
380
+ this.ifaces.factory.encodeFunctionData('base_pool_count'),
381
+ decodeFunction: uint256DecodeToNumber,
382
+ },
383
+ ]);
384
+
385
+ const poolCount = poolCountResult[0].returnData;
386
+ const basePoolCount = poolCountResult[1].returnData;
387
+
388
+ const calldataGetPoolAddresses = _.range(0, poolCount).map(i => ({
475
389
  target: factoryAddress,
476
- callData: this.ifaces.factory.encodeFunctionData(
477
- 'plain_implementations',
478
- [coinNumber, implInd],
479
- ),
390
+ callData: this.ifaces.factory.encodeFunctionData('pool_list', [i]),
480
391
  decodeFunction: addressDecode,
481
- })),
482
- ),
483
- ),
484
- );
392
+ }));
393
+
394
+ const calldataGetBasePoolAddresses = _.range(0, basePoolCount).map(
395
+ i => ({
396
+ target: factoryAddress,
397
+ callData: this.ifaces.factory.encodeFunctionData(
398
+ 'base_pool_list',
399
+ [i],
400
+ ),
401
+ decodeFunction: addressDecode,
402
+ }),
403
+ );
485
404
 
486
- const allResultsFromFactory = (
487
- await this.dexHelper.multiWrapper.tryAggregate<
488
- string[] | number[] | string
489
- >(true, callDataFromFactoryPools)
490
- ).map(r => r.returnData);
405
+ const allPoolAddresses = (
406
+ await this.dexHelper.multiWrapper.tryAggregate(
407
+ true,
408
+ calldataGetPoolAddresses.concat(calldataGetBasePoolAddresses),
409
+ )
410
+ ).map(e => e.returnData);
411
+
412
+ const poolAddresses = allPoolAddresses.slice(0, poolCount);
413
+ const basePoolAddresses = allPoolAddresses.slice(poolCount);
414
+
415
+ const customPoolAddresses = Object.values(
416
+ this.config.customPools,
417
+ ).map(customPool => customPool.address);
418
+ basePoolAddresses.forEach(basePool => {
419
+ if (
420
+ !customPoolAddresses.includes(basePool) &&
421
+ !this.config.disabledPools.has(basePool)
422
+ ) {
423
+ this._reportForUnspecifiedCustomPool(basePool);
424
+ }
425
+ });
491
426
 
492
- const resultsFromFactory = allResultsFromFactory.slice(
493
- 0,
494
- factoryResultsDivider,
495
- );
427
+ let callDataFromFactoryPools: MultiCallParams<
428
+ string[] | number[] | string
429
+ >[] = poolAddresses
430
+ .map(p => [
431
+ {
432
+ target: factoryAddress,
433
+ callData: this.ifaces.factory.encodeFunctionData(
434
+ 'get_implementation_address',
435
+ [p],
436
+ ),
437
+ decodeFunction: addressDecode,
438
+ },
439
+ {
440
+ target: factoryAddress,
441
+ callData: this.ifaces.factory.encodeFunctionData('get_coins', [
442
+ p,
443
+ ]),
444
+ decodeFunction: (
445
+ result: MultiResult<BytesLike> | BytesLike,
446
+ ): string[] =>
447
+ generalDecoder<string[]>(
448
+ result,
449
+ ['address[4]'],
450
+ new Array(4).fill(NULL_ADDRESS),
451
+ parsed => parsed[0].map((p: string) => p.toLowerCase()),
452
+ ),
453
+ },
454
+ {
455
+ target: factoryAddress,
456
+ callData: this.ifaces.factory.encodeFunctionData(
457
+ 'get_decimals',
458
+ [p],
459
+ ),
460
+ decodeFunction: (
461
+ result: MultiResult<BytesLike> | BytesLike,
462
+ ): number[] =>
463
+ generalDecoder<number[]>(
464
+ result,
465
+ ['uint256[4]'],
466
+ [0, 0, 0, 0],
467
+ parsed =>
468
+ parsed[0].map((p: BigNumber) => Number(p.toString())),
469
+ ),
470
+ },
471
+ ])
472
+ .flat();
473
+
474
+ // This is divider between pools related results and implementations
475
+ const factoryResultsDivider = callDataFromFactoryPools.length;
476
+
477
+ // Implementations must be requested from factory, but it accepts as arg basePool address
478
+ // for metaPools
479
+ callDataFromFactoryPools = callDataFromFactoryPools.concat(
480
+ ...basePoolAddresses.map(basePoolAddress => ({
481
+ target: factoryAddress,
482
+ callData: this.ifaces.factory.encodeFunctionData(
483
+ 'metapool_implementations',
484
+ [basePoolAddress],
485
+ ),
486
+ decodeFunction: (
487
+ result: MultiResult<BytesLike> | BytesLike,
488
+ ): string[] =>
489
+ generalDecoder<string[]>(
490
+ result,
491
+ ['address[10]'],
492
+ new Array(10).fill(NULL_ADDRESS),
493
+ parsed => parsed[0].map((p: string) => p.toLowerCase()),
494
+ ),
495
+ })),
496
+ // To receive plain pool implementation address, you have to call plain_implementations
497
+ // with two variables: N_COINS and implementations_index
498
+ // N_COINS is between 2-4. Currently more than 4 coins is not supported
499
+ // as for implementation index, there are only 0-9 indexes
500
+ ..._.flattenDeep(
501
+ _.range(2, FACTORY_MAX_PLAIN_COINS + 1).map(coinNumber =>
502
+ _.range(FACTORY_MAX_PLAIN_IMPLEMENTATIONS_FOR_COIN).map(
503
+ implInd => ({
504
+ target: factoryAddress,
505
+ callData: this.ifaces.factory.encodeFunctionData(
506
+ 'plain_implementations',
507
+ [coinNumber, implInd],
508
+ ),
509
+ decodeFunction: addressDecode,
510
+ }),
511
+ ),
512
+ ),
513
+ ),
514
+ );
496
515
 
497
- const allAvailableImplementations = _.flattenDeep(
498
- allResultsFromFactory.slice(factoryResultsDivider) as string[],
499
- ).filter(
500
- implementation =>
501
- implementation !== NULL_ADDRESS &&
502
- !this.config.disabledImplementations.has(implementation),
503
- );
516
+ const allResultsFromFactory = (
517
+ await this.dexHelper.multiWrapper.tryAggregate<
518
+ string[] | number[] | string
519
+ >(true, callDataFromFactoryPools)
520
+ ).map(r => r.returnData);
504
521
 
505
- allAvailableImplementations.forEach(implementation => {
506
- const currentImplementation =
507
- this.config.factoryPoolImplementations[implementation];
508
- if (currentImplementation === undefined) {
509
- this._reportForUnspecifiedImplementation(implementation);
510
- }
511
- });
522
+ const resultsFromFactory = allResultsFromFactory.slice(
523
+ 0,
524
+ factoryResultsDivider,
525
+ );
512
526
 
513
- const stateInitializePromises: Promise<void>[] = [];
514
- _.chunk(resultsFromFactory, 3).forEach((result, i) => {
515
- if (this.config.disabledPools.has(poolAddresses[i])) {
516
- this.logger.trace(`Filtering disabled pool ${poolAddresses[i]}`);
517
- return;
518
- }
527
+ const allAvailableImplementations = _.flattenDeep(
528
+ allResultsFromFactory.slice(factoryResultsDivider) as string[],
529
+ ).filter(
530
+ implementation =>
531
+ implementation !== NULL_ADDRESS &&
532
+ !this.config.disabledImplementations.has(implementation),
533
+ );
519
534
 
520
- let [implementationAddress, coins, coins_decimals] = result as [
521
- string,
522
- string[],
523
- number[],
524
- ];
535
+ allAvailableImplementations.forEach(implementation => {
536
+ const currentImplementation =
537
+ this.config.factoryPoolImplementations[implementation];
538
+ if (currentImplementation === undefined) {
539
+ this._reportForUnspecifiedImplementation(implementation);
540
+ }
541
+ });
525
542
 
526
- implementationAddress = implementationAddress.toLowerCase();
527
- coins = coins.map(c => c.toLowerCase()).filter(c => c !== NULL_ADDRESS);
528
- coins_decimals = coins_decimals.filter(cd => cd !== 0);
543
+ const stateInitializePromises: Promise<void>[] = [];
544
+ _.chunk(resultsFromFactory, 3).forEach((result, i) => {
545
+ if (this.config.disabledPools.has(poolAddresses[i])) {
546
+ this.logger.trace(`Filtering disabled pool ${poolAddresses[i]}`);
547
+ return;
548
+ }
549
+
550
+ let [implementationAddress, coins, coins_decimals] = result as [
551
+ string,
552
+ string[],
553
+ number[],
554
+ ];
555
+
556
+ implementationAddress = implementationAddress.toLowerCase();
557
+ coins = coins
558
+ .map(c => c.toLowerCase())
559
+ .filter(c => c !== NULL_ADDRESS);
560
+ coins_decimals = coins_decimals.filter(cd => cd !== 0);
561
+
562
+ const factoryImplementationFromConfig =
563
+ this.config.factoryPoolImplementations[implementationAddress];
564
+
565
+ if (
566
+ factoryImplementationFromConfig === undefined &&
567
+ !this.config.disabledImplementations.has(implementationAddress)
568
+ ) {
569
+ this._reportForUnspecifiedImplementation(
570
+ implementationAddress,
571
+ poolAddresses[i],
572
+ );
573
+ return;
574
+ }
575
+
576
+ const factoryImplementationConstants =
577
+ ImplementationConstants[factoryImplementationFromConfig.name];
578
+
579
+ let isMeta: boolean = false;
580
+ let basePoolStateFetcher: PoolPollingBase | undefined;
581
+ if (factoryImplementationFromConfig.basePoolAddress !== undefined) {
582
+ isMeta = true;
583
+ const basePoolIdentifier = this.getPoolIdentifier(
584
+ factoryImplementationFromConfig.basePoolAddress,
585
+ false,
586
+ );
587
+ const basePool = this.poolManager.getPool(
588
+ basePoolIdentifier,
589
+ false,
590
+ );
591
+ if (basePool === null) {
592
+ this.logger.error(
593
+ `${this.dexKey}_${this.dexHelper.config.data.network}: custom base pool ${basePoolIdentifier} was not initialized properly. ` +
594
+ `You must call initializeCustomPollingPools before fetching factory`,
595
+ );
596
+ return;
597
+ }
598
+ basePoolStateFetcher = basePool;
599
+ }
600
+
601
+ const poolConstants: PoolConstants = {
602
+ COINS: coins,
603
+ coins_decimals,
604
+ rate_multipliers: this._calcRateMultipliers(coins_decimals),
605
+ };
606
+
607
+ const poolIdentifier = this.getPoolIdentifier(
608
+ poolAddresses[i],
609
+ isMeta,
610
+ );
529
611
 
530
- const factoryImplementationFromConfig =
531
- this.config.factoryPoolImplementations[implementationAddress];
612
+ const newPool = new FactoryStateHandler(
613
+ this.logger,
614
+ this.dexKey,
615
+ this.dexHelper.config.data.network,
616
+ this.cacheStateKey,
617
+ factoryImplementationFromConfig.name,
618
+ implementationAddress.toLowerCase(),
619
+ poolAddresses[i],
620
+ this.config.stateUpdatePeriodMs,
621
+ factoryAddress,
622
+ poolIdentifier,
623
+ poolConstants,
624
+ factoryImplementationConstants,
625
+ factoryImplementationConstants.isFeeOnTransferSupported,
626
+ factoryImplementationFromConfig.liquidityApiSlug ?? '/factory',
627
+ basePoolStateFetcher,
628
+ factoryImplementationFromConfig.customGasCost,
629
+ factoryImplementationFromConfig.isStoreRateSupported,
630
+ );
532
631
 
533
- if (
534
- factoryImplementationFromConfig === undefined &&
535
- !this.config.disabledImplementations.has(implementationAddress)
536
- ) {
537
- this._reportForUnspecifiedImplementation(
538
- implementationAddress,
539
- poolAddresses[i],
540
- );
541
- return;
542
- }
632
+ this.poolManager.initializeNewPool(poolIdentifier, newPool);
543
633
 
544
- const factoryImplementationConstants =
545
- ImplementationConstants[factoryImplementationFromConfig.name];
634
+ if (initializeInitialState) {
635
+ stateInitializePromises.push(
636
+ this.poolManager.initializeIndividualPollingPoolState(
637
+ poolIdentifier,
638
+ factoryImplementationConstants.isFeeOnTransferSupported,
639
+ ),
640
+ );
641
+ }
642
+ });
546
643
 
547
- let isMeta: boolean = false;
548
- let basePoolStateFetcher: PoolPollingBase | undefined;
549
- if (factoryImplementationFromConfig.basePoolAddress !== undefined) {
550
- isMeta = true;
551
- const basePoolIdentifier = this.getPoolIdentifier(
552
- factoryImplementationFromConfig.basePoolAddress,
553
- false,
554
- );
555
- const basePool = this.poolManager.getPool(basePoolIdentifier, false);
556
- if (basePool === null) {
644
+ await Promise.all(stateInitializePromises);
645
+ } catch (e) {
557
646
  this.logger.error(
558
- `${this.dexKey}_${this.dexHelper.config.data.network}: custom base pool ${basePoolIdentifier} was not initialized properly. ` +
559
- `You must call initializeCustomPollingPools before fetching factory`,
647
+ `Error fetching factory pools for ${factoryAddress}: `,
648
+ e,
560
649
  );
561
- return;
650
+ throw e;
562
651
  }
563
- basePoolStateFetcher = basePool;
564
- }
565
-
566
- const poolConstants: PoolConstants = {
567
- COINS: coins,
568
- coins_decimals,
569
- rate_multipliers: this._calcRateMultipliers(coins_decimals),
570
- };
571
-
572
- const poolIdentifier = this.getPoolIdentifier(poolAddresses[i], isMeta);
573
-
574
- const newPool = new FactoryStateHandler(
575
- this.logger,
576
- this.dexKey,
577
- this.dexHelper.config.data.network,
578
- this.cacheStateKey,
579
- factoryImplementationFromConfig.name,
580
- implementationAddress.toLowerCase(),
581
- poolAddresses[i],
582
- this.config.stateUpdatePeriodMs,
583
- factoryAddress,
584
- poolIdentifier,
585
- poolConstants,
586
- factoryImplementationConstants,
587
- factoryImplementationConstants.isFeeOnTransferSupported,
588
- basePoolStateFetcher,
589
- factoryImplementationFromConfig.customGasCost,
590
- factoryImplementationFromConfig.isStoreRateSupported,
591
- );
592
-
593
- this.poolManager.initializeNewPool(poolIdentifier, newPool);
594
-
595
- if (initializeInitialState) {
596
- stateInitializePromises.push(
597
- this.poolManager.initializeIndividualPollingPoolState(
598
- poolIdentifier,
599
- factoryImplementationConstants.isFeeOnTransferSupported,
600
- ),
601
- );
602
- }
603
- });
604
-
605
- await Promise.all(stateInitializePromises);
652
+ }),
653
+ );
606
654
 
607
655
  this.areFactoryPoolsFetched = true;
608
656
  }