ShareClassGovernor

Git Source

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

bytes32 public constant BALLOT_TYPEHASH = _BALLOT_TYPEHASH;

EXTENDED_BALLOT_TYPEHASH

bytes32 public constant EXTENDED_BALLOT_TYPEHASH = _EXTENDED_BALLOT_TYPEHASH;

ShareClassGovernorStorageLocation

bytes32 private constant ShareClassGovernorStorageLocation =
    0x562a9c0a18060dac6c99104dbc22c3187c8da12ab6cbbc0788d567773f540f00;

Functions

_getShareClassGovernorStorage

constructor

init

Intializes the Governor's state

Parameters

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

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

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

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

Name
Type
Description

<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

Name
Type
Description

proposalId

uint256

The ID of the proposal

Returns

Name
Type
Description

<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

Name
Type
Description

proposalId

uint256

The ID of the proposal

Returns

Name
Type
Description

<none>

uint256

The deadline of the proposal, which is measured in seconds from the Unix epoch

proposalProposer

Returns the proposer of a proposal

Returns

Name
Type
Description

<none>

address

The address of the proposer

proposalShareClass

Returns the share class associated with a proposal

Parameters

Name
Type
Description

proposalId

uint256

The ID of the proposal

Returns

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

<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

Name
Type
Description

<none>

bool

True if the for votes are greater than the quorum, false otherwise

supportsInterface

ERC165 support

Structs

ShareClassGovernorStorage

Last updated