Governance: Listing proposals

I have been using the Open Zeppelin Governance contracts with great success.

I was wondering if there is a way to list the proposals that have been stored in a governor contract? For now, I need to produce a hash to retrieve a single proposal. I see there is an internal _proposals store but there is no way to iterate through these proposals externally?

Otherwise, will I need to externally store proposal descriptions and/or hashes to be able to access Governor proposals? What is the convention for storing these? Swarm/IPFS? A centralized db?

Thanks for any help

Hi @haydeny. Sorry for the delay in answering.

You can list proposals by filtering the ProposalCreated event. You can also find the details for a proposal id by specifying the proposalId in the event filter. The way you do this depends on whether you're using Web3.js or Ethers.js.

Hi @frangio , I tried to do the same thing. Listing proposal from a Governor Contract same as Tally did.
I read your answer but still did not get it.
ProposalCreated event has no "indexed" parameter, how can it be filtered ?

Also I did not understand, when you said it can list proposal, since it did not return any list of proposals. But just a proposal which is just created. Am I wrong ?

@haydeny Could you please let me know how to do it, in case you already succeed ?

My bad. For compatibility with GovernorBravo the proposalId is not indexed.

But you can filter by the event selector to get all ProposalCreated events.

1 Like

Thanks @frangio I will try this out. I think I ran into the same problem as @Charles808, i.e. that nothing was indexed in the ProposalCreated event. Will implement what you've suggested and post here if successful.

1 Like

@Charles808 I ended up using @frangio 's recommendation to retrieve all the ProposalCreated events and then looping through the events, filtering them using the proposalId.

So, using ethers.js, something like the following has worked for me:

  const filters = await governance.filters.ProposalCreated();
  const logs = await governance.queryFilter(filters, 0, "latest");
  const events = logs.map((log) => governance.interface.parseLog(log));

This gets me a list of events using the ethers.Contract's filters property (I assume this receives ProposalCreated only for my contract):

  const filteredEvents = events.filter(event => event.args.proposalId.eq(proposalId));
  const filteredEvent = filteredEvents.pop();
  const args = filteredEvent.args;

This gets me the attributes of a proposal where proposalId is some valid proposal identifier. One option is to pull this identifier by looping through the events and getting the object's proposalId variable.

I did have some trouble getting the values so had to retrieve using the numerical index:

args.values doesn't work. values: Object.values(args[3]) does.

1 Like