diff --git a/src/helpers/environment/Environment/Environment.ts b/src/helpers/environment/Environment/Environment.ts index a4aa20def..e34213489 100644 --- a/src/helpers/environment/Environment/Environment.ts +++ b/src/helpers/environment/Environment/Environment.ts @@ -157,12 +157,12 @@ export class Environment { case NetworkId.MAINNET: return this._get({ key: `VITE_ETHEREUM_ARCHIVE_NODE_URL`, - fallback: "https://rpc.ankr.com/eth", + fallback: "https://eth.merkle.io", }); default: return this._get({ key: `VITE_ETHEREUM_ARCHIVE_NODE_URL`, - fallback: "https://rpc.ankr.com/eth", + fallback: "https://eth.merkle.io", }); } }; diff --git a/src/views/Governance/hooks/useGetProposals.tsx b/src/views/Governance/hooks/useGetProposals.tsx index c9ac953e7..ab1e7f3e7 100644 --- a/src/views/Governance/hooks/useGetProposals.tsx +++ b/src/views/Governance/hooks/useGetProposals.tsx @@ -3,36 +3,72 @@ import { GOVERNANCE_CONTRACT } from "src/constants/contracts"; import { Environment } from "src/helpers/environment/Environment/Environment"; import { Providers } from "src/helpers/providers/Providers/Providers"; import { NetworkId } from "src/networkDetails"; +import { OlympusGovernorBravo__factory } from "src/typechain"; import { ProposalCreatedEventObject } from "src/typechain/OlympusGovernorBravo"; export const useGetProposals = () => { const archiveProvider = Providers.getArchiveStaticProvider(NetworkId.MAINNET); - const contract = GOVERNANCE_CONTRACT.getEthersContract(NetworkId.MAINNET); + // const contract = GOVERNANCE_CONTRACT.getEthersContract(NetworkId.MAINNET); + const contractAddress = GOVERNANCE_CONTRACT.addresses[NetworkId.MAINNET]; + const contract = OlympusGovernorBravo__factory.connect(contractAddress, archiveProvider); + return useQuery( ["getProposals", NetworkId.MAINNET], async () => { - // using EVENTS - const proposalCreatedEvents = await contract.queryFilter( - contract.filters.ProposalCreated(), - Environment.getGovernanceStartBlock(), - ); - - const proposals = Promise.all( - proposalCreatedEvents.map(async item => { + const proposals: { createdAtBlock: Date; details: ProposalCreatedEventObject; title: string; txHash: string }[] = + []; + let blockNumber = await archiveProvider.getBlockNumber(); + const startBlock = Environment.getGovernanceStartBlock(); + const chunkSize = 10000; //RPC limit + // Fetch the last proposal ID + const lastProposalId = (await contract.proposalCount()).toNumber(); + + // If there are no proposals, return an empty array + if (lastProposalId === 0) { + console.log("No proposals found."); + return proposals; + } + let foundProposalId1 = false; + + while (blockNumber > startBlock && !foundProposalId1) { + const fromBlock = Math.max(blockNumber - chunkSize, startBlock); + + const proposalCreatedEvents = await contract.queryFilter( + contract.filters.ProposalCreated(), + fromBlock, + blockNumber, + ); + + // Process each event + for (const item of proposalCreatedEvents) { const timestamp = (await archiveProvider.getBlock(item.blockNumber)).timestamp; + if (item.decode) { const details = { ...item.decode(item.data), values: item.args[3] } as ProposalCreatedEventObject; - return { + + // Stop if we hit proposal ID 1 + if (Number(details.id) === 1) { + foundProposalId1 = true; + break; + } + + proposals.push({ createdAtBlock: new Date(timestamp * 1000), details, title: details.description.split(/#+\s|\n/g)[1] || `${details.description.slice(0, 20)}...`, txHash: item.transactionHash, - }; + }); } - }), - ); + } + + // Move to the next block range (going backwards) + blockNumber = fromBlock - 1; + } + console.log("Proposals found:", proposals.length); + return proposals; }, + { enabled: !!archiveProvider && !!contract }, ); };