OpenZeppelin Governor
Compatibility considerations when implementing OpenZeppelin governor
To be compatible with the Tally app we recommend you to use OpenZeppelin's library Governor contract. If you want to implement changes to this base contract, here is the interface that you should follow to make sure your contract works with our app.
Event signatures
Tally's API listens to event logs from Governor contracts when indexing them. Your contract will need to maintain the same event signatures that OZ Governor implements:
Function signatures
Tally's frontend app helps users make web3 calls to your Governor contract. The app lets users create Proposals as well as vote on, queue and execute them. In addition, the app reads state from the contract with function calls.
To be compatible with Tally, your Governor will need these function signatures:
If your OpenZeppelin governor contract uses a Timelock, it will also need this signature:
Quorum
Tally needs the quorum to calculate if a proposal has passed. That means that Tally requires the Governor to have a quorum()
function:
Optionally, Tally also supports the quorumNumerator()
and quorumDenominator()
functions. Governors with quorums that are a function of token supply should implement these functions:
If the Governor is missing either quorumNumerator()
or quorumDenominator()
, Tally falls back to the quorum()
function and assumes that the quorum is fixed.
Voting Delay
Tally needs to know the voting delay to calculate when voting starts without polling the blockchain. A votingDelay()
function on Governor is required:
Voting Period
Tally needs to know the voting period to calculate when a proposal finishes voting without polling the blockchain. A votingPeriod()
function on Governor is required:
Proposal state lifecycle
Tally's app expects the following proposal states. If your Governor uses a custom proposal lifecycle, those states won't show up correctly on on Tally:
Governor Parameter Changes
Governors can change their own parameters, like proposal times and the amount of voting power required to create and pass proposals. To make sure that Tally indexes your Governor's parameter changes, implement these event signatures:
If your OpenZeppelin governor contract uses a Timelock, it will also need this event:
Quorum Extension
Tally handles the ProposalExtended
event, which is emitted by governors that implement the PreventLateQuorum
extension:
Clock Mode
Since Governor v4.9, all voting contracts (including ERC20Votes
and ERC721Votes
) rely on IERC6372 for clock management. The Governor will automatically detect the clock mode used by the token and adapt to it. There is no need to override anything in the Governor contract. You can learn more about compatibility of your token and Governor contract with clock mode here.
Tally checks the contract lock using the IERC-6372 standard. We accept blocknumber
and timestamp
clock modes.Specifically, Tally expects Governor and token contracts to implement a CLOCK_MODE()
function that returns either mode=blocknumber&from=default
or mode=blocknumber&from=<CAIP-2-ID>
. If the call to the governor's CLOCK_MODE()
method returns mode=timestamp
then proposal start and end times will be interpreted as unix timestamps otherwise they will be interpreted as block numbers.
If you're interested in support for another contract clock, Tally would need to do some custom work. Get in touch with biz@tally.xyz.
Last updated