@paraswap/dex-lib 4.1.7-pub-sub.2 → 4.1.7-pub-sub.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/build/dex/angle-staked-stable/angle-staked-stable.js +2 -1
  2. package/build/dex/angle-staked-stable/angle-staked-stable.js.map +1 -1
  3. package/build/dex/angle-transmuter/angle-transmuter.js.map +1 -1
  4. package/build/dex/balancer-v1/config.js +2 -1
  5. package/build/dex/balancer-v1/config.js.map +1 -1
  6. package/build/dex/dexalot/dexalot.d.ts +2 -9
  7. package/build/dex/dexalot/dexalot.js +18 -62
  8. package/build/dex/dexalot/dexalot.js.map +1 -1
  9. package/build/dex/dexalot/rate-fetcher.d.ts +19 -4
  10. package/build/dex/dexalot/rate-fetcher.js +112 -8
  11. package/build/dex/dexalot/rate-fetcher.js.map +1 -1
  12. package/build/dex/dexalot/types.d.ts +0 -1
  13. package/build/dex/generic-rfq/rate-fetcher.js +0 -12
  14. package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
  15. package/build/dex/hashflow/constants.d.ts +2 -2
  16. package/build/dex/hashflow/constants.js +2 -2
  17. package/build/dex/hashflow/hashflow.d.ts +1 -6
  18. package/build/dex/hashflow/hashflow.js +9 -34
  19. package/build/dex/hashflow/hashflow.js.map +1 -1
  20. package/build/dex/hashflow/rate-fetcher.d.ts +12 -2
  21. package/build/dex/hashflow/rate-fetcher.js +54 -6
  22. package/build/dex/hashflow/rate-fetcher.js.map +1 -1
  23. package/build/dex/hashflow/types.d.ts +0 -1
  24. package/build/dex/weth/weth.js +2 -1
  25. package/build/dex/weth/weth.js.map +1 -1
  26. package/build/lib/pub-sub.d.ts +0 -2
  27. package/build/lib/pub-sub.js +0 -12
  28. package/build/lib/pub-sub.js.map +1 -1
  29. package/build/pricing-helper.d.ts +1 -1
  30. package/build/pricing-helper.js +13 -9
  31. package/build/pricing-helper.js.map +1 -1
  32. package/build/types.d.ts +1 -0
  33. package/package.json +1 -1
  34. package/src/dex/aave-gsm/aave-gsm-gas-estimation.test.ts +32 -0
  35. package/src/dex/aave-v2/aave-v2-gas-estimation.test.ts +28 -0
  36. package/src/dex/aave-v3/aave-v3-gas-estimation.test.ts +66 -0
  37. package/src/dex/aave-v3-stata/aave-v3-stata-gas-estimation.test.ts +41 -0
  38. package/src/dex/aave-v3-stata-v2/aave-v3-stata-v2-gas-estimation.test.ts +41 -0
  39. package/src/dex/angle-staked-stable/angle-staked-stable-gas-estimation.test.ts +29 -0
  40. package/src/dex/angle-staked-stable/angle-staked-stable.ts +2 -1
  41. package/src/dex/angle-transmuter/angle-transmuter-gas-estimation.test.ts +41 -0
  42. package/src/dex/angle-transmuter/angle-transmuter.ts +0 -1
  43. package/src/dex/balancer-v1/balancer-v1-gas-estimation.test.ts +29 -0
  44. package/src/dex/balancer-v1/config.ts +2 -1
  45. package/src/dex/balancer-v2/balancer-v2-gas-estimation.test.ts +98 -0
  46. package/src/dex/balancer-v3/balancer-v3-gas-estimation.test.ts +30 -0
  47. package/src/dex/bancor/bancor-gas-estimation.test.ts +30 -0
  48. package/src/dex/bebop/bebop-gas-estimation.test.ts +30 -0
  49. package/src/dex/concentrator-arusd/concentrator-arusd-gas-estimation.test.ts +29 -0
  50. package/src/dex/curve-v1/curve-v1-gas-estimation.test.ts +29 -0
  51. package/src/dex/curve-v2/curve-v2-gas-estimation.test.ts +29 -0
  52. package/src/dex/dexalot/dexalot.ts +27 -127
  53. package/src/dex/dexalot/rate-fetcher.ts +219 -9
  54. package/src/dex/dexalot/types.ts +0 -1
  55. package/src/dex/fluid-dex/fluid-dex-gas-estimation.test.ts +29 -0
  56. package/src/dex/fx-protocol-rusd/fx-protocol-rusd-gas-estimation.test.ts +29 -0
  57. package/src/dex/generic-rfq/rate-fetcher.ts +0 -30
  58. package/src/dex/hashflow/constants.ts +2 -2
  59. package/src/dex/hashflow/hashflow-gas-estimation.test.ts +30 -0
  60. package/src/dex/hashflow/hashflow.ts +11 -67
  61. package/src/dex/hashflow/rate-fetcher.ts +106 -8
  62. package/src/dex/hashflow/types.ts +0 -1
  63. package/src/dex/idle-dao/idle-dao--gas-estimation.test.ts +30 -0
  64. package/src/dex/lido/lido-gas-estimation.test.ts +29 -0
  65. package/src/dex/lite-psm/lite-psm-gas-estimation.test.ts +34 -0
  66. package/src/dex/maker-psm/maker-psm-gas-estimation.test.ts +34 -0
  67. package/src/dex/maverick-v1/maverick-v1-gas-estimation.test.ts +29 -0
  68. package/src/dex/maverick-v2/maverick-v2-gas-estimation.test.ts +29 -0
  69. package/src/dex/pancakeswap-v3/pancakeswap-v3-gas-estimation.test.ts +29 -0
  70. package/src/dex/polygon-migrator/polygon-migrator-gas-estimation.test.ts +41 -0
  71. package/src/dex/sky-converter/sky-converter-gas-estimation.test.ts +78 -0
  72. package/src/dex/solidly/solidly-gas-estimation.test.ts +29 -0
  73. package/src/dex/solidly-v3/solidly-v3-gas-estimation.test.ts +29 -0
  74. package/src/dex/spark/spark-gas-estimation.test.ts +29 -0
  75. package/src/dex/stader/stader-gas-estimation.test.ts +29 -0
  76. package/src/dex/stkgho/stkgho-gas-estimation.test.ts +29 -0
  77. package/src/dex/swaap-v2/swaap-v2-estimation.test.ts +29 -0
  78. package/src/dex/swell/swell-estimation.test.ts +29 -0
  79. package/src/dex/trader-joe-v2.1/trader-joe-v2.1-gas-estimation.test.ts +29 -0
  80. package/src/dex/uniswap-v2/uniswap-v2-gas-estimation.test.ts +98 -0
  81. package/src/dex/uniswap-v3/uniswap-v3-gas-estimation.test.ts +98 -0
  82. package/src/dex/usual/usual-gas-estimation.test.ts +54 -0
  83. package/src/dex/usual-pp/usual-pp-gas-estimation.test.ts +29 -0
  84. package/src/dex/weth/weth-gas-estimation.test.ts +42 -0
  85. package/src/dex/weth/weth.ts +3 -1
  86. package/src/dex/wombat/wombat-gas-estimation.test.ts +29 -0
  87. package/src/dex/wsteth/wsteth-gas-estimation.test.ts +41 -0
  88. package/src/dex/wusdm/wusdm-gas-estimation.test.ts +41 -0
  89. package/src/lib/pub-sub.ts +0 -27
  90. package/src/pricing-helper.ts +19 -11
  91. package/src/types.ts +1 -0
  92. package/tests/constants-e2e.ts +8 -0
  93. package/tests/tenderly-simulation-new.test.ts +151 -0
  94. package/tests/tenderly-simulation-new.ts +698 -0
  95. package/tests/token-storage-slots.json +532 -0
  96. package/tests/utils-e2e.ts +137 -1
@@ -46,7 +46,6 @@ export const reversePrice = (price: PriceAndAmountBigNumber) =>
46
46
  price[1].times(price[0]),
47
47
  ] as PriceAndAmountBigNumber;
48
48
 
49
- const logPrefix = 'RateFetched[pub_sub]';
50
49
  export class RateFetcher {
51
50
  private tokensFetcher: Fetcher<TokensResponse>;
52
51
  private pairsFetcher: Fetcher<PairsResponse>;
@@ -168,7 +167,6 @@ export class RateFetcher {
168
167
  }
169
168
 
170
169
  async initialize() {
171
- this.logger.info(`${logPrefix} Initializing rate fetcher`);
172
170
  const isContract = await isContractAddress(
173
171
  this.dexHelper.web3Provider,
174
172
  this.config.maker,
@@ -181,10 +179,8 @@ export class RateFetcher {
181
179
  }
182
180
 
183
181
  if (this.dexHelper.config.isSlave) {
184
- this.logger.info(`${logPrefix} Subscribing to prices pubsub`);
185
182
  this.pricesPubSub.subscribe();
186
183
  if (this.blacklistPubSub) {
187
- this.logger.info(`${logPrefix} Subscribing to blacklist pubsub`);
188
184
  const initSet = await this.dexHelper.cache.smembers(
189
185
  this.blackListCacheKey,
190
186
  );
@@ -194,7 +190,6 @@ export class RateFetcher {
194
190
  }
195
191
 
196
192
  start() {
197
- this.logger.info(`${logPrefix} Starting rate fetcher`);
198
193
  this.tokensFetcher.startPolling();
199
194
  this.rateFetcher.startPolling();
200
195
  this.pairsFetcher.startPolling();
@@ -204,7 +199,6 @@ export class RateFetcher {
204
199
  }
205
200
 
206
201
  stop() {
207
- this.logger.info(`${logPrefix} Stopping rate fetcher`);
208
202
  this.tokensFetcher.stopPolling();
209
203
  this.pairsFetcher.stopPolling();
210
204
  this.rateFetcher.stopPolling();
@@ -215,10 +209,6 @@ export class RateFetcher {
215
209
  }
216
210
 
217
211
  private handleTokensResponse(data: TokensResponse) {
218
- this.logger.info(
219
- `${logPrefix} Handling tokens response, tokens: `,
220
- Object.keys(data.tokens).length,
221
- );
222
212
  for (const tokenName of Object.keys(data.tokens)) {
223
213
  const token = data.tokens[tokenName];
224
214
  token.address = token.address.toLowerCase();
@@ -236,10 +226,6 @@ export class RateFetcher {
236
226
  }
237
227
 
238
228
  private handlePairsResponse(resp: PairsResponse) {
239
- this.logger.info(
240
- `${logPrefix} Handling pairs response, pairs: `,
241
- Object.keys(resp.pairs).length,
242
- );
243
229
  this.pairs = {};
244
230
 
245
231
  const pairs: PairMap = {};
@@ -251,19 +237,11 @@ export class RateFetcher {
251
237
  }
252
238
 
253
239
  private handleBlackListResponse(resp: BlackListResponse) {
254
- this.logger.info(
255
- `${logPrefix} Handling blacklist response, blacklist length: `,
256
- resp.blacklist.length,
257
- );
258
240
  for (const address of resp.blacklist) {
259
241
  this.dexHelper.cache.sadd(this.blackListCacheKey, address.toLowerCase());
260
242
  }
261
243
 
262
244
  if (this.blacklistPubSub) {
263
- this.logger.info(
264
- `${logPrefix} Publishing blacklist to pubsub, blacklist length: `,
265
- resp.blacklist.length,
266
- );
267
245
  this.blacklistPubSub.publish(resp.blacklist);
268
246
  }
269
247
  }
@@ -276,10 +254,6 @@ export class RateFetcher {
276
254
  }
277
255
 
278
256
  private handleRatesResponse(resp: RatesResponse) {
279
- this.logger.info(
280
- `${logPrefix} Handling rates response, prices length: `,
281
- Object.keys(resp.prices).length,
282
- );
283
257
  const pubSubData: Record<string, unknown> = {};
284
258
  const ttl = this.config.rateConfig.dataTTLS;
285
259
  const pairs = this.pairs;
@@ -395,10 +369,6 @@ export class RateFetcher {
395
369
 
396
370
  public async getAvailablePairs(): Promise<string[]> {
397
371
  const pairs = await this.pricesPubSub.getAndCache<string[]>(`pairs`);
398
- this.logger.info(
399
- `${logPrefix} Getting available pairs, pairs: `,
400
- pairs?.length,
401
- );
402
372
  if (!pairs) {
403
373
  return [];
404
374
  }
@@ -4,11 +4,11 @@ export const HASHFLOW_BLACKLIST_TTL_S = 60 * 60 * 24 * 7; // 7 days
4
4
 
5
5
  export const HASHFLOW_MM_RESTRICT_TTL_S = 60 * 60;
6
6
 
7
- export const HASHFLOW_PRICES_CACHES_TTL_S = 3;
7
+ export const HASHFLOW_PRICES_CACHES_TTL_S = 5;
8
8
 
9
9
  export const HASHFLOW_MARKET_MAKERS_CACHES_TTL_S = 30;
10
10
 
11
- export const HASHFLOW_API_PRICES_POLLING_INTERVAL_MS = 1000;
11
+ export const HASHFLOW_API_PRICES_POLLING_INTERVAL_MS = 2000;
12
12
 
13
13
  export const HASHFLOW_API_MARKET_MAKERS_POLLING_INTERVAL_MS = 28 * 1000; // 28 secs
14
14
 
@@ -0,0 +1,30 @@
1
+ /* eslint-disable no-console */
2
+ import 'dotenv/config';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ describe('Hashflow Gas Estimation', () => {
9
+ const dexKey = 'Hashflow';
10
+ const network = Network.MAINNET;
11
+
12
+ describe('swapExactAmountIn', () => {
13
+ const USDT = Tokens[network]['USDT'];
14
+ const USDC = Tokens[network]['USDC'];
15
+ const amount = 100000000n;
16
+
17
+ // todo: fix tx build
18
+ it('tradeRFQT', async () => {
19
+ await testGasEstimation(
20
+ network,
21
+ USDT,
22
+ USDC,
23
+ amount,
24
+ SwapSide.SELL,
25
+ dexKey,
26
+ ContractMethodV6.swapExactAmountIn,
27
+ );
28
+ });
29
+ });
30
+ });
@@ -1,10 +1,6 @@
1
1
  import { ChainId } from '@hashflow/sdk';
2
2
  import { Chain, ChainType, HashflowApi } from '@hashflow/taker-js';
3
- import {
4
- MarketMakersResponse,
5
- PriceLevelsResponse,
6
- RfqResponse,
7
- } from '@hashflow/taker-js/dist/types/rest';
3
+ import { RfqResponse } from '@hashflow/taker-js/dist/types/rest';
8
4
  import BigNumber from 'bignumber.js';
9
5
  import { Interface } from 'ethers/lib/utils';
10
6
  import { assert } from 'ts-essentials';
@@ -145,7 +141,6 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
145
141
  },
146
142
  headers: { Authorization: this.hashFlowAuthToken },
147
143
  },
148
- getCachedMarketMakers: this.getCachedMarketMakers.bind(this),
149
144
  filterMarketMakers: this.getFilteredMarketMakers.bind(this),
150
145
  pricesCacheKey: this.pricesCacheKey,
151
146
  pricesCacheTTLSecs: HASHFLOW_PRICES_CACHES_TTL_S,
@@ -157,9 +152,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
157
152
  }
158
153
 
159
154
  async initializePricing(blockNumber: number): Promise<void> {
160
- if (!this.dexHelper.config.isSlave) {
161
- this.rateFetcher.start();
162
- }
155
+ this.rateFetcher.start();
163
156
 
164
157
  return;
165
158
  }
@@ -198,7 +191,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
198
191
  return [];
199
192
  }
200
193
 
201
- const levels = (await this.getCachedLevels()) || {};
194
+ const levels = (await this.rateFetcher.getCachedLevels()) || {};
202
195
  const makers = Object.keys(levels);
203
196
 
204
197
  return makers
@@ -381,32 +374,6 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
381
374
  return undefined;
382
375
  }
383
376
 
384
- async getCachedMarketMakers(): Promise<
385
- MarketMakersResponse['marketMakers'] | null
386
- > {
387
- const cachedMarketMakers = await this.dexHelper.cache.rawget(
388
- this.marketMakersCacheKey,
389
- );
390
-
391
- if (cachedMarketMakers) {
392
- return JSON.parse(
393
- cachedMarketMakers,
394
- ) as MarketMakersResponse['marketMakers'];
395
- }
396
-
397
- return null;
398
- }
399
-
400
- async getCachedLevels(): Promise<PriceLevelsResponse['levels'] | null> {
401
- const cachedLevels = await this.dexHelper.cache.rawget(this.pricesCacheKey);
402
-
403
- if (cachedLevels) {
404
- return JSON.parse(cachedLevels) as PriceLevelsResponse['levels'];
405
- }
406
-
407
- return null;
408
- }
409
-
410
377
  async getPricesVolume(
411
378
  srcToken: Token,
412
379
  destToken: Token,
@@ -434,7 +401,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
434
401
 
435
402
  const marketMakersToUse = pools.map(p => p.split(`${prefix}_`).pop());
436
403
 
437
- const levelsMap = (await this.getCachedLevels()) || {};
404
+ const levelsMap = (await this.rateFetcher.getCachedLevels()) || {};
438
405
 
439
406
  Object.keys(levelsMap).forEach(mmKey => {
440
407
  if (!marketMakersToUse.includes(mmKey)) {
@@ -715,7 +682,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
715
682
  this.logger.warn(
716
683
  `${this.dexKey}-${this.network}: Encountered restricted user=${options.userAddress}. Adding to local blacklist cache`,
717
684
  );
718
- await this.setBlacklist(options.userAddress);
685
+ await this.rateFetcher.setBlacklist(options.userAddress);
719
686
  } else {
720
687
  if (e instanceof TooStrictSlippageCheckError) {
721
688
  this.logger.warn(
@@ -911,33 +878,6 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
911
878
  };
912
879
  }
913
880
 
914
- getBlackListKey(address: Address) {
915
- return `blacklist_${address}`.toLowerCase();
916
- }
917
-
918
- async isBlacklisted(txOrigin: Address): Promise<boolean> {
919
- const result = await this.dexHelper.cache.get(
920
- this.dexKey,
921
- this.network,
922
- this.getBlackListKey(txOrigin),
923
- );
924
- return result === 'blacklisted';
925
- }
926
-
927
- async setBlacklist(
928
- txOrigin: Address,
929
- ttl: number = HASHFLOW_BLACKLIST_TTL_S,
930
- ) {
931
- await this.dexHelper.cache.setex(
932
- this.dexKey,
933
- this.network,
934
- this.getBlackListKey(txOrigin),
935
- ttl,
936
- 'blacklisted',
937
- );
938
- return true;
939
- }
940
-
941
881
  async getSimpleParam(
942
882
  srcToken: string,
943
883
  destToken: string,
@@ -1058,9 +998,9 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
1058
998
  .wrapETH(tokenAddress)
1059
999
  .toLowerCase();
1060
1000
 
1061
- const makers = (await this.getCachedMarketMakers()) || [];
1001
+ const makers = (await this.rateFetcher.getCachedMarketMakers()) || [];
1062
1002
  const filteredMakers = await this.getFilteredMarketMakers(makers);
1063
- const pLevels = (await this.getCachedLevels()) || {};
1003
+ const pLevels = (await this.rateFetcher.getCachedLevels()) || {};
1064
1004
 
1065
1005
  let baseToken: Token | undefined = undefined;
1066
1006
  // TODO: Improve efficiency of this part. Quite inefficient way to determine
@@ -1120,4 +1060,8 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
1120
1060
  this.rateFetcher.stop();
1121
1061
  }
1122
1062
  }
1063
+
1064
+ async isBlacklisted(txOrigin: Address): Promise<boolean> {
1065
+ return this.rateFetcher.isBlacklisted(txOrigin);
1066
+ }
1123
1067
  }
@@ -1,17 +1,24 @@
1
+ import {
2
+ MarketMakersResponse,
3
+ PriceLevelsResponse,
4
+ } from '@hashflow/taker-js/dist/types/rest';
1
5
  import { Network } from '../../constants';
2
6
  import { IDexHelper } from '../../dex-helper';
3
7
  import { Fetcher, SkippingRequest } from '../../lib/fetcher/fetcher';
4
8
  import { validateAndCast } from '../../lib/validators';
5
- import { Logger } from '../../types';
9
+ import { Address, Logger } from '../../types';
6
10
  import {
7
11
  HashflowMarketMakersResponse,
8
12
  HashflowRateFetcherConfig,
9
13
  HashflowRatesResponse,
10
14
  } from './types';
11
15
  import { marketMakersValidator, pricesResponseValidator } from './validators';
16
+ import { HASHFLOW_BLACKLIST_TTL_S } from './constants';
17
+ import { ExpKeyValuePubSub, NonExpSetPubSub } from '../../lib/pub-sub';
12
18
 
13
19
  export class RateFetcher {
14
20
  private rateFetcher: Fetcher<HashflowRatesResponse>;
21
+ private ratePubSub: ExpKeyValuePubSub;
15
22
  private pricesCacheKey: string;
16
23
  private pricesCacheTTL: number;
17
24
 
@@ -19,6 +26,8 @@ export class RateFetcher {
19
26
  private marketMakersCacheKey: string;
20
27
  private marketMakersCacheTTL: number;
21
28
 
29
+ private blacklistedPubSub: NonExpSetPubSub;
30
+
22
31
  constructor(
23
32
  private dexHelper: IDexHelper,
24
33
  private dexKey: string,
@@ -48,16 +57,18 @@ export class RateFetcher {
48
57
  logger,
49
58
  );
50
59
 
60
+ this.ratePubSub = new ExpKeyValuePubSub(dexHelper, dexKey, 'rates');
61
+
51
62
  this.rateFetcher = new Fetcher<HashflowRatesResponse>(
52
63
  dexHelper.httpRequest,
53
64
  {
54
65
  info: {
55
66
  requestOptions: config.rateConfig.pricesReqParams,
56
67
  requestFunc: async options => {
57
- const { filterMarketMakers, getCachedMarketMakers } =
58
- config.rateConfig;
68
+ const { filterMarketMakers } = config.rateConfig;
59
69
 
60
- const cachedMarketMakers = (await getCachedMarketMakers()) || [];
70
+ const cachedMarketMakers =
71
+ (await this.getCachedMarketMakers()) || [];
61
72
  const filteredMarketMakers = await filterMarketMakers(
62
73
  cachedMarketMakers,
63
74
  );
@@ -86,11 +97,24 @@ export class RateFetcher {
86
97
  config.rateConfig.pricesIntervalMs,
87
98
  logger,
88
99
  );
100
+
101
+ this.blacklistedPubSub = new NonExpSetPubSub(
102
+ dexHelper,
103
+ dexKey,
104
+ 'blacklisted',
105
+ );
89
106
  }
90
107
 
91
- start() {
92
- this.marketMakersFetcher.startPolling();
93
- this.rateFetcher.startPolling();
108
+ async start() {
109
+ if (!this.dexHelper.config.isSlave) {
110
+ this.marketMakersFetcher.startPolling();
111
+ this.rateFetcher.startPolling();
112
+ } else {
113
+ this.ratePubSub.subscribe();
114
+
115
+ const allBlacklisted = await this.getAllBlacklisted();
116
+ this.blacklistedPubSub.initializeAndSubscribe(allBlacklisted);
117
+ }
94
118
  }
95
119
 
96
120
  stop() {
@@ -109,10 +133,84 @@ export class RateFetcher {
109
133
 
110
134
  private handleRatesResponse(resp: HashflowRatesResponse): void {
111
135
  const { levels } = resp;
112
- this.dexHelper.cache.rawset(
136
+ this.dexHelper.cache.setex(
137
+ this.dexKey,
138
+ this.network,
113
139
  this.pricesCacheKey,
140
+ this.pricesCacheTTL,
114
141
  JSON.stringify(levels),
142
+ );
143
+
144
+ this.ratePubSub.publish(
145
+ { [this.pricesCacheKey]: levels },
115
146
  this.pricesCacheTTL,
116
147
  );
117
148
  }
149
+
150
+ async getCachedMarketMakers(): Promise<
151
+ MarketMakersResponse['marketMakers'] | null
152
+ > {
153
+ const cachedMarketMakers = await this.dexHelper.cache.rawget(
154
+ this.marketMakersCacheKey,
155
+ );
156
+
157
+ if (cachedMarketMakers) {
158
+ return JSON.parse(
159
+ cachedMarketMakers,
160
+ ) as MarketMakersResponse['marketMakers'];
161
+ }
162
+
163
+ return null;
164
+ }
165
+
166
+ async getCachedLevels(): Promise<PriceLevelsResponse['levels'] | null> {
167
+ const cachedLevels = await this.ratePubSub.getAndCache(this.pricesCacheKey);
168
+
169
+ if (cachedLevels) {
170
+ return cachedLevels as PriceLevelsResponse['levels'];
171
+ }
172
+
173
+ return null;
174
+ }
175
+
176
+ async isBlacklisted(txOrigin: Address): Promise<boolean> {
177
+ return this.blacklistedPubSub.has(txOrigin.toLowerCase());
178
+ }
179
+
180
+ async setBlacklist(
181
+ txOrigin: Address,
182
+ ttl: number = HASHFLOW_BLACKLIST_TTL_S,
183
+ ) {
184
+ await this.dexHelper.cache.setex(
185
+ this.dexKey,
186
+ this.network,
187
+ this.getBlackListKey(txOrigin),
188
+ ttl,
189
+ 'blacklisted',
190
+ );
191
+
192
+ this.blacklistedPubSub.publish([txOrigin.toLowerCase()]);
193
+
194
+ return true;
195
+ }
196
+
197
+ async getAllBlacklisted(): Promise<Address[]> {
198
+ const defaultKey = this.getBlackListKey('');
199
+ const pattern = `${defaultKey}*`;
200
+ const allBlacklisted = await this.dexHelper.cache.keys(
201
+ this.dexKey,
202
+ this.network,
203
+ pattern,
204
+ );
205
+
206
+ return allBlacklisted.map(t => this.getAddressFromBlackListKey(t));
207
+ }
208
+
209
+ getBlackListKey(address: Address) {
210
+ return `blacklist_${address}`.toLowerCase();
211
+ }
212
+
213
+ getAddressFromBlackListKey(key: Address) {
214
+ return (key.split('blacklist_')[1] ?? '').toLowerCase();
215
+ }
118
216
  }
@@ -64,7 +64,6 @@ export type HashflowRateFetcherConfig = {
64
64
  };
65
65
  pricesIntervalMs: number;
66
66
  markerMakersIntervalMs: number;
67
- getCachedMarketMakers: () => Promise<string[] | null>;
68
67
  filterMarketMakers: (makers: string[]) => Promise<string[]>;
69
68
  pricesCacheKey: string;
70
69
  marketMakersCacheKey: string;
@@ -0,0 +1,30 @@
1
+ /* eslint-disable no-console */
2
+ import 'dotenv/config';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ describe('IdleDao Gas Estimation', () => {
9
+ const dexKey = 'IdleDao';
10
+ const network = Network.MAINNET;
11
+
12
+ describe('swapExactAmountIn', () => {
13
+ const STETH = Tokens[network]['STETH'];
14
+ const AA_wstETH = Tokens[network]['AA_wstETH'];
15
+ const amount = 1000000000000000000n;
16
+
17
+ // todo: uncomment? (the dex doesn't seem to be working)
18
+ // it('deposit', async () => {
19
+ // await testGasEstimation(
20
+ // network,
21
+ // STETH,
22
+ // AA_wstETH,
23
+ // amount,
24
+ // SwapSide.SELL,
25
+ // dexKey,
26
+ // ContractMethodV6.swapExactAmountIn,
27
+ // );
28
+ // });
29
+ });
30
+ });
@@ -0,0 +1,29 @@
1
+ /* eslint-disable no-console */
2
+ import 'dotenv/config';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ describe('Lido Gas Estimation', () => {
9
+ const dexKey = 'Lido';
10
+ const network = Network.MAINNET;
11
+
12
+ describe('swapExactAmountIn', () => {
13
+ const STETH = Tokens[network]['STETH'];
14
+ const ETH = Tokens[network]['ETH'];
15
+ const amount = 100000000000000000000n;
16
+
17
+ it('submit', async () => {
18
+ await testGasEstimation(
19
+ network,
20
+ ETH,
21
+ STETH,
22
+ amount,
23
+ SwapSide.SELL,
24
+ dexKey,
25
+ ContractMethodV6.swapExactAmountIn,
26
+ );
27
+ });
28
+ });
29
+ });
@@ -0,0 +1,34 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ dotenv.config();
9
+
10
+ describe('LitePsm Gas Estimation', () => {
11
+ const dexKey = 'LitePsm';
12
+ const network = Network.MAINNET;
13
+ const srcToken = Tokens[network]['USDC'];
14
+ const destToken = Tokens[network]['DAI'];
15
+ const methods: ContractMethodV6[] = [
16
+ ContractMethodV6.swapExactAmountInOutOnMakerPSM,
17
+ ContractMethodV6.swapExactAmountIn,
18
+ ];
19
+ const amount = 10000000n;
20
+
21
+ methods.forEach(async method => {
22
+ it(method, async () => {
23
+ await testGasEstimation(
24
+ network,
25
+ srcToken,
26
+ destToken,
27
+ amount,
28
+ SwapSide.SELL,
29
+ dexKey,
30
+ method,
31
+ );
32
+ });
33
+ });
34
+ });
@@ -0,0 +1,34 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ dotenv.config();
9
+
10
+ describe('MakerPsm Gas Estimation', () => {
11
+ const dexKey = 'MakerPsm';
12
+ const network = Network.MAINNET;
13
+ const srcToken = Tokens[network]['USDC'];
14
+ const destToken = Tokens[network]['DAI'];
15
+ const methods: ContractMethodV6[] = [
16
+ ContractMethodV6.swapExactAmountInOutOnMakerPSM,
17
+ ContractMethodV6.swapExactAmountIn,
18
+ ];
19
+ const amount = 10000000n;
20
+
21
+ methods.forEach(async method => {
22
+ it(method, async () => {
23
+ await testGasEstimation(
24
+ network,
25
+ srcToken,
26
+ destToken,
27
+ amount,
28
+ SwapSide.SELL,
29
+ dexKey,
30
+ method,
31
+ );
32
+ });
33
+ });
34
+ });
@@ -0,0 +1,29 @@
1
+ /* eslint-disable no-console */
2
+ import 'dotenv/config';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ describe('MaverickV1 Gas Estimation', () => {
9
+ const dexKey = 'MaverickV1';
10
+ const network = Network.MAINNET;
11
+
12
+ describe('swapExactAmountIn', () => {
13
+ const USDT = Tokens[network]['USDT'];
14
+ const USDC = Tokens[network]['USDC'];
15
+ const amount = 1000000n;
16
+
17
+ it('exactInputSingle', async () => {
18
+ await testGasEstimation(
19
+ network,
20
+ USDT,
21
+ USDC,
22
+ amount,
23
+ SwapSide.SELL,
24
+ dexKey,
25
+ ContractMethodV6.swapExactAmountIn,
26
+ );
27
+ });
28
+ });
29
+ });
@@ -0,0 +1,29 @@
1
+ /* eslint-disable no-console */
2
+ import 'dotenv/config';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ describe('MaverickV2 Gas Estimation', () => {
9
+ const dexKey = 'MaverickV2';
10
+ const network = Network.MAINNET;
11
+
12
+ describe('swapExactAmountIn', () => {
13
+ const USDT = Tokens[network]['USDT'];
14
+ const USDC = Tokens[network]['USDC'];
15
+ const amount = 100000000n;
16
+
17
+ it('swap', async () => {
18
+ await testGasEstimation(
19
+ network,
20
+ USDT,
21
+ USDC,
22
+ amount,
23
+ SwapSide.SELL,
24
+ dexKey,
25
+ ContractMethodV6.swapExactAmountIn,
26
+ );
27
+ });
28
+ });
29
+ });
@@ -0,0 +1,29 @@
1
+ /* eslint-disable no-console */
2
+ import 'dotenv/config';
3
+ import { testGasEstimation } from '../../../tests/utils-e2e';
4
+ import { Tokens } from '../../../tests/constants-e2e';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { ContractMethodV6 } from '@paraswap/core';
7
+
8
+ describe('PancakeswapV3 Gas Estimation', () => {
9
+ const dexKey = 'PancakeswapV3';
10
+ const network = Network.MAINNET;
11
+
12
+ describe('swapExactAmountIn', () => {
13
+ const USDT = Tokens[network]['USDT'];
14
+ const USDC = Tokens[network]['USDC'];
15
+ const amount = 100000000n;
16
+
17
+ it('exactInput', async () => {
18
+ await testGasEstimation(
19
+ network,
20
+ USDT,
21
+ USDC,
22
+ amount,
23
+ SwapSide.SELL,
24
+ dexKey,
25
+ ContractMethodV6.swapExactAmountIn,
26
+ );
27
+ });
28
+ });
29
+ });