@merkl/api 0.10.344 → 0.10.345

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.
@@ -1,9 +1,8 @@
1
1
  import { log } from "../../../utils/logger";
2
- import { providers } from "../../../utils/providers";
3
- import { getContractCreationBlock } from "@sdk";
2
+ import { ChainId, ChainInteractionService, getContractCreationBlock } from "@sdk";
4
3
  import axios from "axios";
5
4
  async function fetchLogs(chainId, topics, addresses, fromBlock, toBlock) {
6
- const url = providers[chainId].connection.url;
5
+ const url = ChainInteractionService(chainId).provider().connection.url;
7
6
  if (fromBlock === undefined || fromBlock === null || !toBlock || fromBlock > toBlock) {
8
7
  throw new Error(`fromBlock and toBlock are required and fromBlock must be less than toBlock - fromBlock: ${fromBlock} - toBlock:${toBlock}`);
9
8
  }
@@ -12,7 +11,7 @@ async function fetchLogs(chainId, topics, addresses, fromBlock, toBlock) {
12
11
  let contractCreationBlock = toBlock;
13
12
  for (const address of addresses) {
14
13
  try {
15
- const aux = await getContractCreationBlock(address, providers[chainId]);
14
+ const aux = await getContractCreationBlock(address, ChainInteractionService(chainId).provider());
16
15
  if (aux < contractCreationBlock) {
17
16
  contractCreationBlock = aux;
18
17
  }
@@ -34,8 +33,10 @@ async function fetchLogs(chainId, topics, addresses, fromBlock, toBlock) {
34
33
  let step = tempToBlock - tempFromBlock;
35
34
  // Binary search to fetch logs and avoid errors
36
35
  let logs = [];
36
+ // Binary search to fetch logs and avoid errors
37
37
  let isRateLimitingError = false;
38
- // let stepLimited = false;
38
+ let stepLimited = false;
39
+ const maxLogsPerRequest = 10_000;
39
40
  while (true) {
40
41
  try {
41
42
  const data = {
@@ -62,6 +63,15 @@ async function fetchLogs(chainId, topics, addresses, fromBlock, toBlock) {
62
63
  if (res.data.error?.code === 413) {
63
64
  throw new Error("Request entity too large");
64
65
  }
66
+ if (res.data.error?.code === -32000 && chainId === ChainId.AVALANCHE) {
67
+ stepLimited = true;
68
+ step = 2047 * 2;
69
+ throw new Error("Block width exceeded");
70
+ }
71
+ if (res.data.error?.code === -32000 && chainId === ChainId.BSC) {
72
+ // Reall error is: " block not found x"
73
+ throw new Error("Log size exceeded");
74
+ }
65
75
  // Check if we hit the maximum log limit for a single call
66
76
  if (res.data.result?.length === 10000)
67
77
  throw new Error("Log size exceeded");
@@ -69,10 +79,35 @@ async function fetchLogs(chainId, topics, addresses, fromBlock, toBlock) {
69
79
  logs = logs.concat(...logsBatch);
70
80
  const batchSize = logsBatch.length;
71
81
  const blockRange = tempToBlock - tempFromBlock + 1;
82
+ if (!stepLimited) {
83
+ if (batchSize === 0) {
84
+ // Add safeguard for 0 logs case
85
+ // If no logs found, increase step size
86
+ step = Math.floor(step * 2);
87
+ }
88
+ else {
89
+ // Aggressive adjustment based on how far we are from optimal logs per request
90
+ const optimalLogsPerRequest = maxLogsPerRequest * 0.7; // Target 70% of max logs per request
91
+ const logsPerRequestRatio = batchSize / optimalLogsPerRequest;
92
+ if (batchSize < maxLogsPerRequest * 0.8) {
93
+ // More aggressive adjustment when far from target
94
+ const adjustmentFactor = (1 / logsPerRequestRatio) ** 0.7; // Non-linear scaling
95
+ step = Math.floor(step * adjustmentFactor);
96
+ // Allow for larger jumps when log density is very low
97
+ if (logsPerRequestRatio < 0.2) {
98
+ step = Math.floor(step * 2);
99
+ }
100
+ }
101
+ else {
102
+ // Quick reduction when close to limit
103
+ step = Math.floor(step * 0.4);
104
+ }
105
+ }
106
+ }
72
107
  log.local(`fetched ${batchSize} logs between blocks ${tempFromBlock} and ${tempToBlock} (block range: ${blockRange})`);
73
108
  }
74
109
  catch (e) {
75
- if (e instanceof Error && e.toString() === "Error: Request failed with status code 429") {
110
+ if (e.toString() === "Error: Request failed with status code 429") {
76
111
  isRateLimitingError = true;
77
112
  }
78
113
  if (isRateLimitingError) {
@@ -97,7 +132,7 @@ async function fetchLogs(chainId, topics, addresses, fromBlock, toBlock) {
97
132
  isRateLimitingError = false;
98
133
  }
99
134
  if (step === 0) {
100
- log.error("❌ fetchLogs", `error fetching logs for ${addresses}`);
135
+ log.error("❌ fetchLogs", `error fetching logs for ${addresses} on ${ChainId[chainId]}`);
101
136
  return { logs, block: tempFromBlock };
102
137
  }
103
138
  tempToBlock = tempFromBlock + step;
@@ -16,7 +16,7 @@ async function getCompoundV2ForksVaults() {
16
16
  if ([ChainId.LINEA].includes(chainId)) {
17
17
  continue;
18
18
  }
19
- log.local(`Fetching Compound V2 vaults for chainId ${ChainId[chainId]} and compFork ${CompFork[compFork]}`);
19
+ log.local(`Fetching Compound V2 vaults on ${ChainId[chainId]}, for ${CompFork[compFork]}`);
20
20
  const toBlock = await providers[chainId].getBlockNumber();
21
21
  const comptrollerAddress = Comptrollers[compFork][chainId];
22
22
  if (!comptrollerAddress) {
@@ -24,7 +24,9 @@ async function getCompoundV2ForksVaults() {
24
24
  }
25
25
  const creationBlock = (await getContractCreationBlock(comptrollerAddress, providers[chainId])) ?? 0;
26
26
  let logs = [];
27
- const topic = compFork === CompFork.Venus ? MARKET_SUPPORTED_EVENT_HASH : MARKET_LISTED_EVENT_HASH;
27
+ const topic = compFork === CompFork.Venus && chainId === ChainId.ZKSYNC
28
+ ? MARKET_SUPPORTED_EVENT_HASH
29
+ : MARKET_LISTED_EVENT_HASH;
28
30
  logs = await safeFetchLogs(chainId, [topic], [comptrollerAddress], creationBlock, toBlock);
29
31
  if (compFork === CompFork.Ionic && chainId === ChainId.MODE) {
30
32
  const isolatedIonicMarketUnitroller = "0x8Fb3D4a94D0aA5D6EDaAC3Ed82B59a27f56d923a";
@@ -33,9 +35,11 @@ async function getCompoundV2ForksVaults() {
33
35
  logs = logs.concat(isolatedMarketLogs);
34
36
  }
35
37
  const vaults = Object.keys(logs.reduce((acc, transfer) => {
36
- const [cToken] = defaultAbiCoder.decode(["address"], transfer.data);
37
- if (!!cToken) {
38
- acc[cToken] = true;
38
+ if (transfer.data !== "0x") {
39
+ const [cToken] = defaultAbiCoder.decode(["address"], transfer.data);
40
+ if (!!cToken) {
41
+ acc[cToken] = true;
42
+ }
39
43
  }
40
44
  return acc;
41
45
  }, {}));