@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.
- package/build/dex/angle-staked-stable/angle-staked-stable.js +2 -1
- package/build/dex/angle-staked-stable/angle-staked-stable.js.map +1 -1
- package/build/dex/angle-transmuter/angle-transmuter.js.map +1 -1
- package/build/dex/balancer-v1/config.js +2 -1
- package/build/dex/balancer-v1/config.js.map +1 -1
- package/build/dex/dexalot/dexalot.d.ts +2 -9
- package/build/dex/dexalot/dexalot.js +18 -62
- package/build/dex/dexalot/dexalot.js.map +1 -1
- package/build/dex/dexalot/rate-fetcher.d.ts +19 -4
- package/build/dex/dexalot/rate-fetcher.js +112 -8
- package/build/dex/dexalot/rate-fetcher.js.map +1 -1
- package/build/dex/dexalot/types.d.ts +0 -1
- package/build/dex/generic-rfq/rate-fetcher.js +0 -12
- package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
- package/build/dex/hashflow/constants.d.ts +2 -2
- package/build/dex/hashflow/constants.js +2 -2
- package/build/dex/hashflow/hashflow.d.ts +1 -6
- package/build/dex/hashflow/hashflow.js +9 -34
- package/build/dex/hashflow/hashflow.js.map +1 -1
- package/build/dex/hashflow/rate-fetcher.d.ts +12 -2
- package/build/dex/hashflow/rate-fetcher.js +54 -6
- package/build/dex/hashflow/rate-fetcher.js.map +1 -1
- package/build/dex/hashflow/types.d.ts +0 -1
- package/build/dex/weth/weth.js +2 -1
- package/build/dex/weth/weth.js.map +1 -1
- package/build/lib/pub-sub.d.ts +0 -2
- package/build/lib/pub-sub.js +0 -12
- package/build/lib/pub-sub.js.map +1 -1
- package/build/pricing-helper.d.ts +1 -1
- package/build/pricing-helper.js +13 -9
- package/build/pricing-helper.js.map +1 -1
- package/build/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/dex/aave-gsm/aave-gsm-gas-estimation.test.ts +32 -0
- package/src/dex/aave-v2/aave-v2-gas-estimation.test.ts +28 -0
- package/src/dex/aave-v3/aave-v3-gas-estimation.test.ts +66 -0
- package/src/dex/aave-v3-stata/aave-v3-stata-gas-estimation.test.ts +41 -0
- package/src/dex/aave-v3-stata-v2/aave-v3-stata-v2-gas-estimation.test.ts +41 -0
- package/src/dex/angle-staked-stable/angle-staked-stable-gas-estimation.test.ts +29 -0
- package/src/dex/angle-staked-stable/angle-staked-stable.ts +2 -1
- package/src/dex/angle-transmuter/angle-transmuter-gas-estimation.test.ts +41 -0
- package/src/dex/angle-transmuter/angle-transmuter.ts +0 -1
- package/src/dex/balancer-v1/balancer-v1-gas-estimation.test.ts +29 -0
- package/src/dex/balancer-v1/config.ts +2 -1
- package/src/dex/balancer-v2/balancer-v2-gas-estimation.test.ts +98 -0
- package/src/dex/balancer-v3/balancer-v3-gas-estimation.test.ts +30 -0
- package/src/dex/bancor/bancor-gas-estimation.test.ts +30 -0
- package/src/dex/bebop/bebop-gas-estimation.test.ts +30 -0
- package/src/dex/concentrator-arusd/concentrator-arusd-gas-estimation.test.ts +29 -0
- package/src/dex/curve-v1/curve-v1-gas-estimation.test.ts +29 -0
- package/src/dex/curve-v2/curve-v2-gas-estimation.test.ts +29 -0
- package/src/dex/dexalot/dexalot.ts +27 -127
- package/src/dex/dexalot/rate-fetcher.ts +219 -9
- package/src/dex/dexalot/types.ts +0 -1
- package/src/dex/fluid-dex/fluid-dex-gas-estimation.test.ts +29 -0
- package/src/dex/fx-protocol-rusd/fx-protocol-rusd-gas-estimation.test.ts +29 -0
- package/src/dex/generic-rfq/rate-fetcher.ts +0 -30
- package/src/dex/hashflow/constants.ts +2 -2
- package/src/dex/hashflow/hashflow-gas-estimation.test.ts +30 -0
- package/src/dex/hashflow/hashflow.ts +11 -67
- package/src/dex/hashflow/rate-fetcher.ts +106 -8
- package/src/dex/hashflow/types.ts +0 -1
- package/src/dex/idle-dao/idle-dao--gas-estimation.test.ts +30 -0
- package/src/dex/lido/lido-gas-estimation.test.ts +29 -0
- package/src/dex/lite-psm/lite-psm-gas-estimation.test.ts +34 -0
- package/src/dex/maker-psm/maker-psm-gas-estimation.test.ts +34 -0
- package/src/dex/maverick-v1/maverick-v1-gas-estimation.test.ts +29 -0
- package/src/dex/maverick-v2/maverick-v2-gas-estimation.test.ts +29 -0
- package/src/dex/pancakeswap-v3/pancakeswap-v3-gas-estimation.test.ts +29 -0
- package/src/dex/polygon-migrator/polygon-migrator-gas-estimation.test.ts +41 -0
- package/src/dex/sky-converter/sky-converter-gas-estimation.test.ts +78 -0
- package/src/dex/solidly/solidly-gas-estimation.test.ts +29 -0
- package/src/dex/solidly-v3/solidly-v3-gas-estimation.test.ts +29 -0
- package/src/dex/spark/spark-gas-estimation.test.ts +29 -0
- package/src/dex/stader/stader-gas-estimation.test.ts +29 -0
- package/src/dex/stkgho/stkgho-gas-estimation.test.ts +29 -0
- package/src/dex/swaap-v2/swaap-v2-estimation.test.ts +29 -0
- package/src/dex/swell/swell-estimation.test.ts +29 -0
- package/src/dex/trader-joe-v2.1/trader-joe-v2.1-gas-estimation.test.ts +29 -0
- package/src/dex/uniswap-v2/uniswap-v2-gas-estimation.test.ts +98 -0
- package/src/dex/uniswap-v3/uniswap-v3-gas-estimation.test.ts +98 -0
- package/src/dex/usual/usual-gas-estimation.test.ts +54 -0
- package/src/dex/usual-pp/usual-pp-gas-estimation.test.ts +29 -0
- package/src/dex/weth/weth-gas-estimation.test.ts +42 -0
- package/src/dex/weth/weth.ts +3 -1
- package/src/dex/wombat/wombat-gas-estimation.test.ts +29 -0
- package/src/dex/wsteth/wsteth-gas-estimation.test.ts +41 -0
- package/src/dex/wusdm/wusdm-gas-estimation.test.ts +41 -0
- package/src/lib/pub-sub.ts +0 -27
- package/src/pricing-helper.ts +19 -11
- package/src/types.ts +1 -0
- package/tests/constants-e2e.ts +8 -0
- package/tests/tenderly-simulation-new.test.ts +151 -0
- package/tests/tenderly-simulation-new.ts +698 -0
- package/tests/token-storage-slots.json +532 -0
- package/tests/utils-e2e.ts +137 -1
|
@@ -28,14 +28,14 @@ import {
|
|
|
28
28
|
ClobSide,
|
|
29
29
|
DexalotData,
|
|
30
30
|
PairData,
|
|
31
|
-
PairDataMap,
|
|
32
|
-
PriceDataMap,
|
|
33
31
|
DexalotRfqError,
|
|
34
32
|
DexalotAPIParameters,
|
|
35
33
|
RFQResponse,
|
|
36
34
|
RFQResponseError,
|
|
37
|
-
TokenAddrDataMap,
|
|
38
35
|
TokenDataMap,
|
|
36
|
+
PairDataMap,
|
|
37
|
+
TokenAddrDataMap,
|
|
38
|
+
PriceDataMap,
|
|
39
39
|
} from './types';
|
|
40
40
|
import {
|
|
41
41
|
SlippageCheckError,
|
|
@@ -52,15 +52,10 @@ import {
|
|
|
52
52
|
DEXALOT_API_PRICES_POLLING_INTERVAL_MS,
|
|
53
53
|
DEXALOT_PRICES_CACHES_TTL_S,
|
|
54
54
|
DEXALOT_GAS_COST,
|
|
55
|
-
DEXALOT_PAIRS_CACHES_TTL_S,
|
|
56
55
|
DEXALOT_API_PAIRS_POLLING_INTERVAL_MS,
|
|
57
56
|
DEXALOT_TOKENS_CACHES_TTL_S,
|
|
58
57
|
DEXALOT_API_BLACKLIST_POLLING_INTERVAL_MS,
|
|
59
|
-
DEXALOT_RATE_LIMITED_TTL_S,
|
|
60
58
|
DEXALOT_MIN_SLIPPAGE_FACTOR_THRESHOLD_FOR_RESTRICTION,
|
|
61
|
-
DEXALOT_RESTRICTED_CACHE_KEY,
|
|
62
|
-
DEXALOT_RESTRICT_TTL_S,
|
|
63
|
-
DEXALOT_RATELIMIT_CACHE_VALUE,
|
|
64
59
|
DEXALOT_BLACKLIST_CACHES_TTL_S,
|
|
65
60
|
DEXALOT_FIRM_QUOTE_TIMEOUT_MS,
|
|
66
61
|
} from './constants';
|
|
@@ -130,7 +125,6 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
130
125
|
pricesReqParams: this.getAPIReqParams('api/rfq/prices', 'GET'),
|
|
131
126
|
blacklistReqParams: this.getAPIReqParams('api/rfq/blacklist', 'GET'),
|
|
132
127
|
pairsCacheKey: this.pairsCacheKey,
|
|
133
|
-
pairsCacheTTLSecs: DEXALOT_PAIRS_CACHES_TTL_S,
|
|
134
128
|
pricesCacheKey: this.pricesCacheKey,
|
|
135
129
|
pricesCacheTTLSecs: DEXALOT_PRICES_CACHES_TTL_S,
|
|
136
130
|
tokensAddrCacheKey: this.tokensAddrCacheKey,
|
|
@@ -144,10 +138,7 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
144
138
|
}
|
|
145
139
|
|
|
146
140
|
async initializePricing(blockNumber: number): Promise<void> {
|
|
147
|
-
|
|
148
|
-
this.rateFetcher.start();
|
|
149
|
-
}
|
|
150
|
-
|
|
141
|
+
this.rateFetcher.start();
|
|
151
142
|
return;
|
|
152
143
|
}
|
|
153
144
|
|
|
@@ -169,7 +160,7 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
169
160
|
return null;
|
|
170
161
|
}
|
|
171
162
|
|
|
172
|
-
const cachedTokens = (await this.getCachedTokens()) || {};
|
|
163
|
+
const cachedTokens = (await this.rateFetcher.getCachedTokens()) || {};
|
|
173
164
|
if (
|
|
174
165
|
!(normalizedSrcToken.address in cachedTokens) ||
|
|
175
166
|
!(normalizedDestToken.address in cachedTokens)
|
|
@@ -180,7 +171,7 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
180
171
|
normalizedDestToken.symbol =
|
|
181
172
|
cachedTokens[normalizedDestToken.address].symbol;
|
|
182
173
|
|
|
183
|
-
const cachedPairs = (await this.getCachedPairs()) || {};
|
|
174
|
+
const cachedPairs = (await this.rateFetcher.getCachedPairs()) || {};
|
|
184
175
|
|
|
185
176
|
const potentialPairs = [
|
|
186
177
|
{
|
|
@@ -228,7 +219,7 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
228
219
|
return [];
|
|
229
220
|
}
|
|
230
221
|
|
|
231
|
-
const tokensAddr = (await this.getCachedTokensAddr()) || {};
|
|
222
|
+
const tokensAddr = (await this.rateFetcher.getCachedTokensAddr()) || {};
|
|
232
223
|
|
|
233
224
|
return [
|
|
234
225
|
this.getIdentifier(
|
|
@@ -446,7 +437,7 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
446
437
|
const normalizedSrcToken = this.normalizeToken(srcToken);
|
|
447
438
|
const normalizedDestToken = this.normalizeToken(destToken);
|
|
448
439
|
|
|
449
|
-
this.tokensMap = (await this.getCachedTokens()) || {};
|
|
440
|
+
this.tokensMap = (await this.rateFetcher.getCachedTokens()) || {};
|
|
450
441
|
if (normalizedSrcToken.address === normalizedDestToken.address) {
|
|
451
442
|
return null;
|
|
452
443
|
}
|
|
@@ -463,7 +454,7 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
463
454
|
: await this.getPoolIdentifiers(srcToken, destToken, side, blockNumber);
|
|
464
455
|
|
|
465
456
|
pools = await Promise.all(
|
|
466
|
-
pools.map(async p => !(await this.isRestrictedPool(p))),
|
|
457
|
+
pools.map(async p => !(await this.rateFetcher.isRestrictedPool(p))),
|
|
467
458
|
).then(res => pools.filter((_v, i) => res[i]));
|
|
468
459
|
if (pools.length === 0) {
|
|
469
460
|
return null;
|
|
@@ -477,12 +468,12 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
477
468
|
return null;
|
|
478
469
|
}
|
|
479
470
|
|
|
480
|
-
const priceMap = await this.getCachedPrices();
|
|
471
|
+
const priceMap = await this.rateFetcher.getCachedPrices();
|
|
481
472
|
if (!priceMap) {
|
|
482
473
|
return null;
|
|
483
474
|
}
|
|
484
475
|
|
|
485
|
-
const tokensAddr = (await this.getCachedTokensAddr()) || {};
|
|
476
|
+
const tokensAddr = (await this.rateFetcher.getCachedTokensAddr()) || {};
|
|
486
477
|
const pairKey = `${pairData.base}/${pairData.quote}`.toLowerCase();
|
|
487
478
|
if (
|
|
488
479
|
!(pairKey in priceMap) ||
|
|
@@ -565,7 +556,7 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
565
556
|
side: SwapSide,
|
|
566
557
|
options: PreprocessTransactionOptions,
|
|
567
558
|
): Promise<[OptimalSwapExchange<DexalotData>, ExchangeTxInfo]> {
|
|
568
|
-
if (await this.isBlacklisted(options.txOrigin)) {
|
|
559
|
+
if (await this.rateFetcher.isBlacklisted(options.txOrigin)) {
|
|
569
560
|
this.logger.warn(
|
|
570
561
|
`${this.dexKey}-${this.network}: blacklisted TX Origin address '${options.txOrigin}' trying to build a transaction. Bailing...`,
|
|
571
562
|
);
|
|
@@ -735,9 +726,12 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
735
726
|
this.logger.warn(
|
|
736
727
|
`${this.dexKey}-${this.network}: Encountered rate limited user=${options.userAddress}. Adding to local rate limit cache`,
|
|
737
728
|
);
|
|
738
|
-
await this.setRateLimited(
|
|
729
|
+
await this.rateFetcher.setRateLimited(
|
|
730
|
+
options.userAddress,
|
|
731
|
+
errorData.RetryAfter,
|
|
732
|
+
);
|
|
739
733
|
} else {
|
|
740
|
-
await this.setBlacklist(options.userAddress);
|
|
734
|
+
await this.rateFetcher.setBlacklist(options.userAddress);
|
|
741
735
|
this.logger.error(
|
|
742
736
|
`${this.dexKey}-${this.network}: Failed to fetch RFQ for ${swapIdentifier}: ${errorData.Reason}`,
|
|
743
737
|
);
|
|
@@ -758,7 +752,9 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
758
752
|
`${this.dexKey}-${this.network}: protocol is restricted for pools ${poolIdentifiers} due to swap: ${swapIdentifier}`,
|
|
759
753
|
);
|
|
760
754
|
await Promise.all(
|
|
761
|
-
poolIdentifiers.map(
|
|
755
|
+
poolIdentifiers.map(
|
|
756
|
+
async p => await this.rateFetcher.restrictPool(p),
|
|
757
|
+
),
|
|
762
758
|
);
|
|
763
759
|
}
|
|
764
760
|
}
|
|
@@ -844,106 +840,6 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
844
840
|
};
|
|
845
841
|
}
|
|
846
842
|
|
|
847
|
-
getRestrictedPoolKey(poolIdentifier: string): string {
|
|
848
|
-
return `${DEXALOT_RESTRICTED_CACHE_KEY}-${poolIdentifier}`;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
async restrictPool(
|
|
852
|
-
poolIdentifier: string,
|
|
853
|
-
ttl: number = DEXALOT_RESTRICT_TTL_S,
|
|
854
|
-
): Promise<boolean> {
|
|
855
|
-
await this.dexHelper.cache.setex(
|
|
856
|
-
this.dexKey,
|
|
857
|
-
this.network,
|
|
858
|
-
this.getRestrictedPoolKey(poolIdentifier),
|
|
859
|
-
ttl,
|
|
860
|
-
'true',
|
|
861
|
-
);
|
|
862
|
-
return true;
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
async isRestrictedPool(poolIdentifier: string): Promise<boolean> {
|
|
866
|
-
const result = await this.dexHelper.cache.get(
|
|
867
|
-
this.dexKey,
|
|
868
|
-
this.network,
|
|
869
|
-
this.getRestrictedPoolKey(poolIdentifier),
|
|
870
|
-
);
|
|
871
|
-
|
|
872
|
-
return result === 'true';
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
async setBlacklist(
|
|
876
|
-
txOrigin: Address,
|
|
877
|
-
ttl: number = DEXALOT_BLACKLIST_CACHES_TTL_S,
|
|
878
|
-
): Promise<boolean> {
|
|
879
|
-
const cachedBlacklist = await this.dexHelper.cache.get(
|
|
880
|
-
this.dexKey,
|
|
881
|
-
this.network,
|
|
882
|
-
this.blacklistCacheKey,
|
|
883
|
-
);
|
|
884
|
-
|
|
885
|
-
let blacklist: string[] = [];
|
|
886
|
-
if (cachedBlacklist) {
|
|
887
|
-
blacklist = JSON.parse(cachedBlacklist);
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
blacklist.push(txOrigin.toLowerCase());
|
|
891
|
-
|
|
892
|
-
this.dexHelper.cache.setex(
|
|
893
|
-
this.dexKey,
|
|
894
|
-
this.network,
|
|
895
|
-
this.blacklistCacheKey,
|
|
896
|
-
ttl,
|
|
897
|
-
JSON.stringify(blacklist),
|
|
898
|
-
);
|
|
899
|
-
|
|
900
|
-
return true;
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
async isBlacklisted(txOrigin: Address): Promise<boolean> {
|
|
904
|
-
const cachedBlacklist = await this.dexHelper.cache.get(
|
|
905
|
-
this.dexKey,
|
|
906
|
-
this.network,
|
|
907
|
-
this.blacklistCacheKey,
|
|
908
|
-
);
|
|
909
|
-
|
|
910
|
-
if (cachedBlacklist) {
|
|
911
|
-
const blacklist = JSON.parse(cachedBlacklist) as string[];
|
|
912
|
-
return blacklist.includes(txOrigin.toLowerCase());
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
// To not show pricing for rate limited users
|
|
916
|
-
if (await this.isRateLimited(txOrigin)) {
|
|
917
|
-
return true;
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
return false;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
getRateLimitedKey(address: Address) {
|
|
924
|
-
return `rate_limited_${address}`.toLowerCase();
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
async isRateLimited(txOrigin: Address): Promise<boolean> {
|
|
928
|
-
const result = await this.dexHelper.cache.get(
|
|
929
|
-
this.dexKey,
|
|
930
|
-
this.network,
|
|
931
|
-
this.getRateLimitedKey(txOrigin),
|
|
932
|
-
);
|
|
933
|
-
return result === DEXALOT_RATELIMIT_CACHE_VALUE;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
async setRateLimited(txOrigin: Address, ttl = DEXALOT_RATE_LIMITED_TTL_S) {
|
|
937
|
-
await this.dexHelper.cache.setex(
|
|
938
|
-
this.dexKey,
|
|
939
|
-
this.network,
|
|
940
|
-
this.getRateLimitedKey(txOrigin),
|
|
941
|
-
ttl,
|
|
942
|
-
DEXALOT_RATELIMIT_CACHE_VALUE,
|
|
943
|
-
);
|
|
944
|
-
return true;
|
|
945
|
-
}
|
|
946
|
-
|
|
947
843
|
async getSimpleParam(
|
|
948
844
|
srcToken: string,
|
|
949
845
|
destToken: string,
|
|
@@ -1044,9 +940,9 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
1044
940
|
limit: number,
|
|
1045
941
|
): Promise<PoolLiquidity[]> {
|
|
1046
942
|
const normalizedTokenAddress = this.normalizeAddress(tokenAddress);
|
|
1047
|
-
const pairs = (await this.getCachedPairs()) || {};
|
|
1048
|
-
this.tokensMap = (await this.getCachedTokens()) || {};
|
|
1049
|
-
const tokensAddr = (await this.getCachedTokensAddr()) || {};
|
|
943
|
+
const pairs = (await this.rateFetcher.getCachedPairs()) || {};
|
|
944
|
+
this.tokensMap = (await this.rateFetcher.getCachedTokens()) || {};
|
|
945
|
+
const tokensAddr = (await this.rateFetcher.getCachedTokensAddr()) || {};
|
|
1050
946
|
const token = this.getTokenFromAddress(normalizedTokenAddress);
|
|
1051
947
|
if (!token) {
|
|
1052
948
|
return [];
|
|
@@ -1111,4 +1007,8 @@ export class Dexalot extends SimpleExchange implements IDex<DexalotData> {
|
|
|
1111
1007
|
this.rateFetcher.stop();
|
|
1112
1008
|
}
|
|
1113
1009
|
}
|
|
1010
|
+
|
|
1011
|
+
async isBlacklisted(userAddress: string): Promise<boolean> {
|
|
1012
|
+
return this.rateFetcher.isBlacklisted(userAddress);
|
|
1013
|
+
}
|
|
1114
1014
|
}
|
|
@@ -2,9 +2,11 @@ import { Network } from '../../constants';
|
|
|
2
2
|
import { IDexHelper } from '../../dex-helper';
|
|
3
3
|
import { Fetcher } from '../../lib/fetcher/fetcher';
|
|
4
4
|
import { validateAndCast } from '../../lib/validators';
|
|
5
|
-
import { Logger, Token } from '../../types';
|
|
5
|
+
import { Address, Logger, Token } from '../../types';
|
|
6
6
|
import {
|
|
7
7
|
DexalotBlacklistResponse,
|
|
8
|
+
TokenDataMap,
|
|
9
|
+
TokenAddrDataMap,
|
|
8
10
|
DexalotPairsResponse,
|
|
9
11
|
DexalotPricesResponse,
|
|
10
12
|
DexalotRateFetcherConfig,
|
|
@@ -16,13 +18,21 @@ import {
|
|
|
16
18
|
pairsResponseValidator,
|
|
17
19
|
pricesResponseValidator,
|
|
18
20
|
} from './validators';
|
|
21
|
+
import {
|
|
22
|
+
DEXALOT_BLACKLIST_CACHES_TTL_S,
|
|
23
|
+
DEXALOT_RATE_LIMITED_TTL_S,
|
|
24
|
+
DEXALOT_RATELIMIT_CACHE_VALUE,
|
|
25
|
+
DEXALOT_RESTRICT_TTL_S,
|
|
26
|
+
DEXALOT_RESTRICTED_CACHE_KEY,
|
|
27
|
+
} from './constants';
|
|
28
|
+
import { ExpKeyValuePubSub, NonExpSetPubSub } from '../../lib/pub-sub';
|
|
19
29
|
|
|
20
30
|
export class RateFetcher {
|
|
21
31
|
private pairsFetcher: Fetcher<DexalotPairsResponse>;
|
|
22
32
|
private pairsCacheKey: string;
|
|
23
|
-
private pairsCacheTTL: number;
|
|
24
33
|
|
|
25
34
|
private rateFetcher: Fetcher<DexalotPricesResponse>;
|
|
35
|
+
private rateTokensPubSub: ExpKeyValuePubSub;
|
|
26
36
|
private pricesCacheKey: string;
|
|
27
37
|
private pricesCacheTTL: number;
|
|
28
38
|
|
|
@@ -31,9 +41,12 @@ export class RateFetcher {
|
|
|
31
41
|
private tokensCacheTTL: number;
|
|
32
42
|
|
|
33
43
|
private blacklistFetcher: Fetcher<DexalotBlacklistResponse>;
|
|
44
|
+
private blacklistPubSub: NonExpSetPubSub;
|
|
34
45
|
private blacklistCacheKey: string;
|
|
35
46
|
private blacklistCacheTTL: number;
|
|
36
47
|
|
|
48
|
+
private restrictedPoolPubSub: ExpKeyValuePubSub;
|
|
49
|
+
|
|
37
50
|
constructor(
|
|
38
51
|
private dexHelper: IDexHelper,
|
|
39
52
|
private dexKey: string,
|
|
@@ -42,7 +55,6 @@ export class RateFetcher {
|
|
|
42
55
|
config: DexalotRateFetcherConfig,
|
|
43
56
|
) {
|
|
44
57
|
this.pairsCacheKey = config.rateConfig.pairsCacheKey;
|
|
45
|
-
this.pairsCacheTTL = config.rateConfig.pairsCacheTTLSecs;
|
|
46
58
|
this.pricesCacheKey = config.rateConfig.pricesCacheKey;
|
|
47
59
|
this.pricesCacheTTL = config.rateConfig.pricesCacheTTLSecs;
|
|
48
60
|
this.tokensAddrCacheKey = config.rateConfig.tokensAddrCacheKey;
|
|
@@ -51,6 +63,12 @@ export class RateFetcher {
|
|
|
51
63
|
this.blacklistCacheKey = config.rateConfig.blacklistCacheKey;
|
|
52
64
|
this.blacklistCacheTTL = config.rateConfig.blacklistCacheTTLSecs;
|
|
53
65
|
|
|
66
|
+
this.rateTokensPubSub = new ExpKeyValuePubSub(
|
|
67
|
+
dexHelper,
|
|
68
|
+
dexKey,
|
|
69
|
+
'rateTokens',
|
|
70
|
+
);
|
|
71
|
+
|
|
54
72
|
this.pairsFetcher = new Fetcher<DexalotPairsResponse>(
|
|
55
73
|
dexHelper.httpRequest,
|
|
56
74
|
{
|
|
@@ -87,6 +105,7 @@ export class RateFetcher {
|
|
|
87
105
|
logger,
|
|
88
106
|
);
|
|
89
107
|
|
|
108
|
+
this.blacklistPubSub = new NonExpSetPubSub(dexHelper, dexKey, 'blacklist');
|
|
90
109
|
this.blacklistFetcher = new Fetcher<DexalotBlacklistResponse>(
|
|
91
110
|
dexHelper.httpRequest,
|
|
92
111
|
{
|
|
@@ -104,12 +123,30 @@ export class RateFetcher {
|
|
|
104
123
|
config.rateConfig.blacklistIntervalMs,
|
|
105
124
|
logger,
|
|
106
125
|
);
|
|
126
|
+
|
|
127
|
+
this.restrictedPoolPubSub = new ExpKeyValuePubSub(
|
|
128
|
+
dexHelper,
|
|
129
|
+
dexKey,
|
|
130
|
+
'restricted-pool',
|
|
131
|
+
// using default value, we can lazy load non-restricted pools
|
|
132
|
+
// and restrict them by subscribing to this channel
|
|
133
|
+
'false',
|
|
134
|
+
DEXALOT_RESTRICT_TTL_S,
|
|
135
|
+
);
|
|
107
136
|
}
|
|
108
137
|
|
|
109
|
-
start() {
|
|
110
|
-
this.
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
async start() {
|
|
139
|
+
if (!this.dexHelper.config.isSlave) {
|
|
140
|
+
this.pairsFetcher.startPolling();
|
|
141
|
+
this.rateFetcher.startPolling();
|
|
142
|
+
this.blacklistFetcher.startPolling();
|
|
143
|
+
} else {
|
|
144
|
+
this.rateTokensPubSub.subscribe();
|
|
145
|
+
this.restrictedPoolPubSub.subscribe();
|
|
146
|
+
|
|
147
|
+
const initSet = await this.getAllBlacklisted();
|
|
148
|
+
this.blacklistPubSub.initializeAndSubscribe(initSet);
|
|
149
|
+
}
|
|
113
150
|
}
|
|
114
151
|
|
|
115
152
|
stop() {
|
|
@@ -145,7 +182,7 @@ export class RateFetcher {
|
|
|
145
182
|
this.dexKey,
|
|
146
183
|
this.network,
|
|
147
184
|
this.pairsCacheKey,
|
|
148
|
-
this.
|
|
185
|
+
this.tokensCacheTTL,
|
|
149
186
|
JSON.stringify(dexPairs),
|
|
150
187
|
);
|
|
151
188
|
|
|
@@ -164,6 +201,15 @@ export class RateFetcher {
|
|
|
164
201
|
this.tokensCacheTTL,
|
|
165
202
|
JSON.stringify(tokenAddrMap),
|
|
166
203
|
);
|
|
204
|
+
|
|
205
|
+
this.rateTokensPubSub.publish(
|
|
206
|
+
{
|
|
207
|
+
[this.pairsCacheKey]: dexPairs,
|
|
208
|
+
[this.tokensCacheKey]: tokenMap,
|
|
209
|
+
[this.tokensAddrCacheKey]: tokenAddrMap,
|
|
210
|
+
},
|
|
211
|
+
this.tokensCacheTTL,
|
|
212
|
+
);
|
|
167
213
|
}
|
|
168
214
|
|
|
169
215
|
private handleRatesResponse(resp: DexalotPricesResponse): void {
|
|
@@ -180,18 +226,182 @@ export class RateFetcher {
|
|
|
180
226
|
this.pricesCacheTTL,
|
|
181
227
|
JSON.stringify(dexPrices),
|
|
182
228
|
);
|
|
229
|
+
|
|
230
|
+
this.rateTokensPubSub.publish(
|
|
231
|
+
{ [this.pricesCacheKey]: dexPrices },
|
|
232
|
+
this.pricesCacheTTL,
|
|
233
|
+
);
|
|
183
234
|
}
|
|
184
235
|
|
|
185
236
|
private async handleBlacklistResponse(
|
|
186
237
|
resp: DexalotBlacklistResponse,
|
|
187
238
|
): Promise<void> {
|
|
188
239
|
const { blacklist } = resp;
|
|
240
|
+
const data = blacklist.map(item => item.toLowerCase());
|
|
189
241
|
this.dexHelper.cache.setex(
|
|
190
242
|
this.dexKey,
|
|
191
243
|
this.network,
|
|
192
244
|
this.blacklistCacheKey,
|
|
193
245
|
this.blacklistCacheTTL,
|
|
194
|
-
JSON.stringify(
|
|
246
|
+
JSON.stringify(data),
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
this.blacklistPubSub.publish(data);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async getCachedTokens(): Promise<TokenDataMap | null> {
|
|
253
|
+
const cachedTokens = await this.rateTokensPubSub.getAndCache(
|
|
254
|
+
this.tokensCacheKey,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
if (cachedTokens) {
|
|
258
|
+
return cachedTokens as TokenDataMap;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async getCachedPairs(): Promise<PairDataMap | null> {
|
|
265
|
+
const cachedPairs = await this.rateTokensPubSub.getAndCache(
|
|
266
|
+
this.pairsCacheKey,
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
if (cachedPairs) {
|
|
270
|
+
return cachedPairs as PairDataMap;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async getCachedTokensAddr(): Promise<TokenAddrDataMap | null> {
|
|
277
|
+
const cachedTokensAddr = await this.rateTokensPubSub.getAndCache(
|
|
278
|
+
this.tokensAddrCacheKey,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
if (cachedTokensAddr) {
|
|
282
|
+
return cachedTokensAddr as TokenAddrDataMap;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async setBlacklist(
|
|
289
|
+
txOrigin: Address,
|
|
290
|
+
ttl: number = DEXALOT_BLACKLIST_CACHES_TTL_S,
|
|
291
|
+
): Promise<boolean> {
|
|
292
|
+
const blacklist = await this.getAllBlacklisted();
|
|
293
|
+
|
|
294
|
+
blacklist.push(txOrigin.toLowerCase());
|
|
295
|
+
|
|
296
|
+
this.dexHelper.cache.setex(
|
|
297
|
+
this.dexKey,
|
|
298
|
+
this.network,
|
|
299
|
+
this.blacklistCacheKey,
|
|
300
|
+
ttl,
|
|
301
|
+
JSON.stringify(blacklist),
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
this.blacklistPubSub.publish([txOrigin.toLowerCase()]);
|
|
305
|
+
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async getAllBlacklisted(): Promise<string[]> {
|
|
310
|
+
const cachedBlacklist = await this.dexHelper.cache.get(
|
|
311
|
+
this.dexKey,
|
|
312
|
+
this.network,
|
|
313
|
+
this.blacklistCacheKey,
|
|
195
314
|
);
|
|
315
|
+
|
|
316
|
+
if (cachedBlacklist) {
|
|
317
|
+
return JSON.parse(cachedBlacklist);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async isBlacklisted(txOrigin: Address): Promise<boolean> {
|
|
324
|
+
const blacklisted = await this.blacklistPubSub.has(txOrigin.toLowerCase());
|
|
325
|
+
|
|
326
|
+
return blacklisted;
|
|
327
|
+
|
|
328
|
+
/*
|
|
329
|
+
rate-limit check was only if blacklist data set was not available,
|
|
330
|
+
in the current implementation it should not be the case,
|
|
331
|
+
so skip next check
|
|
332
|
+
*/
|
|
333
|
+
// To not show pricing for rate limited users
|
|
334
|
+
if (await this.isRateLimited(txOrigin)) {
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
async setRateLimited(txOrigin: Address, ttl = DEXALOT_RATE_LIMITED_TTL_S) {
|
|
342
|
+
await this.dexHelper.cache.setex(
|
|
343
|
+
this.dexKey,
|
|
344
|
+
this.network,
|
|
345
|
+
this.getRateLimitedKey(txOrigin),
|
|
346
|
+
ttl,
|
|
347
|
+
DEXALOT_RATELIMIT_CACHE_VALUE,
|
|
348
|
+
);
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
async isRateLimited(txOrigin: Address): Promise<boolean> {
|
|
353
|
+
const result = await this.dexHelper.cache.get(
|
|
354
|
+
this.dexKey,
|
|
355
|
+
this.network,
|
|
356
|
+
this.getRateLimitedKey(txOrigin),
|
|
357
|
+
);
|
|
358
|
+
return result === DEXALOT_RATELIMIT_CACHE_VALUE;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
getRateLimitedKey(address: Address) {
|
|
362
|
+
return `rate_limited_${address}`.toLowerCase();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async getCachedPrices(): Promise<PriceDataMap | null> {
|
|
366
|
+
const cachedPrices = await this.rateTokensPubSub.getAndCache(
|
|
367
|
+
this.pricesCacheKey,
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
if (cachedPrices) {
|
|
371
|
+
return cachedPrices as PriceDataMap;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async restrictPool(
|
|
378
|
+
poolIdentifier: string,
|
|
379
|
+
ttl: number = DEXALOT_RESTRICT_TTL_S,
|
|
380
|
+
): Promise<boolean> {
|
|
381
|
+
await this.dexHelper.cache.setex(
|
|
382
|
+
this.dexKey,
|
|
383
|
+
this.network,
|
|
384
|
+
this.getRestrictedPoolKey(poolIdentifier),
|
|
385
|
+
ttl,
|
|
386
|
+
'true',
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
await this.restrictedPoolPubSub.publish(
|
|
390
|
+
{ [this.getRestrictedPoolKey(poolIdentifier)]: 'true' },
|
|
391
|
+
ttl,
|
|
392
|
+
);
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async isRestrictedPool(poolIdentifier: string): Promise<boolean> {
|
|
397
|
+
const result = await this.restrictedPoolPubSub.getAndCache(
|
|
398
|
+
this.getRestrictedPoolKey(poolIdentifier),
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
return result === 'true';
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
getRestrictedPoolKey(poolIdentifier: string): string {
|
|
405
|
+
return `${DEXALOT_RESTRICTED_CACHE_KEY}-${poolIdentifier}`;
|
|
196
406
|
}
|
|
197
407
|
}
|
package/src/dex/dexalot/types.ts
CHANGED
|
@@ -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('FluidDex Gas Estimation', () => {
|
|
9
|
+
const dexKey = 'FluidDex';
|
|
10
|
+
const network = Network.MAINNET;
|
|
11
|
+
|
|
12
|
+
describe('swapExactAmountIn', () => {
|
|
13
|
+
const USDC = Tokens[network]['USDC'];
|
|
14
|
+
const USDT = Tokens[network]['USDT'];
|
|
15
|
+
const amount = 10000n;
|
|
16
|
+
|
|
17
|
+
it('swapIn', async () => {
|
|
18
|
+
await testGasEstimation(
|
|
19
|
+
network,
|
|
20
|
+
USDC,
|
|
21
|
+
USDT,
|
|
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('FxProtocolRusd Gas Estimation', () => {
|
|
9
|
+
const dexKey = 'FxProtocolRusd';
|
|
10
|
+
const network = Network.MAINNET;
|
|
11
|
+
|
|
12
|
+
describe('swapExactAmountIn', () => {
|
|
13
|
+
const weETH = Tokens[network]['weETH'];
|
|
14
|
+
const rUSD = Tokens[network]['rUSD'];
|
|
15
|
+
const amount = 1000000000000000000n;
|
|
16
|
+
|
|
17
|
+
it('mint', async () => {
|
|
18
|
+
await testGasEstimation(
|
|
19
|
+
network,
|
|
20
|
+
weETH,
|
|
21
|
+
rUSD,
|
|
22
|
+
amount,
|
|
23
|
+
SwapSide.SELL,
|
|
24
|
+
dexKey,
|
|
25
|
+
ContractMethodV6.swapExactAmountIn,
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|