Proposals and Voting
On this page
fact Based on the governance contract sources. Both governors are OpenZeppelin v5.1 Governor with GovernorSettings, GovernorCountingFractional, GovernorVotes(veNOTE), GovernorVotesQuorumFraction and governance execution control. UpgradeGovernor is a NoteGovernor subclass with constructor floors.
Two Governors, Two Governance Delays
| Item | NoteGovernor | UpgradeGovernor |
|---|---|---|
| Name | Note Governor | Note Upgrade Governor |
| Decides | Parameters, series policy, module swaps, recovery unwind, gauge registration, emission schedule, treasury actions | upgradeToAndCall on the four UUPS proxies (Treasury, BondDepository, RevenueRouter, Desk) and governance-authority configuration |
| Voting delay | 1 day | 1 day |
| Voting period | 5 days | 7 days (floor MIN_VOTING_PERIOD) |
| Proposal threshold | 0.5% of veNOTE supply (proposalThresholdBps = 50) | 0.5% |
| Quorum | max(4% of veNOTE supply at snapshot, QUORUM_FLOOR) (quorumNumerator = 4) | max(8%, QUORUM_FLOOR) (floor MIN_QUORUM_NUMERATOR) |
Quorum floor (QUORUM_FLOOR, immutable, Params.quorumFloor) | 800,000 veNOTE in DeployGovernance.s.sol (QUORUM_FLOOR env override), estimate, to be confirmed against the launch lock supply | same |
| Quorum counts | for + abstain | for + abstain |
| Governance | governance, 48 h | upgrade governance, 7 days (floor the minimum governance delay) |
| End to end (no cancellation) | about 8 days | about 15 days |
| Clock | timestamp, inherited from veNOTE | same |
Both governors share CLOCK_MODE = mode=timestamp and COUNTING_MODE = support=bravo,fractional&quorum=for,abstain¶ms=fractional. The floor constants are MIN_VOTING_PERIOD = 7 days, MIN_QUORUM_NUMERATOR = 8 and the minimum governance delay.
The UpgradeGovernor constructor rejects quorum, voting-period or governance-delay values below its floors. Later changes to the voting period and quorum must also respect their minimum values.
proposalThreshold() is max(proposalThresholdAbsolute, getPastTotalSupply(clock() − 1) × bps / 10,000). The supply is read one second in the past because IVotes.getPastTotalSupply requires a past timepoint. setProposalThresholdBps is onlyGovernance and emits ProposalThresholdBpsSet(previous, current); values above 10,000 revert InvalidBps.
Lifecycle
ProposalState values. The first duration is NoteGovernor's, the second UpgradeGovernor's. Execution is permissionless once the governance delay has elapsed.- Propose.
propose(targets, values, calldatas, description). The proposer must hold at least the threshold in veNOTE atclock() − 1. Descriptions start with# <title>and include a## Risksection so the app and indexers can render them consistently. - Pending for
votingDelay(1 day). The vote snapshot is taken at the end of this delay, so locks created afterproposestill count if they exist at the snapshot. The proposer maycancelin this state. - Active for
votingPeriod. Anyone with weight at the snapshot casts a vote. - Succeeded if for-votes exceed against-votes and for + abstain reach quorum; otherwise Defeated.
- Queued by
queue(). Governance records the operation on-chain for the fullminDelay. The guardian may cancel it before execution; the governor then reports the cancelled state. - Executed by anyone calling
execute()after the delay.EXECUTOR_ROLEisaddress(0).
Voting
castVote(id, support) with support 0 = against, 1 = for, 2 = abstain, and castVoteWithReason, are the ordinary paths. Because both governors use GovernorCountingFractional, a voter can split weight across the three options in one transaction:
// support = 255 selects fractional mode; params packs three uint128 weights
governor.castVoteWithReasonAndParams(
proposalId,
255,
"60/25/15 split",
abi.encodePacked(uint128 againstVotes, uint128 forVotes, uint128 abstainVotes)
);
The three weights must not exceed the voter’s weight at the snapshot. Fractional mode also lets a voter cast in several transactions, as long as the running total stays within their weight. Votes cannot be changed once cast in nominal mode.
Governance Delays
fact Parameter changes and upgrades use separate delayed governance execution paths.
| Item | Governance | Upgrade Governance |
|---|---|---|
minDelay | 48 hours | 7 days |
| PROPOSER, CANCELLER | NoteGovernor (and optionally launch governance authority as PROPOSER) | UpgradeGovernor (and optionally launch governance authority as PROPOSER) |
| CANCELLER | Guardian | Guardian |
| EXECUTOR | address(0) (anyone) | address(0) |
DEFAULT_ADMIN_ROLE | renounced by the deployer | renounced by the deployer |
Is owner() of | every Governed module, veNOTE, GaugeController, EmissionSchedule, Minter, gauges, SeriesRegistry | nothing; it is the only address _authorizeUpgrade accepts |
Because admin is renounced, granting or revoking a governance role is itself a governed operation on that same governance. Changing minDelay uses updateDelay, which only the governance can call on itself.
Security Council
The guardian is the Security Council role on each Governed module. It can cancel queued governance actions, subject to the limits below.
| Can | Cannot |
|---|---|
pause() any module (onlyOwnerOrGuardian) | unpause() (owner only) |
cancel any queued operation on either governance | Propose, queue or execute anything |
NoteCore.cancelUnwind(seriesId) | proposeUnwind, unwind, sweepExcess |
OracleAdapter.revokeForceObserve | Propose a forced price or cancel an observation |
| - | Change any parameter, register or deprecate a core, add a gauge |
| - | Move funds from any contract, including recovered escrow |
| - | Upgrade code or shorten either delay |
A pause stops strikes and observations but does not itself disable the listed exit functions. Each exit still needs its required series state, matured request or claimable balance. A live note is not redeemable merely because the core is paused. Governance must resume paused activity; there is no promised resumption time.
Reading a Proposal in the App
The app’s Governance section lists proposals from both governors with their state, timeline and vote bars, and shows every pending operation on both governance delays with its execute time. Pending operations that renounce ownership of a module or hand a role to an unknown address should be treated as red flags; the contract documentation records renounceOwnership as forbidden by process because a scheduled renounce would make unpause impossible.
Keep exploring, or revisit this topic from the navigation.