@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.
- package/build/config.js +4 -2
- package/build/config.js.map +1 -1
- package/build/dex/algebra/config.js +0 -16
- package/build/dex/algebra/config.js.map +1 -1
- package/build/dex/curve-v1-factory/config.js +128 -11
- package/build/dex/curve-v1-factory/config.js.map +1 -1
- package/build/dex/curve-v1-factory/curve-v1-factory.d.ts +1 -0
- package/build/dex/curve-v1-factory/curve-v1-factory.js +29 -17
- package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.js +1 -0
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js +4 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/constants.js +10 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/constants.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js +40 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js +24 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js +53 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/utils.d.ts +1 -0
- package/build/dex/curve-v1-factory/price-handlers/functions/utils.js +5 -1
- package/build/dex/curve-v1-factory/price-handlers/functions/utils.js.map +1 -1
- package/build/dex/curve-v1-factory/price-handlers/types.d.ts +2 -2
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.d.ts +3 -2
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js +38 -6
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/pool-polling-base.js.map +1 -1
- package/build/dex/curve-v1-factory/types.d.ts +11 -2
- package/build/dex/curve-v1-factory/types.js +3 -0
- package/build/dex/curve-v1-factory/types.js.map +1 -1
- package/build/dex/dexalot/config.js +7 -0
- package/build/dex/dexalot/config.js.map +1 -1
- package/build/dex/hashflow/constants.d.ts +27 -0
- package/build/dex/hashflow/constants.js +29 -1
- package/build/dex/hashflow/constants.js.map +1 -1
- package/build/dex/hashflow/hashflow.d.ts +3 -2
- package/build/dex/hashflow/hashflow.js +69 -12
- package/build/dex/hashflow/hashflow.js.map +1 -1
- package/build/dex/hashflow/types.d.ts +11 -0
- package/build/dex/hashflow/types.js +9 -0
- package/build/dex/hashflow/types.js.map +1 -1
- package/build/dex/idex.d.ts +1 -1
- package/build/dex/index.d.ts +2 -2
- package/build/dex/pancakeswap-v3/config.js +30 -0
- package/build/dex/pancakeswap-v3/config.js.map +1 -1
- package/build/dex/pancakeswap-v3/pancakeswap-v3.js +5 -1
- package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +1 -1
- package/build/dex/woo-fi-v2/config.js +4 -4
- package/package.json +1 -1
- package/src/config.ts +4 -2
- package/src/dex/algebra/config.ts +0 -18
- package/src/dex/curve-v1-factory/config.ts +128 -11
- package/src/dex/curve-v1-factory/curve-v1-factory-e2e.test.ts +123 -1
- package/src/dex/curve-v1-factory/curve-v1-factory-integration.test.ts +392 -0
- package/src/dex/curve-v1-factory/curve-v1-factory.ts +61 -39
- package/src/dex/curve-v1-factory/curve-v1-pool-manager.ts +1 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.ts +6 -2
- package/src/dex/curve-v1-factory/price-handlers/functions/_rates.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/_xp.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/_xp_mem.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/constants.ts +11 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/get_D.ts +59 -1
- package/src/dex/curve-v1-factory/price-handlers/functions/get_D_mem.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/get_dy.ts +51 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/get_y.ts +68 -1
- package/src/dex/curve-v1-factory/price-handlers/functions/get_y_D.ts +2 -0
- package/src/dex/curve-v1-factory/price-handlers/functions/utils.ts +4 -0
- package/src/dex/curve-v1-factory/price-handlers/types.ts +8 -1
- package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +71 -18
- package/src/dex/curve-v1-factory/state-polling-pools/pool-polling-base.ts +1 -0
- package/src/dex/curve-v1-factory/types.ts +12 -1
- package/src/dex/dexalot/config.ts +7 -0
- package/src/dex/dexalot/dexalot-e2e.test.ts +23 -1
- package/src/dex/dexalot/dexalot-integration.test.ts +121 -0
- package/src/dex/hashflow/constants.ts +32 -0
- package/src/dex/hashflow/hashflow.ts +121 -19
- package/src/dex/hashflow/types.ts +20 -2
- package/src/dex/idex.ts +1 -1
- package/src/dex/index.ts +2 -2
- package/src/dex/pancakeswap-v3/config.ts +32 -0
- package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +21 -0
- package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +7 -1
- package/src/dex/woo-fi-v2/config.ts +4 -4
- package/tests/constants-e2e.ts +38 -3
- package/tests/utils-e2e.ts +1 -0
- 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
|
-
|
|
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.
|
|
742
|
-
|
|
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
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
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
|
|
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,
|
|
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 |
|
|
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(
|
|
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: '
|
|
19
|
-
wooOracleV2Address: '
|
|
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: '
|
|
59
|
-
wooOracleV2Address: '
|
|
58
|
+
wooPPV2Address: '0xEd9e3f98bBed560e66B89AaC922E29D4596A9642',
|
|
59
|
+
wooOracleV2Address: '0x2A375567f5E13F6bd74fDa7627Df3b1Af6BfA5a6',
|
|
60
60
|
integrationHelperAddress: '0x020630613E296c3E9b06186f630D1bF97A2B6Ad1',
|
|
61
61
|
// USDC
|
|
62
62
|
quoteToken: {
|
package/tests/constants-e2e.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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: '
|
|
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',
|