ShareClassGovernor
Inherits: StartupGovernor, ProposalGovernor, IShareClassGovernor
Author: Daniel Yamagata
A governance contract that enables the execution of arbitrary transactions by a super-majority of a treasury's signers. However, the management of the treasury's board members requires a proposal proccess. A preferred share class can be allocated control of up to three board seats, while the common shares do not have a limit on the number of seats that can be allocated. Once allocated, seats cannot be decreased. For example, if Preferred Shares Class A is allocated control over 2 board seats, its allocation cannot be decreased to 1 board seat. The allocation of seats is done directly by the board of directors. However, the assignment of the allocated board seats is left to the proposal process.
The following contract is heavily based on OZ's Governor Upgradeable, the Late Stage governor, and the Startup Governor The primary difference is proposals are fragmented by share classes. Therefore, direct inheritance from OZ's governor was not possible
State Variables
BALLOT_TYPEHASH
EXTENDED_BALLOT_TYPEHASH
ShareClassGovernorStorageLocation
Functions
_getShareClassGovernorStorage
constructor
init
Intializes the Governor's state
Parameters
initTreasury
address
The address of the Treasury that the Governor is in charge of
<none>
bytes
__ShareClassGovernor_init
The 'params' argument is maintained in case future versions require additional initialization parameters
state
Returns the state of a proposal associated with 'proposalId' as a ProposalState enum
increaseBoardSeatsForShareClass
Increases the board seats for a given share class.
This function should be called with caution: the number of board seats for a given share class cannot be decreased. Only callable by governance, itself.
Parameters
shareClass
address
The share class to increase the allocated board seats for
increaseAmount
uint256
The amount to increase the allocated board seats by
proposeBoardMemberChange
Proposes a board member change for a given 'shareClass'. The 'action' must be releated to adding a board member, removing a board member, or swapping a board member.
If the threshold is n, where n is the total number of board members, the new threshold will be n - 1. Otherwise, the threshold of the treasury will not change. The 'action' needs to be one that manages the owners of a team. These are defined in _validateAction(...)
Parameters
shareClass
address
The share class to propose a board member change for
action
bytes4
The action for managing the treasury's owners
params
bytes
The abi.encoded parameters for the given 'action'
description
string
The description of the proposal
Returns
<none>
uint256
The proposal ID
cancelProposal
Cancels a pending proposal for 'shareClass'.
The caller must be the Proposal's proposer or the Mezz Hub's owner. The params are solely used to re-create the proposal's ID
Returns
<none>
uint256
The proposal ID
executeProposal
Executes a proposal that succeeded.
The caller is not access controlled. However, the proposal must have succeeded and cannot have been executed To succeed, the proposal's for-votes must have reached the quorum and must exceed its against votes. Unless the proposal, has a super-majority, which is 75% in this case, of the votes, it will only be executable once the votiing period has passed. The params and actions are re-validated. The 'target' will also be the treasury
executeTx
Same as StartupGovernor's executeTx(...) except with further data validation. Specifically, the management of the treasury's owners and its threshold are disabled. To change these, the proposal process is required.
changeTreasuryThreshold
Changes the Treasury's security threshold. Must be called by the governor, itself.
Meant to be called via the Share Class Governor's executeTx()
Parameters
newTreasuryThreshold
uint256
The new threshold for the treasury
getVotes
Returns the number of votes for an 'account' given a 'shareClass' and 'timepoint'
_getVotes
Non-adjusted for voting weight, since all proposals are separated by share classes
quorum
Returns the nominal quorum for a proposal given a 'shareClass' and 'timepoint'. The nominal quorum is the minimum number of for-votes that a proposal needs to succeed It is based off the quorum percentage, which is set by governance, itself
_quorum
proposalThreshold
Returns the nominal proposal threshold given a 'shareClass' The nominal proposal threshold is the minimum number of votes that the sender must have for a proposal to be created It is based off the proposal threshold percentage, which is set by governance, itself
_proposalThreshold
superMajority
Returns the nominal super majority given a 'shareClass' and 'timepoint' A super majority in this context is 75% of the total votes for a share class. It a proposal has >75% of for-votes of the outstanding total votes, it is able to skip the voting period and be executed immediately
_superMajority
_castVote
'params' are unused outside of event emission
hashProposal
Returns the hash of a proposal given a 'shareClass', 'action', 'params', and 'descriptionHash' All of the aforementioned argumetns can be found via events emitted by the Share Class Governor for existing proposals
Returns
<none>
uint256
The proposal ID as a uint256
proposalSnapshot
Returns a proposal's snapshot, which is the time at which votes are counted. Any votes accumulated past this point are not counted towards the proposal
The snapshot is set during the proposal's and is the sum of the voting delay and block.timestamp
Parameters
proposalId
uint256
The ID of the proposal
Returns
<none>
uint256
The snapshot of the proposal, which is measured in seconds from the Unix epoch
proposalDeadline
Returns a proposal's deadline, which is the time at which the proposal can no longer be voted on
The deadline is set during the proposal's creation and is the sum of the voting delay, voting period, and block.timestamp
Parameters
proposalId
uint256
The ID of the proposal
Returns
<none>
uint256
The deadline of the proposal, which is measured in seconds from the Unix epoch
proposalProposer
Returns the proposer of a proposal
Returns
<none>
address
The address of the proposer
proposalShareClass
Returns the share class associated with a proposal
Parameters
proposalId
uint256
The ID of the proposal
Returns
<none>
address
The address of the share class
allocatedBoardSeats
Returns the total number of allocated board seats across all share classes
This does not include the board seats that have been set. For example, company Foo can have 5 allocated seats yet only 4 members set
_allocatedBoardSeats
getAllocatedSeatsByShareClass
Returns the number of allocated board seats for a given share class
getBoardMembersByShareClass
Returns the board members that have been set by a given share class
coreId
Returns the coreId of the implementation as a bytes32
The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))
version
Returns the version of the implementation as a uint256
COUNTING_MODE
Returns a URL-encoded sequence of key-value pairs that each describe one aspect of voting
Mezzanine Proposal Governors use votes in line with Bravo. The quorum also only counts for votes, like in Bravo. Reference: https://docs.openzeppelin.com/contracts/4.x/api/governance#IGovernor-COUNTING_MODE--
Returns
<none>
string
The URL-encoded sequence of key-value pairs
_updateBoardMembers
Updates state. Also reconstructs the params for a given proposal such that it includes the Treasury's threshold, if needed
Returns
<none>
bytes
The calldata for the execution of the transaction
_addOwnerForShareClass
Adds 'ownerToAdd' to the board members for 'shareClass'
_removeOwnerForShareClass
Removes 'ownerToRemove' from the board members for 'shareClass'
_checkInvariants
Reverts if the Treasury's total number of owners is greater than the allocated number of board seats
_validateShareClass
Reverts if 'shareClass' is not tracked by 'treasuryCache'
_validateAction
Validates that an action to manage the Treasury's owners. Unlike in TeamLogic's manageOwners(), the params for adding an owner and removing an owner do not include arguments to change the threshold for the treasury. This is to prevent a malicious proposal by a preferred share class that adds or switches an owner and then changes the threshold to 1. This would effectively enable them to control the treasury without the consent of the other signers. The threshold param is reconstructed in _updateBoardMembers(...) to include the Treasury's current threshold. If the threshold is the same as the number of owners, then the threshold is decreased by 1
_encodeStateBitmap
_getTotalVotesAtTimepoint
Returns the past total votes for the 'shareClass' at timepoint. The voting weight of the shares is ignored
_superMajorityReached
Returns whether or not a super majority has been reached for a given proposal. Only for-votes are counted towards the super majority
Returns
<none>
bool
True if the for-votes are greater than the super majority, false otherwise
_quorumReached
Returns whether or not the quourum has been reached for a given proposal. Only for-votes are counted towards the quorum
Returns
<none>
bool
True if the for votes are greater than the quorum, false otherwise
supportsInterface
ERC165 support
Structs
ShareClassGovernorStorage
Last updated