Skip to main content

Proposals

Any proposal to Meticulous' Governor follows this lifecycle:

  1. Proposal is submitted by calling propose(). Proposal review period begins.
  2. Proposal is activated for voting by calling activate(). Proposal voting period begins.
  3. Proposal is queued by calling queue(). Proposal is transfered to Timelock, and grace period begins.
  4. Proposal is executed by calling execute(), upgrading Meticulous protocol.

Submission

Anyone can submit a proposal to the Governor contract by calling propose(). However, the proposer must have a minimum amount of voting power to submit a proposal, which is determined by calling the getProposalThresholdVotes() function:

function getProposalThresholdVotes() public view returns (uint256) {
return (MET.totalSupply() * proposalThreshold) / 100_000;
}

The proposer's MET balance is checked within the propose(), queue(), and execute() functions. If, at any time, the proposer's MET balance falls below the proposal threshold, the proposal reverts. This approach ensures that proposers (or their delegators) maintain skin in the game, preventing them from benefiting from malicious proposals.

info

The current proposalThreshold is set to 0.4% of the total MET supply

Proposal Review

Calling propose() sets the start block of the proposal votingDelay number of days after current block. This delay is designed to give tokenholders time to review the proposal and its implications.

Tokenholders responsibilities include, but are not limited to:

  1. Verify proposal actions align with the protocol's goals,
  2. Intent: Ensure the proposal intent is clear, transparent and not malicious,
  3. Consensus: Ensure the proposal on-chain actions matches the consensus reached in the forums.
  4. Security Assurance: This phase is critical for safeguarding the protocol against malicious proposals.
  5. Community Engagement: Active community participation is vital in evaluating feasibility and impact.
info

The current votingDelay is set to 3 days

Proposal Activation

Anyone can activate a proposal by calling activate(). Calling activate records records quorumVotes on the proposal. If the proposal targets a high-risk module, the quorum is calculated using the getHighRiskQuorumVotes() function:

function getHighRiskQuorumVotes() public view returns (uint256) {
return (MET.totalSupply() * highRiskQuorum) / 100_000;
}

Otherwise, quorum is calculated using the getQuorumVotes() function:

function getQuorumVotes() public view returns (uint256) {
return (MET.totalSupply() * quorumPct) / 100_000;
}

The proposal will use this quorumVotes for the remainder of proposal lifecycle.

info

The current quorumPct is set to 10% of MET supply

info

The current votingPeriod is set to 7 days from the time the proposal is activated.

Proposal Queuing

Anyone can activate a proposal by calling queue(). Queueing a proposal prepares the proposal for execution by the Timelock contract in delay days. The proposer's MET balance is again checked during queue(). If the balance falls below proposalThreshold, the proposal will fail.

info

The current delay is set to 1 day

Proposal Execution

Any can execute a proposal by calling execute(). Executing a proposal triggers the Timelock contract to execute the proposal's actions. The proposer's MET balance is again checked during execute(). If the balance falls below proposalThreshold, the proposal will fail.

Also, if the proposal is not activated within the GRACE_PERIOD days after proposal is queued, it will expire and can no longer be executed.

info

The current GRACE_PERIOD is set to 1 day

Canceling Proposal

The proposal can be canceled at any time (before execution) by the proposer. A proposer can be canceled by anyone only if the proposer's MET balance is below proposalThreshold.