Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 66 additions & 8 deletions scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,74 @@ const parseFilePath = filePath => {
};

/**
* Fetches events in batches to avoid RPC limitations.
* All batches are fetched in parallel for better performance.
* Runs async tasks with a concurrency limit to avoid overwhelming the RPC.
*
* @param {Array<{ fromBlock: number, toBlock: number }>} items - Items to process.
* @param {number} concurrency - Max number of concurrent tasks.
* @param {function} fn - Async function (item) => Promise<ethers.Event[]>
* @param {number} [retries=2] - Number of retries per batch on failure.
* @returns {Promise<ethers.Event[][]>} Results per batch.
*/
const runWithConcurrency = async (items, concurrency, fn, retries = 2) => {
const results = [];
let index = 0;

const runNext = async () => {
if (index >= items.length) {
return;
}
const currentIndex = index++;
const item = items[currentIndex];
let lastError;
for (let attempt = 0; attempt <= retries; attempt++) {
try {
const result = await fn(item);
results[currentIndex] = result;
return;
} catch (err) {
lastError = err;
if (attempt < retries) {
const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError;
};

const workers = Array.from({ length: Math.min(concurrency, items.length) }, () =>
(async () => {
while (index < items.length) {
await runNext();
}
})(),
);
await Promise.all(workers);
return results;
};

/**
* Fetches events in batches to avoid RPC limitations and timeouts.
* Uses limited concurrency and smaller batches to reduce per-request load and retries on failure.
*
* @param {ethers.Contract} contract - The contract to query events from.
* @param {ethers.EventFilter} eventFilter - The event filter to apply.
* @param {number} startBlock - The starting block number.
* @param {ethers.providers.Provider} provider - The Ethereum provider to interact with the blockchain.
* @param {number} [batchSize=10000] - The number of blocks to query per batch.
* @param {number} [batchSize=5000] - The number of blocks to query per batch (smaller = less timeout risk).
* @param {number} [concurrency=5] - Max concurrent batch requests (avoids overwhelming the RPC).
* @param {number} [retries=2] - Retries per batch with exponential backoff on failure.
* @returns {Promise<ethers.Event[]>} A promise that resolves to an array of events.
*/
const fetchEventsInBatches = async (contract, eventFilter, startBlock, provider, batchSize = 10_000) => {
const fetchEventsInBatches = async (
contract,
eventFilter,
startBlock,
provider,
batchSize = 5000,
concurrency = 5,
retries = 2,
) => {
const endBlock = await provider.getBlockNumber();
const batches = [];

Expand All @@ -99,10 +156,11 @@ const fetchEventsInBatches = async (contract, eventFilter, startBlock, provider,
batches.push({ fromBlock, toBlock });
}

const batchResults = await Promise.all(
batches.map(({ fromBlock, toBlock }) => {
return contract.queryFilter(eventFilter, fromBlock, toBlock);
}),
const batchResults = await runWithConcurrency(
batches,
concurrency,
({ fromBlock, toBlock }) => contract.queryFilter(eventFilter, fromBlock, toBlock),
retries,
);

return batchResults.flat();
Expand Down
5 changes: 5 additions & 0 deletions src/constants/privateProducts.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ const allPrivateProductsIds = [
403, // TermMax
405, // OpenCover YoUSD
406, // Teller
409, // OpenCover WETH SuperVault
410, // OpenCover Base USDC SuperVault
411, // OpenCover WBTC SuperVault
412, // OpenCover Steakhouse HYI USDC Base
413, // OpenCover Steakhouse USDC
];

module.exports = {
Expand Down
2 changes: 2 additions & 0 deletions src/constants/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,4 +397,6 @@ export const productCategoryMap: { [productId: number]: ProductCategoryEnum } =
388: ProductCategoryEnum.Dex, // Hybra Finance
391: ProductCategoryEnum.YieldOptimizer, // IPOR
404: ProductCategoryEnum.Custody, // BingX Custody
407: ProductCategoryEnum.Custody, // HTX Custody
408: ProductCategoryEnum.Lending, // Venus Flux
};
Binary file added src/logos/407-htx.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions src/logos/408-venus-flux.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions src/logos/409-open-cover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions src/logos/410-open-cover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions src/logos/411-open-cover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions src/logos/412-open-cover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading