openzeppelin-contracts icon indicating copy to clipboard operation
openzeppelin-contracts copied to clipboard

ERC1155Votes

Open jaketimothy opened this issue 2 years ago • 4 comments

Fixes #3757

This is an implementation of voting unit tracking for ERC1155 tokens modeled off of ERC20Votes. Voting units and delegations are enabled for each id using an adaptation of Votes (VotesMulti).

Configuration of unique voting power, maintaining a list of weights, or enabling/disabling voting ids is excluded and left to the user to extend from this or implement in a governor.

Alternative implementations aggregate the vote units across ids and store checkpoints of the total only. That approach creates a risk of failing transfers due to voting power overflow and is not as extensible.

PR Checklist

  • [x] Tests
  • [ ] Documentation
  • [x] Changelog entry

jaketimothy avatar Dec 13 '22 07:12 jaketimothy

In what cases is it necessary to vote with or delegate each id separately? Introducing a new VotesMulti contract is a real downside for us. We would like a simpler variant of ERC1155Votes built on the existing Votes contract.

frangio avatar Dec 28 '22 21:12 frangio

In what cases is it necessary to vote with or delegate each id separately? Introducing a new VotesMulti contract is a real downside for us. We would like a simpler variant of ERC1155Votes built on the existing Votes contract.

For context

Motivation

Imagine a single entity with classes of tokens.  In a general vote, each ERC1155 token id would have a voting weight - most would be 1, some 0 and others potentially >1.  A general vote may be desirable for updating protocol parameters, changing issuance curve, etc.  Any subclass with its own responsibilities and assets could also hold special votes.  I am also accounting for traditional share classes and their voting patterns: common shares, non-voting shares, and various series of preferred shares.  This can be achieved with a suite of governors keyed off of a single ERC1155 token.  After trying to build something like this with ERC20s, it became burdensome to add new classes and convert between them.

Design

Since different governors will need to consider either one or all (and perhaps subsets) of the token ids, I opted for more granular vote unit tracking.  I do not need delegation to be unique across token ids - this could be simplified to a single delegate for all tokens.  Since voting unit tracking needs access to transfer hooks, I don't see a way to separate the vote unit tracking from the token contract.  If that were possible, then an instance of Votes per governor would take care of it.  In order to base ERC1155Votes on the existing Votes, voting weights would be managed in the token and only a general vote would be supported without token id specific checkpoints. 

For now, I'll scale this back as requested.

jaketimothy avatar Dec 30 '22 00:12 jaketimothy

I see. That sounds like an interesting and realistic use case. If the goal is to have separate Governor instances for each of the different kinds of voting tokens, I would've leaned towards separate ERC20s like you said you tried initially. Why do you need to convert between them? That sounds like it could be implemented in a contract for converting.

For an ERC1155 where votes can be counted individually, I would still keep delegation global per account (that is, not per id), in order to preserve compatibility with governance tooling.

frangio avatar Dec 30 '22 14:12 frangio

I am highly interested about it. Any update?

ronmegini avatar Mar 22 '23 09:03 ronmegini