# Governance technical specifications
## Vote Token
vFATHOM (vFTHM)
#### Inherited functionality:
vFTHM is a Non-Transferable, Burnable, Pausable and Mintable ERC20 token with access control.
**ERC20Permit.sol:**
"Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]"
Inherited ERC20Permit functionality **allows** for the delegation of voting power by signature.
**ERC20Votes.sol:**
"Extension of ERC20 to support Compound-like voting and delegation"
Inherited ERC20Votes functionality **accounts** for the delegation of voting power by signature.
## Fathom Governor
Currently called MainTokenGovernor.sol
#### Inherited functionality:
**Governor.sol:**
The main functionality comes from: Governor.sol, further discussed in the section "Key Functions".
**GovernorVotes.sol:**
Inherited functionality responsible for calculating voters voting power given an account and a blocknumber.
**GovernorSettings.sol:**
Parameters controlling governance are from: GovernorSettings.sol. The parameters of interest are:
uint256 private _votingDelay;
uint256 private _votingPeriod;
uint256 private _proposalThreshold;
Here:
_votingDelay is the delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts.
_votingPeriod is the number of blocks that an active proposal remains open for voting.
_proposalThreshold is the number of vFTHM tokens required in order for a voter to become a proposer
**GovernorVotesQuorumFraction.sol:**
The quorum is the fraction vFTHM token holders who cast a vote as a fraction of the total voting power (total supply of vote tokens) required for a proposal to pass. Inherited functionality responible for setting the quorum requirements as a fraction of the total token supply.
**GovernorTimelockControl.sol:**
Timelock extensions add a delay for governance decisions to be executed. Functionality inherited from GovernorTimelockControl.sol are responsible for controlling the queing and execution of proposals.
**GovernorCountingSimple.sol:**
There are three options when casting a vote:
enum VoteType {
Against,
For,
Abstain
}
Votes for each proposal are counted and stored in s struct with the form:
struct ProposalVote {
uint256 againstVotes;
uint256 forVotes;
uint256 abstainVotes;
mapping(address => bool) hasVoted;
}
Functions for tallying votes and determining proposal success are inherited from GovernorCountingSimple.sol.
#### Key Functions:
***propose:***
/**
* @dev Create a new proposal. Vote start {IGovernor-votingDelay}
blocks after the proposal is created and ends
* {IGovernor-votingPeriod} blocks after the voting starts.
*
* Emits a {ProposalCreated} event.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public virtual returns (uint256 proposalId);
***state:***
/**
* @dev Current state of a proposal, following Compound's convention
*/
function state(uint256 proposalId) public view virtual returns (ProposalState);
Here ProposalState is the enum:
enum ProposalState {
Pending,
Active,
Canceled,
Defeated,
Succeeded,
Queued,
Expired,
Executed
}
***getVotes:***
/**
* @notice module:reputation
* @dev Voting power of an `account` at a specific `blockNumber`.
*
* Note: this can be implemented in a number of ways, for
example by reading the delegated balance from one (or
* multiple), {ERC20Votes} tokens.
*/
function getVotes(address account, uint256 blockNumber)
public view virtual returns (uint256);
***castVote:***
/**
* @dev Cast a vote
*
* Emits a {VoteCast} event.
*/
function castVote(uint256 proposalId, uint8 support)
public virtual returns (uint256 balance);
and:
/**
* @dev Cast a vote with a reason
*
* Emits a {VoteCast} event.
*/
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) public virtual returns (uint256 balance);
For delegatee votes:
/**
* @dev Cast a vote using the user's cryptographic signature.
*
* Emits a {VoteCast} event.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) public virtual returns (uint256 balance);
For all forms of voting, the voting options are from the following enum.
// enum VoteType {
// Against,
// For,
// Abstain
// }
// => 0 = Against, 1 = For, 2 = Abstain
***queue:***
/**
* @dev Function to queue a proposal to the timelock.
*/
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public virtual returns (uint256 proposalId);
***confirmProposal:***
The governance process and all of its contracts are owned by N wallets. A predetermined subset of confirm a proposal before it can be executed. This is exlpained in more detail in the "Accesibility Permissions and Roles" section.
function confirmProposal(uint _proposalId)
***execute:***
/**
* @dev Execute a successful proposal.
This requires the quorum to be reached,
the vote to be successful, and the
deadline to be reached.
*
* Emits a {ProposalExecuted} event.
*
* Note: some module can modify the requirements for
execution, for example by adding an additional timelock.
*/
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) public payable virtual returns (uint256 proposalId);
#### Deployment and initialisation parameters:
Steps:
1. Deploy Timelock Controller contract
2. Deploy vFTHM token contract
3. Initialize the Timelock Controller contract with parameters:
uint minDelay, address[] proposers, address[] executors
4. Deploy the FathomGovernor contract (Currently called MainTokenGovernor) with parameters: IVotes _token,
TimelockController _timelock,
address[] memory _signers,
uint _numConfirmationsRequired
The signers arrays is discussed in the "Accesibility Permissions and Roles" section.
<!--
## Multisig Treasury
##### Functionality
##### Key Functions:
-->
## Accesibility Permissions and Roles
***FathomGovernor and TimelockController:***
After deployment of FathomGovernor and TimelockController, the following TimelockController permissions need to be given to FathomGovernor:
timelockController.PROPOSER_ROLE()
timelockController.EXECUTOR_ROLE()
timelockController.TIMELOCK_ADMIN_ROLE()
***Signers:***
Both Multisig and FathomGovernor have arrays of signers. The signers have similar functionality, but differ in their responsibility.
The MultiSig signers are responsible for the confirmation of transactions queued in the multisig wallet, whereas the FathomGovernor signers are responsible for the confirmation of a proposal before it may be executed.