0
# Governance
1
2
Complete on-chain governance framework providing proposal management, voting systems, timelock controls, and delegation mechanisms for decentralized autonomous organizations (DAOs).
3
4
## Capabilities
5
6
### Core Governor Framework
7
8
Flexible governance system supporting proposals, voting, and execution with extensible architecture.
9
10
```solidity { .api }
11
/**
12
* @dev Core governor interface defining standard governance functionality
13
*/
14
interface IGovernor is IERC165, IERC6372 {
15
/**
16
* @dev Create a new proposal
17
*/
18
function propose(
19
address[] memory targets,
20
uint256[] memory values,
21
bytes[] memory calldatas,
22
string memory description
23
) external returns (uint256 proposalId);
24
25
/**
26
* @dev Execute a successful proposal
27
*/
28
function execute(
29
address[] memory targets,
30
uint256[] memory values,
31
bytes[] memory calldatas,
32
bytes32 descriptionHash
33
) external payable returns (uint256 proposalId);
34
35
/**
36
* @dev Cast a vote on a proposal
37
*/
38
function castVote(uint256 proposalId, uint8 support) external returns (uint256 balance);
39
40
/**
41
* @dev Cast vote with reasoning
42
*/
43
function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external returns (uint256 balance);
44
45
/**
46
* @dev Cast vote using signature for gasless voting
47
*/
48
function castVoteBySig(uint256 proposalId, uint8 support, address voter, bytes memory signature) external returns (uint256 balance);
49
50
/**
51
* @dev Get current state of a proposal
52
*/
53
function state(uint256 proposalId) external view returns (ProposalState);
54
55
/**
56
* @dev Get required quorum at specific timepoint
57
*/
58
function quorum(uint256 timepoint) external view returns (uint256);
59
60
/**
61
* @dev Get voting weight of account at timepoint
62
*/
63
function getVotes(address account, uint256 timepoint) external view returns (uint256);
64
}
65
66
/**
67
* @dev Core Governor implementation with proposal lifecycle management
68
*/
69
abstract contract Governor is Context, ERC165, EIP712, Nonces, IGovernor, IERC721Receiver, IERC1155Receiver {
70
/**
71
* @dev Execute arbitrary calls through governance (self-administration)
72
*/
73
function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance;
74
75
/**
76
* @dev Modifier restricting access to governance itself
77
*/
78
modifier onlyGovernance();
79
}
80
```
81
82
### Voting Systems
83
84
Multiple voting mechanisms supporting different vote counting strategies and participation models.
85
86
```solidity { .api }
87
/**
88
* @dev Simple 3-option voting: Against (0), For (1), Abstain (2)
89
*/
90
abstract contract GovernorCountingSimple is Governor {
91
/**
92
* @dev Get vote counts for a proposal
93
*/
94
function proposalVotes(uint256 proposalId) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes);
95
96
/**
97
* @dev Check if account has voted on proposal
98
*/
99
function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);
100
}
101
102
/**
103
* @dev Fractional voting allowing split votes across options
104
*/
105
abstract contract GovernorCountingFractional is Governor {
106
/**
107
* @dev Get amount of votes already used by account on proposal
108
*/
109
function usedVotes(uint256 proposalId, address account) public view virtual returns (uint256);
110
111
/**
112
* @dev Cast fractional votes across multiple options
113
* @param params Encoded as abi.encodePacked(uint128(against), uint128(for), uint128(abstain))
114
*/
115
function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) public virtual returns (uint256);
116
}
117
```
118
119
### Timelock Integration
120
121
Secure timelock mechanisms for delayed execution and multi-signature governance controls.
122
123
```solidity { .api }
124
/**
125
* @dev Timelock controller for delayed execution of governance decisions
126
*/
127
contract TimelockController is AccessControl, IERC721Receiver, IERC1155Receiver {
128
/**
129
* @dev Schedule single operation for future execution
130
*/
131
function schedule(
132
address target,
133
uint256 value,
134
bytes calldata data,
135
bytes32 predecessor,
136
bytes32 salt,
137
uint256 delay
138
) public virtual onlyRole(PROPOSER_ROLE);
139
140
/**
141
* @dev Schedule batch of operations for future execution
142
*/
143
function scheduleBatch(
144
address[] calldata targets,
145
uint256[] calldata values,
146
bytes[] calldata payloads,
147
bytes32 predecessor,
148
bytes32 salt,
149
uint256 delay
150
) public virtual onlyRole(PROPOSER_ROLE);
151
152
/**
153
* @dev Execute ready operation
154
*/
155
function execute(
156
address target,
157
uint256 value,
158
bytes calldata payload,
159
bytes32 predecessor,
160
bytes32 salt
161
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE);
162
163
/**
164
* @dev Cancel pending operation
165
*/
166
function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE);
167
168
/**
169
* @dev Update minimum delay for operations
170
*/
171
function updateDelay(uint256 newDelay) external virtual;
172
173
/**
174
* @dev Get operation state
175
*/
176
function getOperationState(bytes32 id) public view virtual returns (OperationState);
177
178
/**
179
* @dev Check if operation is ready for execution
180
*/
181
function isOperationReady(bytes32 id) public view virtual returns (bool);
182
}
183
184
/**
185
* @dev Governor extension integrating with TimelockController
186
*/
187
abstract contract GovernorTimelockControl is Governor {
188
/**
189
* @dev Get associated timelock address
190
*/
191
function timelock() public view virtual returns (address);
192
193
/**
194
* @dev Update timelock address (governance only)
195
*/
196
function updateTimelock(address newTimelock) external virtual onlyGovernance;
197
198
/**
199
* @dev Queue proposal for execution through timelock
200
*/
201
function queue(
202
address[] memory targets,
203
uint256[] memory values,
204
bytes[] memory calldatas,
205
bytes32 descriptionHash
206
) public virtual returns (uint256);
207
}
208
```
209
210
### Vote Delegation and Weight Management
211
212
Systems for delegating voting power and tracking voting weights over time with checkpoint-based history.
213
214
```solidity { .api }
215
/**
216
* @dev Voting power delegation and historical tracking
217
*/
218
abstract contract Votes is Context, EIP712, Nonces, IERC5805 {
219
/**
220
* @dev Delegate voting power to another account
221
*/
222
function delegate(address delegatee) public virtual;
223
224
/**
225
* @dev Delegate voting power using signature (gasless)
226
*/
227
function delegateBySig(
228
address delegatee,
229
uint256 nonce,
230
uint256 expiry,
231
uint8 v,
232
bytes32 r,
233
bytes32 s
234
) public virtual;
235
236
/**
237
* @dev Get current voting power of account
238
*/
239
function getVotes(address account) public view virtual returns (uint256);
240
241
/**
242
* @dev Get historical voting power at specific timepoint
243
*/
244
function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256);
245
246
/**
247
* @dev Get total supply at specific timepoint
248
*/
249
function getPastTotalSupply(uint256 timepoint) public view virtual returns (uint256);
250
251
/**
252
* @dev Get current delegate of account
253
*/
254
function delegates(address account) public view virtual returns (address);
255
}
256
257
/**
258
* @dev Governor extension using external vote source (ERC20Votes/ERC721Votes)
259
*/
260
abstract contract GovernorVotes is Governor {
261
/**
262
* @dev Get voting power from token contract
263
*/
264
function getVotes(address account, uint256 timepoint) public view virtual override returns (uint256);
265
266
/**
267
* @dev Get associated voting token
268
*/
269
function token() public view virtual returns (IERC5805);
270
}
271
```
272
273
### Quorum Management
274
275
Flexible quorum systems with fractional requirements and historical tracking.
276
277
```solidity { .api }
278
/**
279
* @dev Fractional quorum based on total supply percentage
280
*/
281
abstract contract GovernorVotesQuorumFraction is GovernorVotes {
282
/**
283
* @dev Get current quorum numerator
284
*/
285
function quorumNumerator() public view virtual returns (uint256);
286
287
/**
288
* @dev Get quorum denominator (default: 100 for percentage)
289
*/
290
function quorumDenominator() public view virtual returns (uint256);
291
292
/**
293
* @dev Update quorum numerator (governance only)
294
*/
295
function updateQuorumNumerator(uint256 newNumerator) external virtual onlyGovernance;
296
297
/**
298
* @dev Calculate quorum at specific timepoint
299
*/
300
function quorum(uint256 timepoint) public view virtual override returns (uint256);
301
302
/**
303
* @dev Get historical quorum numerator
304
*/
305
function quorumNumerator(uint256 timepoint) public view virtual returns (uint256);
306
}
307
```
308
309
### Advanced Governance Features
310
311
Extensions for enhanced governance functionality including late quorum protection and proposal guardians.
312
313
```solidity { .api }
314
/**
315
* @dev Configurable governance settings
316
*/
317
abstract contract GovernorSettings is Governor {
318
/**
319
* @dev Set voting delay between proposal and voting start
320
*/
321
function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance;
322
323
/**
324
* @dev Set voting period duration
325
*/
326
function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance;
327
328
/**
329
* @dev Set minimum tokens needed to create proposal
330
*/
331
function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance;
332
}
333
334
/**
335
* @dev Protection against late quorum manipulation
336
*/
337
abstract contract GovernorPreventLateQuorum is Governor {
338
/**
339
* @dev Get vote extension period when quorum reached late
340
*/
341
function lateQuorumVoteExtension() public view virtual returns (uint256);
342
343
/**
344
* @dev Set late quorum vote extension period
345
*/
346
function setLateQuorumVoteExtension(uint256 newExtension) public virtual onlyGovernance;
347
348
/**
349
* @dev Get proposal deadline with potential extension
350
*/
351
function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256);
352
}
353
354
/**
355
* @dev Proposal guardian with cancellation authority
356
*/
357
abstract contract GovernorProposalGuardian is Governor {
358
/**
359
* @dev Get current proposal guardian
360
*/
361
function proposalGuardian() public view virtual returns (address);
362
363
/**
364
* @dev Set proposal guardian (governance only)
365
*/
366
function setProposalGuardian(address newGuardian) public virtual onlyGovernance;
367
368
/**
369
* @dev Cancel proposal (guardian or proposer only)
370
*/
371
function cancel(
372
address[] memory targets,
373
uint256[] memory values,
374
bytes[] memory calldatas,
375
bytes32 descriptionHash
376
) public virtual returns (uint256);
377
}
378
379
/**
380
* @dev Proposal storage for L2 optimization and enumeration
381
*/
382
abstract contract GovernorStorage is Governor {
383
/**
384
* @dev Queue proposal using stored details
385
*/
386
function queue(uint256 proposalId) public virtual;
387
388
/**
389
* @dev Execute proposal using stored details
390
*/
391
function execute(uint256 proposalId) public payable virtual;
392
393
/**
394
* @dev Get stored proposal details
395
*/
396
function proposalDetails(uint256 proposalId) public view virtual returns (ProposalDetails memory);
397
398
/**
399
* @dev Get total number of proposals created
400
*/
401
function proposalCount() public view virtual returns (uint256);
402
}
403
```
404
405
## Types
406
407
```solidity { .api }
408
/**
409
* @dev Possible states of a governance proposal
410
*/
411
enum ProposalState {
412
Pending, // Proposal created, voting not started
413
Active, // Voting is active
414
Canceled, // Proposal was canceled
415
Defeated, // Proposal was defeated (not enough votes)
416
Succeeded, // Proposal succeeded (enough votes)
417
Queued, // Proposal queued in timelock
418
Expired, // Proposal expired before execution
419
Executed // Proposal was executed
420
}
421
422
/**
423
* @dev Timelock operation states
424
*/
425
enum OperationState {
426
Unset, // Operation not scheduled
427
Waiting, // Scheduled, waiting for delay
428
Ready, // Ready for execution
429
Done // Already executed
430
}
431
432
/**
433
* @dev Support options for voting
434
*/
435
enum VoteType {
436
Against, // Vote against proposal (0)
437
For, // Vote for proposal (1)
438
Abstain // Abstain from voting (2)
439
}
440
441
/**
442
* @dev Stored proposal details structure
443
*/
444
struct ProposalDetails {
445
address[] targets;
446
uint256[] values;
447
bytes[] calldatas;
448
bytes32 descriptionHash;
449
}
450
451
/**
452
* @dev Standard voting interface (ERC-5805)
453
*/
454
interface IERC5805 is IERC6372, IVotes {}
455
456
/**
457
* @dev Clock interface for timepoint queries (ERC-6372)
458
*/
459
interface IERC6372 {
460
function clock() external view returns (uint48);
461
function CLOCK_MODE() external view returns (string memory);
462
}
463
464
/**
465
* @dev Voting interface
466
*/
467
interface IVotes {
468
function getVotes(address account) external view returns (uint256);
469
function getPastVotes(address account, uint256 timepoint) external view returns (uint256);
470
function getPastTotalSupply(uint256 timepoint) external view returns (uint256);
471
function delegates(address account) external view returns (address);
472
function delegate(address delegatee) external;
473
function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
474
}
475
476
/**
477
* @dev Timelock controller roles
478
*/
479
bytes32 constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); // Can schedule operations
480
bytes32 constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); // Can execute operations
481
bytes32 constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE"); // Can cancel operations
482
```
483
484
**Usage Example:**
485
486
```solidity
487
import "@openzeppelin/contracts/governance/Governor.sol";
488
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
489
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
490
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
491
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
492
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
493
494
contract MyDAO is
495
Governor,
496
GovernorSettings,
497
GovernorCountingSimple,
498
GovernorVotes,
499
GovernorVotesQuorumFraction,
500
GovernorTimelockControl
501
{
502
constructor(
503
IVotes _token,
504
TimelockController _timelock,
505
uint256 _quorumPercentage
506
)
507
Governor("MyDAO")
508
GovernorSettings(7200, 50400, 1000e18) // 1 day delay, 1 week voting, 1000 token threshold
509
GovernorVotes(_token)
510
GovernorVotesQuorumFraction(_quorumPercentage)
511
GovernorTimelockControl(_timelock)
512
{}
513
514
// Required override functions
515
function votingDelay() public view override(IGovernor, GovernorSettings) returns (uint256) {
516
return super.votingDelay();
517
}
518
519
function votingPeriod() public view override(IGovernor, GovernorSettings) returns (uint256) {
520
return super.votingPeriod();
521
}
522
523
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
524
return super.proposalThreshold();
525
}
526
}
527
```