@paraswap/dex-lib 2.50.6-sdai → 2.50.7-sdai

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/build/config.js +4 -2
  2. package/build/config.js.map +1 -1
  3. package/build/dex/algebra/config.js +0 -16
  4. package/build/dex/algebra/config.js.map +1 -1
  5. package/build/dex/curve-v1-factory/config.js +128 -11
  6. package/build/dex/curve-v1-factory/config.js.map +1 -1
  7. package/build/dex/curve-v1-factory/curve-v1-factory.d.ts +1 -0
  8. package/build/dex/curve-v1-factory/curve-v1-factory.js +29 -17
  9. package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
  10. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js +1 -0
  11. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js.map +1 -1
  12. package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js +1 -0
  13. package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js.map +1 -1
  14. package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js +4 -1
  15. package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js.map +1 -1
  16. package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js +1 -0
  17. package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js.map +1 -1
  18. package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js +1 -0
  19. package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js.map +1 -1
  20. package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js +1 -0
  21. package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js.map +1 -1
  22. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js +1 -0
  23. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js.map +1 -1
  24. package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js +1 -0
  25. package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js.map +1 -1
  26. package/build/dex/curve-v1-factory/price-handlers/functions/constants.js +10 -0
  27. package/build/dex/curve-v1-factory/price-handlers/functions/constants.js.map +1 -1
  28. package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js +40 -0
  29. package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js.map +1 -1
  30. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js +1 -0
  31. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js.map +1 -1
  32. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js +1 -0
  33. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js.map +1 -1
  34. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js +24 -0
  35. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js.map +1 -1
  36. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js +1 -0
  37. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js.map +1 -1
  38. package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js +53 -0
  39. package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js.map +1 -1
  40. package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js +1 -0
  41. package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js.map +1 -1
  42. package/build/dex/curve-v1-factory/price-handlers/functions/utils.d.ts +1 -0
  43. package/build/dex/curve-v1-factory/price-handlers/functions/utils.js +5 -1
  44. package/build/dex/curve-v1-factory/price-handlers/functions/utils.js.map +1 -1
  45. package/build/dex/curve-v1-factory/price-handlers/types.d.ts +2 -2
  46. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.d.ts +3 -2
  47. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js +38 -6
  48. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
  49. package/build/dex/curve-v1-factory/state-polling-pools/pool-polling-base.js.map +1 -1
  50. package/build/dex/curve-v1-factory/types.d.ts +11 -2
  51. package/build/dex/curve-v1-factory/types.js +3 -0
  52. package/build/dex/curve-v1-factory/types.js.map +1 -1
  53. package/build/dex/dexalot/config.js +7 -0
  54. package/build/dex/dexalot/config.js.map +1 -1
  55. package/build/dex/hashflow/constants.d.ts +27 -0
  56. package/build/dex/hashflow/constants.js +29 -1
  57. package/build/dex/hashflow/constants.js.map +1 -1
  58. package/build/dex/hashflow/hashflow.d.ts +3 -2
  59. package/build/dex/hashflow/hashflow.js +69 -12
  60. package/build/dex/hashflow/hashflow.js.map +1 -1
  61. package/build/dex/hashflow/types.d.ts +11 -0
  62. package/build/dex/hashflow/types.js +9 -0
  63. package/build/dex/hashflow/types.js.map +1 -1
  64. package/build/dex/idex.d.ts +1 -1
  65. package/build/dex/index.d.ts +2 -2
  66. package/build/dex/pancakeswap-v3/config.js +30 -0
  67. package/build/dex/pancakeswap-v3/config.js.map +1 -1
  68. package/build/dex/pancakeswap-v3/pancakeswap-v3.js +5 -1
  69. package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +1 -1
  70. package/build/dex/woo-fi-v2/config.js +4 -4
  71. package/package.json +1 -1
  72. package/src/config.ts +4 -2
  73. package/src/dex/algebra/config.ts +0 -18
  74. package/src/dex/curve-v1-factory/config.ts +128 -11
  75. package/src/dex/curve-v1-factory/curve-v1-factory-e2e.test.ts +123 -1
  76. package/src/dex/curve-v1-factory/curve-v1-factory-integration.test.ts +392 -0
  77. package/src/dex/curve-v1-factory/curve-v1-factory.ts +61 -39
  78. package/src/dex/curve-v1-factory/curve-v1-pool-manager.ts +1 -0
  79. package/src/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.ts +2 -0
  80. package/src/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.ts +6 -2
  81. package/src/dex/curve-v1-factory/price-handlers/functions/_rates.ts +2 -0
  82. package/src/dex/curve-v1-factory/price-handlers/functions/_xp.ts +2 -0
  83. package/src/dex/curve-v1-factory/price-handlers/functions/_xp_mem.ts +2 -0
  84. package/src/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.ts +2 -0
  85. package/src/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.ts +2 -0
  86. package/src/dex/curve-v1-factory/price-handlers/functions/constants.ts +11 -0
  87. package/src/dex/curve-v1-factory/price-handlers/functions/get_D.ts +59 -1
  88. package/src/dex/curve-v1-factory/price-handlers/functions/get_D_mem.ts +2 -0
  89. package/src/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.ts +2 -0
  90. package/src/dex/curve-v1-factory/price-handlers/functions/get_dy.ts +51 -0
  91. package/src/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.ts +2 -0
  92. package/src/dex/curve-v1-factory/price-handlers/functions/get_y.ts +68 -1
  93. package/src/dex/curve-v1-factory/price-handlers/functions/get_y_D.ts +2 -0
  94. package/src/dex/curve-v1-factory/price-handlers/functions/utils.ts +4 -0
  95. package/src/dex/curve-v1-factory/price-handlers/types.ts +8 -1
  96. package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +71 -18
  97. package/src/dex/curve-v1-factory/state-polling-pools/pool-polling-base.ts +1 -0
  98. package/src/dex/curve-v1-factory/types.ts +12 -1
  99. package/src/dex/dexalot/config.ts +7 -0
  100. package/src/dex/dexalot/dexalot-e2e.test.ts +23 -1
  101. package/src/dex/dexalot/dexalot-integration.test.ts +121 -0
  102. package/src/dex/hashflow/constants.ts +32 -0
  103. package/src/dex/hashflow/hashflow.ts +121 -19
  104. package/src/dex/hashflow/types.ts +20 -2
  105. package/src/dex/idex.ts +1 -1
  106. package/src/dex/index.ts +2 -2
  107. package/src/dex/pancakeswap-v3/config.ts +32 -0
  108. package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +21 -0
  109. package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +7 -1
  110. package/src/dex/woo-fi-v2/config.ts +4 -4
  111. package/tests/constants-e2e.ts +38 -3
  112. package/tests/utils-e2e.ts +1 -0
  113. package/src/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
@@ -185,4 +185,125 @@ describe('Dexalot', function () {
185
185
  }
186
186
  });
187
187
  });
188
+
189
+ describe('Arbitrum', () => {
190
+ const network = Network.ARBITRUM;
191
+ const dexHelper = new DummyDexHelper(network);
192
+
193
+ const tokens = Tokens[network];
194
+
195
+ const tokenASymbol = 'USDT';
196
+ const tokenBSymbol = 'USDC';
197
+
198
+ const amountsForTokenA = [
199
+ 0n,
200
+ 1n * BI_POWS[tokens[tokenASymbol].decimals],
201
+ 2n * BI_POWS[tokens[tokenASymbol].decimals],
202
+ 3n * BI_POWS[tokens[tokenASymbol].decimals],
203
+ 4n * BI_POWS[tokens[tokenASymbol].decimals],
204
+ 5n * BI_POWS[tokens[tokenASymbol].decimals],
205
+ 6n * BI_POWS[tokens[tokenASymbol].decimals],
206
+ 7n * BI_POWS[tokens[tokenASymbol].decimals],
207
+ 8n * BI_POWS[tokens[tokenASymbol].decimals],
208
+ 9n * BI_POWS[tokens[tokenASymbol].decimals],
209
+ 10n * BI_POWS[tokens[tokenASymbol].decimals],
210
+ ];
211
+
212
+ const amountsForTokenB = [
213
+ 0n,
214
+ 1n * BI_POWS[tokens[tokenBSymbol].decimals],
215
+ 2n * BI_POWS[tokens[tokenBSymbol].decimals],
216
+ 3n * BI_POWS[tokens[tokenBSymbol].decimals],
217
+ 4n * BI_POWS[tokens[tokenBSymbol].decimals],
218
+ 5n * BI_POWS[tokens[tokenBSymbol].decimals],
219
+ 6n * BI_POWS[tokens[tokenBSymbol].decimals],
220
+ 7n * BI_POWS[tokens[tokenBSymbol].decimals],
221
+ 8n * BI_POWS[tokens[tokenBSymbol].decimals],
222
+ 9n * BI_POWS[tokens[tokenBSymbol].decimals],
223
+ 10n * BI_POWS[tokens[tokenBSymbol].decimals],
224
+ ];
225
+
226
+ beforeEach(async () => {
227
+ blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
228
+ dexalot = new Dexalot(network, dexKey, dexHelper);
229
+ await dexalot.initializePricing(blockNumber);
230
+ await sleep(5000);
231
+ });
232
+
233
+ afterEach(async () => {
234
+ dexalot.releaseResources();
235
+ await sleep(5000);
236
+ });
237
+
238
+ it(`getPoolIdentifiers and getPricesVolume SELL ${tokenASymbol} ${tokenBSymbol}`, async function () {
239
+ await testPricingOnNetwork(
240
+ dexalot,
241
+ network,
242
+ dexKey,
243
+ blockNumber,
244
+ tokenASymbol,
245
+ tokenBSymbol,
246
+ SwapSide.SELL,
247
+ amountsForTokenA,
248
+ );
249
+ });
250
+
251
+ it(`getPoolIdentifiers and getPricesVolume BUY ${tokenASymbol} ${tokenBSymbol}`, async function () {
252
+ await testPricingOnNetwork(
253
+ dexalot,
254
+ network,
255
+ dexKey,
256
+ blockNumber,
257
+ tokenASymbol,
258
+ tokenBSymbol,
259
+ SwapSide.BUY,
260
+ amountsForTokenB,
261
+ );
262
+ });
263
+
264
+ it(`getPoolIdentifiers and getPricesVolume SELL ${tokenBSymbol} ${tokenASymbol}`, async function () {
265
+ await testPricingOnNetwork(
266
+ dexalot,
267
+ network,
268
+ dexKey,
269
+ blockNumber,
270
+ tokenBSymbol,
271
+ tokenASymbol,
272
+ SwapSide.SELL,
273
+ amountsForTokenB,
274
+ );
275
+ });
276
+
277
+ it(`getPoolIdentifiers and getPricesVolume BUY ${tokenBSymbol} ${tokenASymbol}`, async function () {
278
+ await testPricingOnNetwork(
279
+ dexalot,
280
+ network,
281
+ dexKey,
282
+ blockNumber,
283
+ tokenBSymbol,
284
+ tokenASymbol,
285
+ SwapSide.BUY,
286
+ amountsForTokenA,
287
+ );
288
+ });
289
+
290
+ it('getTopPoolsForToken', async function () {
291
+ // We have to check without calling initializePricing, because
292
+ // pool-tracker is not calling that function
293
+ const dexalot = new Dexalot(network, dexKey, dexHelper);
294
+ const poolLiquidity = await dexalot.getTopPoolsForToken(
295
+ tokens[tokenASymbol].address,
296
+ 10,
297
+ );
298
+ console.log(`${tokenASymbol} Top Pools:`, poolLiquidity);
299
+
300
+ if (!dexalot.hasConstantPriceLargeAmounts) {
301
+ checkPoolsLiquidity(
302
+ poolLiquidity,
303
+ Tokens[network][tokenASymbol].address,
304
+ dexKey,
305
+ );
306
+ }
307
+ });
308
+ });
188
309
  });
@@ -20,3 +20,35 @@ export const HASHFLOW_GAS_COST = 100_000;
20
20
 
21
21
  export const HASHFLOW_MIN_SLIPPAGE_FACTOR_THRESHOLD_FOR_RESTRICTION =
22
22
  new BigNumber('0.001');
23
+
24
+ export const RESTRICT_79_TTL_MS = 60 * 30 * 1000; // 30 mins
25
+ export const RESTRICT_SLIPPAGE_TTL_MS = 60 * 30 * 1000; // 30 mins
26
+ export const RESTRICT_84_TTL_MS = 60 * 10 * 1000; // 10 mins
27
+ export const RESTRICT_76_TTL_MS = 60 * 30 * 1000; // 30 mins
28
+ export const RESTRICT_82_TTL_MS = 60 * 30 * 1000; // 30 mins
29
+ export const RESTRICT_42_TTL_MS = 60 * 60 * 1000; // 60 mins
30
+ export const RESTRICT_85_TTL_MS = 60 * 20 * 1000; // 20 mins
31
+ export const RESTRICT_74_TTL_MS = 60 * 20 * 1000; // 20 mins
32
+ export const RESTRICT_UNKNOWN_TTL_MS = 60 * 60 * 1000; // 60 mins
33
+ export const RESTRICT_MISSING_QUOTE_DATA_TTL_MS = 60 * 10 * 1000; // 10 mins
34
+ export const RESTRICT_MISSING_SIGNATURE_TTL_MS = 60 * 10 * 1000; // 10 mins
35
+
36
+ export const UNKNOWN_ERROR_CODE = 'UNKNOWN';
37
+
38
+ export const ERROR_CODE_TO_RESTRICT_TTL = {
39
+ '79': RESTRICT_79_TTL_MS, // {"code":79,"message":"Below minimum amount"}
40
+ SLIPPAGE: RESTRICT_SLIPPAGE_TTL_MS, // Error: Hashflow-56: too much slippage on quote SELL quoteTokenAmount 800317519410129900 / destAmount 848781022570196154 < 0.995
41
+ '84': RESTRICT_84_TTL_MS, // {"code":84,"message":"Rate Limit"}
42
+ '76': RESTRICT_76_TTL_MS, // {"code":76,"message":"Exceeds supported amounts"}
43
+ '82': RESTRICT_82_TTL_MS, // {"code":82,"message":"No maker supports this request"}
44
+ '42': RESTRICT_42_TTL_MS, // {"code":42,"message":"Unknown error"}
45
+ '85': RESTRICT_85_TTL_MS, // {"code":85,"message":"Markets too volatile"}
46
+ '74': RESTRICT_74_TTL_MS, // {"code":74,"message":"No maker could quote"}
47
+ MISSING_QUOTE_DATA: RESTRICT_MISSING_QUOTE_DATA_TTL_MS, // missing quote data
48
+ MISSING_SIGNATURE_DATA: RESTRICT_MISSING_SIGNATURE_TTL_MS, // missing signature
49
+ [UNKNOWN_ERROR_CODE]: RESTRICT_UNKNOWN_TTL_MS, // unknown error
50
+ };
51
+
52
+ // not actually consecutive, meaning is if the error appeared > CONSECUTIVE_ERROR_THRESHOLD times within CONSECUTIVE_ERROR_TIMESPAN_MS ms -> restrict mm for ERROR_CODE_TO_RESTRICT_TTL[errorCode] ms
53
+ export const CONSECUTIVE_ERROR_TIMESPAN_MS = 60 * 60 * 1000; // 1 hour
54
+ export const CONSECUTIVE_ERROR_THRESHOLD = 3;
@@ -33,11 +33,14 @@ import {
33
33
  SimpleExchangeParam,
34
34
  Token,
35
35
  } from '../../types';
36
- import { getDexKeysWithNetwork } from '../../utils';
36
+ import { getDexKeysWithNetwork, Utils } from '../../utils';
37
37
  import { TooStrictSlippageCheckError } from '../generic-rfq/types';
38
38
  import { SimpleExchange } from '../simple-exchange';
39
39
  import { Adapters, HashflowConfig } from './config';
40
40
  import {
41
+ CONSECUTIVE_ERROR_THRESHOLD,
42
+ CONSECUTIVE_ERROR_TIMESPAN_MS,
43
+ ERROR_CODE_TO_RESTRICT_TTL,
41
44
  HASHFLOW_API_CLIENT_NAME,
42
45
  HASHFLOW_API_MARKET_MAKERS_POLLING_INTERVAL_MS,
43
46
  HASHFLOW_API_PRICES_POLLING_INTERVAL_MS,
@@ -48,9 +51,12 @@ import {
48
51
  HASHFLOW_MIN_SLIPPAGE_FACTOR_THRESHOLD_FOR_RESTRICTION,
49
52
  HASHFLOW_MM_RESTRICT_TTL_S,
50
53
  HASHFLOW_PRICES_CACHES_TTL_S,
54
+ UNKNOWN_ERROR_CODE,
51
55
  } from './constants';
52
56
  import { RateFetcher } from './rate-fetcher';
53
57
  import {
58
+ CacheErrorCodesData,
59
+ ErrorCode,
54
60
  HashflowData,
55
61
  PriceLevel,
56
62
  RfqError,
@@ -69,6 +75,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
69
75
  private hashFlowAuthToken: string;
70
76
  private disabledMMs: Set<string>;
71
77
  private runtimeMMsRestrictHashMapKey: string;
78
+ private runtimeMMsRestrictHashMapErrorCodesKey: string;
72
79
 
73
80
  private pricesCacheKey: string;
74
81
  private marketMakersCacheKey: string;
@@ -108,6 +115,8 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
108
115
  this.disabledMMs = new Set(dexHelper.config.data.hashFlowDisabledMMs);
109
116
  this.runtimeMMsRestrictHashMapKey =
110
117
  `${CACHE_PREFIX}_${this.dexKey}_${this.network}_restricted_mms`.toLowerCase();
118
+ this.runtimeMMsRestrictHashMapErrorCodesKey =
119
+ `${CACHE_PREFIX}_${this.dexKey}_${this.network}_restricted_mms_error_codes`.toLowerCase();
111
120
 
112
121
  this.rateFetcher = new RateFetcher(
113
122
  this.dexHelper,
@@ -595,7 +604,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
595
604
  normalizedDestToken.address,
596
605
  )}: ${JSON.stringify(rfq)}`;
597
606
  this.logger.warn(message);
598
- throw new RfqError(message);
607
+ throw new RfqError(message, `${rfq?.error?.code}` as ErrorCode);
599
608
  } else if (!rfq.quotes[0].quoteData) {
600
609
  const message = `${this.dexKey}-${
601
610
  this.network
@@ -604,7 +613,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
604
613
  normalizedDestToken.address,
605
614
  )}. Missing quote data`;
606
615
  this.logger.warn(message);
607
- throw new RfqError(message);
616
+ throw new RfqError(message, 'MISSING_QUOTE_DATA');
608
617
  } else if (!rfq.quotes[0].signature) {
609
618
  const message = `${this.dexKey}-${
610
619
  this.network
@@ -613,7 +622,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
613
622
  normalizedDestToken.address,
614
623
  )}. Missing signature`;
615
624
  this.logger.warn(message);
616
- throw new RfqError(message);
625
+ throw new RfqError(message, 'MISSING_SIGNATURE_DATA');
617
626
  }
618
627
 
619
628
  assert(
@@ -729,7 +738,13 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
729
738
  this.logger.warn(
730
739
  `${this.dexKey}-${this.network} MM unknown preprocess transaction error: ${e}`,
731
740
  );
732
- await this.restrictMM(mm);
741
+ const code =
742
+ e instanceof RfqError || e instanceof SlippageCheckError
743
+ ? e?.code || UNKNOWN_ERROR_CODE
744
+ : UNKNOWN_ERROR_CODE;
745
+ await this.restrictMM(mm, code).catch(err =>
746
+ this.logger.warn(`Failed to restrict MM ${mm}: ${err}`),
747
+ );
733
748
  }
734
749
  }
735
750
 
@@ -737,24 +752,111 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
737
752
  }
738
753
  }
739
754
 
740
- async restrictMM(mm: string): Promise<void> {
741
- this.logger.warn(
742
- `${this.dexKey}-${this.network}: ${mm} was restricted for ${HASHFLOW_MM_RESTRICT_TTL_S} sec. due to fails`,
743
- );
744
-
745
- // We use timestamp for creation date to later discern if it already expired or not
746
- await this.dexHelper.cache.hset(
747
- this.runtimeMMsRestrictHashMapKey,
755
+ async restrictMM(mm: string, errorCode: ErrorCode): Promise<void> {
756
+ const errorCodesRaw = await this.dexHelper.cache.hget(
757
+ this.runtimeMMsRestrictHashMapErrorCodesKey,
748
758
  mm,
749
- Date.now().toString(),
750
759
  );
751
760
 
752
- // Expiry cache because it has levels for blacklisted MM
753
- this.dexHelper.cache.del(this.dexKey, this.network, 'levels').catch(e => {
754
- this.logger.error(
755
- `${this.dexKey}-${this.network}: Failed to delete levels cache: ${e.message}`,
761
+ const errorCodes: CacheErrorCodesData = Utils.Parse(errorCodesRaw) || {};
762
+
763
+ const error = errorCodes?.[errorCode];
764
+
765
+ if (
766
+ !error ||
767
+ error.addedDatetimeMS + CONSECUTIVE_ERROR_TIMESPAN_MS < Date.now()
768
+ ) {
769
+ this.logger.warn(
770
+ `${this.dexKey}-${this.network}: First encounter of error code=${errorCode} for ${mm} OR error ocurred outside of threshold, setting up counter`,
756
771
  );
757
- });
772
+ const data: CacheErrorCodesData = {
773
+ ...errorCodes,
774
+ [errorCode]: {
775
+ count: 1,
776
+ addedDatetimeMS: Date.now(),
777
+ },
778
+ };
779
+ await this.dexHelper.cache.hset(
780
+ this.runtimeMMsRestrictHashMapErrorCodesKey,
781
+ mm,
782
+ Utils.Serialize(data),
783
+ );
784
+ return;
785
+ } else {
786
+ const restrictTTLMs =
787
+ ERROR_CODE_TO_RESTRICT_TTL[errorCode] ||
788
+ ERROR_CODE_TO_RESTRICT_TTL[UNKNOWN_ERROR_CODE];
789
+
790
+ if (error.count + 1 > CONSECUTIVE_ERROR_THRESHOLD) {
791
+ this.logger.warn(
792
+ `${this.dexKey}-${this.network}: ${mm} was restricted for ${
793
+ restrictTTLMs / 1000
794
+ } sec. due to ${errorCode} happening ${
795
+ error.count + 1
796
+ } times within last ${Math.floor(
797
+ CONSECUTIVE_ERROR_TIMESPAN_MS / 1000 / 60,
798
+ )} minutes`,
799
+ );
800
+
801
+ // date added is checked against HASHFLOW_MM_RESTRICT_TTL_S, as a hack we set a date so that it's checked against specific ttls based on error type to not change parsing logic for mms
802
+ //
803
+ // Example1: ttl for a particular error is 20 minutes (< default 60 minutes)
804
+ // Meaning we need to set `addedDatetimeMS` for restrict hash as Date.now() - 40 minutes (diff between default restrict ttl=1h and particular error restrict ttl = 20 minutes). So the `addedDatetimeMS` is in the past, and after 20 minutes mm will not be considered as restricted
805
+ //
806
+ // Example 2: ttl for a particular error is 80 minutes (> default 60 minutes)
807
+ // Meaning we need to set `addedDatetimeMS` for restrict hash as Date.now() + 20 minutes (in the future), then after an hour (default) it'll still be 20 minutes left for restriction to be cleared
808
+
809
+ const defaultRestrictTTLMS = Math.floor(
810
+ HASHFLOW_MM_RESTRICT_TTL_S * 1000,
811
+ );
812
+ const dateModifierMS =
813
+ defaultRestrictTTLMS > restrictTTLMs
814
+ ? -(defaultRestrictTTLMS - restrictTTLMs)
815
+ : restrictTTLMs - defaultRestrictTTLMS;
816
+
817
+ const date = (Date.now() + dateModifierMS).toString();
818
+
819
+ // We use timestamp for creation date to later discern if it already expired or not
820
+ await this.dexHelper.cache.hset(
821
+ this.runtimeMMsRestrictHashMapKey,
822
+ mm,
823
+ date,
824
+ );
825
+
826
+ // resetting error count
827
+ const data: CacheErrorCodesData = {
828
+ ...errorCodes,
829
+ [errorCode]: {
830
+ count: 1,
831
+ addedDatetimeMS: Date.now(),
832
+ },
833
+ };
834
+ await this.dexHelper.cache.hset(
835
+ this.runtimeMMsRestrictHashMapErrorCodesKey,
836
+ mm,
837
+ Utils.Serialize(data),
838
+ );
839
+
840
+ return;
841
+ } else {
842
+ const newCount = +error.count + 1;
843
+ this.logger.warn(
844
+ `${this.dexKey}-${this.network}: ${mm} Error with code: ${errorCode} happened ${newCount} times (below or equal to the limit: ${CONSECUTIVE_ERROR_THRESHOLD}), updating counter`,
845
+ );
846
+ const data: CacheErrorCodesData = {
847
+ ...errorCodes,
848
+ [errorCode]: {
849
+ count: newCount,
850
+ addedDatetimeMS: error.addedDatetimeMS, // initial date stays
851
+ },
852
+ };
853
+ await this.dexHelper.cache.hset(
854
+ this.runtimeMMsRestrictHashMapErrorCodesKey,
855
+ mm,
856
+ Utils.Serialize(data),
857
+ );
858
+ }
859
+ }
758
860
  }
759
861
 
760
862
  getCalldataGasCost(poolPrices: PoolPrices<HashflowData>): number | number[] {
@@ -1,5 +1,6 @@
1
1
  import { Chain, QuoteData } from '@hashflow/taker-js/dist/types/common';
2
2
  import { RequestHeaders } from '../../dex-helper';
3
+ import { ERROR_CODE_TO_RESTRICT_TTL, UNKNOWN_ERROR_CODE } from './constants';
3
4
 
4
5
  export type HashflowData = {
5
6
  mm: string;
@@ -16,14 +17,22 @@ export interface PriceLevel {
16
17
  p: string;
17
18
  }
18
19
 
19
- export class RfqError extends Error {}
20
+ export class RfqError extends Error {
21
+ code: ErrorCode;
22
+ constructor(message: string, code: ErrorCode = UNKNOWN_ERROR_CODE) {
23
+ super(message);
24
+ this.code = code;
25
+ }
26
+ }
20
27
 
21
28
  export enum RFQType {
22
29
  RFQT = 0,
23
30
  RFQM = 1,
24
31
  }
25
32
 
26
- export class SlippageCheckError extends Error {}
33
+ export class SlippageCheckError extends Error {
34
+ code: ErrorCode = 'SLIPPAGE';
35
+ }
27
36
 
28
37
  export type HashflowRatesLevel = {
29
38
  pair: Record<string, string>;
@@ -63,3 +72,12 @@ export type HashflowRateFetcherConfig = {
63
72
  marketMakersCacheTTLSecs: number;
64
73
  };
65
74
  };
75
+
76
+ export type ErrorCode = keyof typeof ERROR_CODE_TO_RESTRICT_TTL;
77
+
78
+ export type CacheErrorCodesData = {
79
+ [code in ErrorCode]: {
80
+ addedDatetimeMS: number;
81
+ count: number;
82
+ } | null;
83
+ };
package/src/dex/idex.ts CHANGED
@@ -194,7 +194,7 @@ export interface IDex<
194
194
  IDexPooltracker {}
195
195
 
196
196
  // Defines the static objects of the IDex class
197
- export interface DexContructor<
197
+ export interface DexConstructor<
198
198
  ExchangeData,
199
199
  DirectParam = null,
200
200
  OptimizedExchangeData = ExchangeData,
package/src/dex/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import { UnoptimizedRate } from '../types';
3
3
  import { CurveV2 } from './curve-v2';
4
- import { IDexTxBuilder, DexContructor, IDex, IRouteOptimizer } from './idex';
4
+ import { IDexTxBuilder, DexConstructor, IDex, IRouteOptimizer } from './idex';
5
5
  import { Jarvis } from './jarvis';
6
6
  import { JarvisV6 } from './jarvis-v6/jarvis-v6';
7
7
  import { StablePool } from './stable-pool';
@@ -185,7 +185,7 @@ interface IGetDirectFunctionName {
185
185
 
186
186
  export class DexAdapterService {
187
187
  dexToKeyMap: {
188
- [key: string]: LegacyDexConstructor | DexContructor<any, any, any>;
188
+ [key: string]: LegacyDexConstructor | DexConstructor<any, any, any>;
189
189
  } = {};
190
190
  directFunctionsNames: string[];
191
191
  dexInstances: {
@@ -69,6 +69,38 @@ export const PancakeswapV3Config: DexConfigMap<DexParams> = {
69
69
  'https://api.studio.thegraph.com/query/45376/exchange-v3-base/version/latest',
70
70
  },
71
71
  },
72
+ DackieSwapV3: {
73
+ [Network.BASE]: {
74
+ factory: '0x3D237AC6D2f425D2E890Cc99198818cc1FA48870',
75
+ quoter: '0x4fDBD73aD4B1DDde594BF05497C15f76308eFfb9',
76
+ deployer: '0x4f205D69834f9B101b9289F7AFFAc9B77B3fF9b7',
77
+ router: '0x4030ebafeb76e5fc848891076dfe315993800ba5',
78
+ supportedFees: [10000n, 2500n, 500n, 100n],
79
+ stateMulticall: '0xeBF40A40CA3D4310Bf53048F48e860656e1D7C81',
80
+ uniswapMulticall: '0x091e99cb1C49331a94dD62755D168E941AbD0693',
81
+ chunksCount: 10,
82
+ initRetryFrequency: 10,
83
+ initHash: `0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2`,
84
+ subgraphURL:
85
+ 'https://api.studio.thegraph.com/query/50473/exchange-clmm/version/latest',
86
+ },
87
+ },
88
+ SwapBasedV3: {
89
+ [Network.BASE]: {
90
+ factory: '0xb5620f90e803c7f957a9ef351b8db3c746021bea',
91
+ quoter: '0x4fDBD73aD4B1DDde594BF05497C15f76308eFfb9',
92
+ deployer: '0x905a650133147012390c42624eeba4d3313bec6c',
93
+ router: '0x756c6bbdd915202adac7bebb1c6c89ac0886503f',
94
+ supportedFees: [10000n, 2500n, 500n, 100n, 35n],
95
+ stateMulticall: '0xeBF40A40CA3D4310Bf53048F48e860656e1D7C81',
96
+ uniswapMulticall: '0x091e99cb1C49331a94dD62755D168E941AbD0693',
97
+ chunksCount: 10,
98
+ initRetryFrequency: 10,
99
+ initHash: `0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2`,
100
+ subgraphURL:
101
+ 'https://api.studio.thegraph.com/query/67101/swapbased-pcsv3-core/version/latest',
102
+ },
103
+ },
72
104
  };
73
105
 
74
106
  export const Adapters: Record<number, AdapterMappings> = {
@@ -421,4 +421,25 @@ describe('PancakeswapV3 E2E', () => {
421
421
  nativeTokenAmount,
422
422
  );
423
423
  });
424
+
425
+ describe('SwapBasedV3 Base', () => {
426
+ const network = Network.BASE;
427
+
428
+ const tokenASymbol: string = 'USDbC';
429
+ const tokenBSymbol: string = 'USDC';
430
+
431
+ const tokenAAmount: string = '11111000000';
432
+ const tokenBAmount: string = '11111000000';
433
+ const nativeTokenAmount = '110000000000000000000';
434
+
435
+ testForNetwork(
436
+ network,
437
+ 'SwapBasedV3',
438
+ tokenASymbol,
439
+ tokenBSymbol,
440
+ tokenAAmount,
441
+ tokenBAmount,
442
+ nativeTokenAmount,
443
+ );
444
+ });
424
445
  });
@@ -87,7 +87,13 @@ export class PancakeswapV3
87
87
  intervalTask?: NodeJS.Timeout;
88
88
 
89
89
  public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
90
- getDexKeysWithNetwork(_.pick(PancakeswapV3Config, ['PancakeswapV3']));
90
+ getDexKeysWithNetwork(
91
+ _.pick(PancakeswapV3Config, [
92
+ 'PancakeswapV3',
93
+ 'DackieSwapV3',
94
+ 'SwapBasedV3',
95
+ ]),
96
+ );
91
97
 
92
98
  logger: Logger;
93
99
 
@@ -15,8 +15,8 @@ export const WooFiV2Config: DexConfigMap<DexParams> = {
15
15
  },
16
16
  },
17
17
  [Network.BSC]: {
18
- wooPPV2Address: '0x59dE3B49314Bf5067719364A2Cb43e8525ab93FA',
19
- wooOracleV2Address: '0x72dc7fa5eeb901a34173C874A7333c8d1b34bca9',
18
+ wooPPV2Address: '0xEd9e3f98bBed560e66B89AaC922E29D4596A9642',
19
+ wooOracleV2Address: '0x2A375567f5E13F6bd74fDa7627Df3b1Af6BfA5a6',
20
20
  integrationHelperAddress: '0xAA9c15cd603428cA8ddD45e933F8EfE3Afbcc173',
21
21
  // USDT
22
22
  quoteToken: {
@@ -55,8 +55,8 @@ export const WooFiV2Config: DexConfigMap<DexParams> = {
55
55
  },
56
56
  },
57
57
  [Network.AVALANCHE]: {
58
- wooPPV2Address: '0x3b3E4b4741e91aF52d0e9ad8660573E951c88524',
59
- wooOracleV2Address: '0xc13843aE0D2C5ca9E0EfB93a78828446D8173d19',
58
+ wooPPV2Address: '0xEd9e3f98bBed560e66B89AaC922E29D4596A9642',
59
+ wooOracleV2Address: '0x2A375567f5E13F6bd74fDa7627Df3b1Af6BfA5a6',
60
60
  integrationHelperAddress: '0x020630613E296c3E9b06186f630D1bF97A2B6Ad1',
61
61
  // USDC
62
62
  quoteToken: {
@@ -327,6 +327,10 @@ export const Tokens: {
327
327
  address: '0x40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f',
328
328
  decimals: 18,
329
329
  },
330
+ USDe: {
331
+ address: '0x4c9EDD5852cd905f086C759E8383e09bff1E68B3',
332
+ decimals: 18,
333
+ },
330
334
  crvUSD: {
331
335
  address: '0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E',
332
336
  decimals: 18,
@@ -368,12 +372,16 @@ export const Tokens: {
368
372
  address: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063',
369
373
  decimals: 18,
370
374
  },
371
- USDC: {
375
+ USDCe: {
372
376
  address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
373
377
  decimals: 6,
374
378
  addBalance: _balancesFn,
375
379
  addAllowance: _allowancesFn,
376
380
  },
381
+ USDC: {
382
+ address: '0x576Cf361711cd940CD9C397BB98C4C896cBd38De',
383
+ decimals: 6,
384
+ },
377
385
  POPS: {
378
386
  address: '0xa92A1576D11dB45c53be71d59245ac97ce0d8147',
379
387
  decimals: 18,
@@ -382,6 +390,10 @@ export const Tokens: {
382
390
  address: '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619',
383
391
  decimals: 18,
384
392
  },
393
+ crvUSD: {
394
+ address: '0xc4ce1d6f5d98d65ee25cf85e9f2e9dcfee6cb5d6',
395
+ decimals: 18,
396
+ },
385
397
  WMATIC: {
386
398
  address: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
387
399
  decimals: 18,
@@ -584,6 +596,14 @@ export const Tokens: {
584
596
  address: '0x2f733095b80a04b38b0d10cc884524a3d09b836a',
585
597
  decimals: 6,
586
598
  },
599
+ scrvUSDC_e: {
600
+ address: '0x0cf1aa18ab7020973705aa9c46bbec6150e2782b',
601
+ decimals: 18,
602
+ },
603
+ scrvUSDC_p: {
604
+ address: '0x8b697f95d8c9fbbcc597a89223b10b80369490a1',
605
+ decimals: 18,
606
+ },
587
607
  },
588
608
  [Network.BSC]: {
589
609
  POPS: {
@@ -855,6 +875,10 @@ export const Tokens: {
855
875
  address: '0xaf88d065e77c8cc2239327c5edb3a432268e5831',
856
876
  decimals: 6,
857
877
  },
878
+ crvUSD: {
879
+ address: '0x498bf2b1e120fed3ad3d42ea2165e9b73f99c1e5',
880
+ decimals: 18,
881
+ },
858
882
  OHM: {
859
883
  address: '0xf0cb2dc0db5e6c66b9a70ac27b06b878da017028',
860
884
  decimals: 9,
@@ -952,6 +976,10 @@ export const Tokens: {
952
976
  address: '0x3D51a9fB5dCc87F7B237B04975559b920a9a56Ff',
953
977
  decimals: 18,
954
978
  },
979
+ crvUSD: {
980
+ address: '0xc52d7f23a2e460248db6ee192cb23dd12bddcbf6',
981
+ decimals: 18,
982
+ },
955
983
  OP: {
956
984
  address: '0x4200000000000000000000000000000000000042',
957
985
  decimals: 18,
@@ -1123,6 +1151,7 @@ export const Holders: {
1123
1151
  POL: '0x57B6Ad484ccdd902C4419424bA648ba6Ed45dc68',
1124
1152
  SDEX: '0xB0470cF15B22a6A32c49a7C20E3821B944A76058',
1125
1153
  frxETH: '0x9df2322bdAEC46627100C999E6dDdD27837fec6e',
1154
+ USDe: '0x74e6c48e667d698a4cf90665b6960a5bae39e603',
1126
1155
  },
1127
1156
  [Network.ROPSTEN]: {
1128
1157
  ETH: '0x43262A12d8610AA70C15DbaeAC321d51613c9071',
@@ -1136,7 +1165,8 @@ export const Holders: {
1136
1165
  WETH: '0x62ac55b745f9b08f1a81dcbbe630277095cf4be1',
1137
1166
  WMATIC: '0x016ba20db4b681f83e5fbbe0c433c96268ab5815',
1138
1167
  AMWMATIC: '0x8832924854e3Cedb0a6Abf372e6CCFF9F7654332',
1139
- USDC: '0xf89d7b9c864f589bbf53a82105107622b35eaa40',
1168
+ USDCe: '0xf89d7b9c864f589bbf53a82105107622b35eaa40',
1169
+ USDC: '0x53207E216540125e322CdA8A693b0b89576DEb46',
1140
1170
  POPS: '0x2693b57ee51f4e2a26dfb339a911fa8731061f49',
1141
1171
  MUST: '0x9f2a409848fb9b7bd058b24a23e8dbf1e166a109',
1142
1172
  AMDAI: '0xFA0DCe8280FCDf369a4cbFc1830d3302789307a6',
@@ -1159,6 +1189,7 @@ export const Holders: {
1159
1189
  amUSDC: '0x6e7f19cd23049c7118e14470e2bf85d2e26ee0ae',
1160
1190
  MAI: '0x9a8cf02f3e56c664ce75e395d0e4f3dc3dafe138',
1161
1191
  SDEX: '0xB0470cF15B22a6A32c49a7C20E3821B944A76058',
1192
+ crvUSD: '0x9D3a22A71C2bddFEF006f1c207C06B0A5f42f95F',
1162
1193
  },
1163
1194
  [Network.FANTOM]: {
1164
1195
  DAI: '0x370f4b2dcf75c94d8d4450b493661a9c6170d0b5',
@@ -1186,6 +1217,8 @@ export const Holders: {
1186
1217
  lzUSDC: '0x1e38e2e0e7df3be6592867d0ac2713a4dbda8350',
1187
1218
  axlUSDC: '0x1c664Bafc646510684Ba1588798c67fe22a8c7cf',
1188
1219
  SOLID: '0xdF6A50d16320D9eAf0D91e0039fcE89c700F95F1',
1220
+ scrvUSDC_e: '0x49000C4E845de46017F089EF7c175cEA6c5a94b8',
1221
+ scrvUSDC_p: '0x45d426F005741D3BF771AB0c0EF419cCAe1BB750',
1189
1222
  },
1190
1223
  [Network.BSC]: {
1191
1224
  DAI: '0xf68a4b64162906eff0ff6ae34e2bb1cd42fef62d',
@@ -1238,7 +1271,7 @@ export const Holders: {
1238
1271
  nETH: '0xcf2ef00e75558512ae735679ea5df62ad2056786',
1239
1272
  avWETH: '0x92d78e32b990d10aeca0875dc5585f1a6f958179',
1240
1273
  YUSD: '0x6c1a5ef2acde1fd2fc68def440d2c1eb35bae24a',
1241
- BTCb: '0x84c06d3c27821d0136f66306f5028d43ceac268d',
1274
+ BTCb: '0x4bb7f4c3d47C4b431cb0658F44287d52006fb506',
1242
1275
  AMPL: '0xfcaA5ea7F8eb0631BcA72C345025C0A5a6D93f0E',
1243
1276
  PHAR: '0x654296D56532f62B7d91d335791d3c364a9385b5',
1244
1277
  },
@@ -1269,6 +1302,7 @@ export const Holders: {
1269
1302
  RDNT: '0x62383739d68dd0f844103db8dfb05a7eded5bbe6',
1270
1303
  SDEX: '0xb0470cf15b22a6a32c49a7c20e3821b944a76058',
1271
1304
  wstETH: '0x916792f7734089470de27297903bed8a4630b26d',
1305
+ crvUSD: '0x171c53d55b1bcb725f660677d9e8bad7fd084282',
1272
1306
  },
1273
1307
  [Network.OPTIMISM]: {
1274
1308
  ETH: '0x9ef21bE1C270AA1c3c3d750F458442397fBFFCB6',
@@ -1287,6 +1321,7 @@ export const Holders: {
1287
1321
  rETH: '0x4c2e69e58b14de9afedfb94319519ce34e087283',
1288
1322
  WBTC: '0xb9c8f0d3254007ee4b98970b94544e473cd610ec',
1289
1323
  frxETH: '0x4d4edf8291d169f975b99914b6ab3326abb45938',
1324
+ crvUSD: '0xD1A992417a0ABFFa632Cbde4DA9F5DcF85CAa858',
1290
1325
  },
1291
1326
  [Network.ZKEVM]: {
1292
1327
  ETH: '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9',