0
# Governance
1
2
Advanced DAO governance framework with flexible voting mechanisms, proposal management, timelock controllers, and vote delegation systems for decentralized decision-making.
3
4
## Capabilities
5
6
### Core Governor Contract
7
8
The GovernorUpgradeable contract provides the foundation for DAO governance with proposal creation, voting, and execution.
9
10
```solidity { .api }
11
/**
12
* @dev Core governance contract for DAOs
13
*/
14
abstract contract GovernorUpgradeable {
15
function __Governor_init(string memory name_) internal onlyInitializing;
16
17
/**
18
* @dev Name of the governor instance
19
*/
20
function name() external view returns (string memory);
21
22
/**
23
* @dev Version of the governor instance
24
*/
25
function version() external view returns (string memory);
26
27
/**
28
* @dev Hashing function used to build the proposal id from the proposal details
29
*/
30
function hashProposal(address[] calldata targets, uint256[] calldata values, bytes[] calldata calldatas, bytes32 descriptionHash) external pure returns (uint256);
31
32
/**
33
* @dev Current state of a proposal
34
*/
35
function state(uint256 proposalId) external view returns (ProposalState);
36
37
/**
38
* @dev Block number used to retrieve user's votes and quorum
39
*/
40
function proposalSnapshot(uint256 proposalId) external view returns (uint256);
41
42
/**
43
* @dev Block number at which votes close
44
*/
45
function proposalDeadline(uint256 proposalId) external view returns (uint256);
46
47
/**
48
* @dev Create a new proposal
49
*/
50
function propose(address[] calldata targets, uint256[] calldata values, bytes[] calldata calldatas, string calldata description) external returns (uint256);
51
52
/**
53
* @dev Queue a successful proposal
54
*/
55
function queue(address[] calldata targets, uint256[] calldata values, bytes[] calldata calldatas, bytes32 descriptionHash) external returns (uint256);
56
57
/**
58
* @dev Execute a successful proposal
59
*/
60
function execute(address[] calldata targets, uint256[] calldata values, bytes[] calldata calldatas, bytes32 descriptionHash) external payable returns (uint256);
61
62
/**
63
* @dev Cancel a proposal
64
*/
65
function cancel(address[] calldata targets, uint256[] calldata values, bytes[] calldata calldatas, bytes32 descriptionHash) external returns (uint256);
66
67
/**
68
* @dev Cast a vote on a proposal
69
*/
70
function castVote(uint256 proposalId, uint8 support) external returns (uint256);
71
72
/**
73
* @dev Cast a vote with a reason
74
*/
75
function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) external returns (uint256);
76
77
/**
78
* @dev Cast a vote by signature
79
*/
80
function castVoteBySig(uint256 proposalId, uint8 support, address voter, bytes memory signature) external returns (uint256);
81
}
82
83
// Proposal states
84
enum ProposalState {
85
Pending,
86
Active,
87
Canceled,
88
Defeated,
89
Succeeded,
90
Queued,
91
Expired,
92
Executed
93
}
94
95
// Events
96
event ProposalCreated(uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 voteStart, uint256 voteEnd, string description);
97
event ProposalQueued(uint256 proposalId, uint256 etaSeconds);
98
event ProposalExecuted(uint256 proposalId);
99
event ProposalCanceled(uint256 proposalId);
100
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
101
```
102
103
### Vote Delegation and Tracking
104
105
The VotesUpgradeable contract enables vote delegation and historical vote tracking for governance tokens.
106
107
```solidity { .api }
108
/**
109
* @dev Vote delegation and tracking functionality
110
*/
111
abstract contract VotesUpgradeable {
112
function __Votes_init() internal onlyInitializing;
113
114
/**
115
* @dev Returns the current amount of votes that account has
116
*/
117
function getVotes(address account) external view returns (uint256);
118
119
/**
120
* @dev Returns the amount of votes that account had at timepoint
121
*/
122
function getPastVotes(address account, uint256 timepoint) external view returns (uint256);
123
124
/**
125
* @dev Returns the total supply of votes available at timepoint
126
*/
127
function getPastTotalSupply(uint256 timepoint) external view returns (uint256);
128
129
/**
130
* @dev Returns the delegate that account has chosen
131
*/
132
function delegates(address account) external view returns (address);
133
134
/**
135
* @dev Delegates votes from the sender to delegatee
136
*/
137
function delegate(address delegatee) external;
138
139
/**
140
* @dev Delegates votes from signer to delegatee
141
*/
142
function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
143
}
144
145
// Events
146
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
147
event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);
148
```
149
150
### Timelock Controller
151
152
Timelock controller for delayed execution of governance proposals.
153
154
```solidity { .api }
155
/**
156
* @dev Timelock controller for delayed execution
157
*/
158
contract TimelockControllerUpgradeable {
159
function __TimelockController_init(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) internal onlyInitializing;
160
161
/**
162
* @dev Returns the minimum delay for operations
163
*/
164
function getMinDelay() external view returns (uint256);
165
166
/**
167
* @dev Returns whether an id corresponds to a registered operation
168
*/
169
function isOperation(bytes32 id) external view returns (bool);
170
171
/**
172
* @dev Returns whether an operation is pending
173
*/
174
function isOperationPending(bytes32 id) external view returns (bool);
175
176
/**
177
* @dev Returns whether an operation is ready for execution
178
*/
179
function isOperationReady(bytes32 id) external view returns (bool);
180
181
/**
182
* @dev Returns whether an operation is done
183
*/
184
function isOperationDone(bytes32 id) external view returns (bool);
185
186
/**
187
* @dev Returns the timestamp at which an operation becomes ready
188
*/
189
function getTimestamp(bytes32 id) external view returns (uint256);
190
191
/**
192
* @dev Schedule an operation
193
*/
194
function schedule(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt, uint256 delay) external;
195
196
/**
197
* @dev Execute an operation
198
*/
199
function execute(address target, uint256 value, bytes calldata payload) external payable;
200
201
/**
202
* @dev Cancel an operation
203
*/
204
function cancel(bytes32 id) external;
205
}
206
207
// Role constants
208
bytes32 constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
209
bytes32 constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
210
bytes32 constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE");
211
```
212
213
### Governor Extensions
214
215
#### Voting Settings
216
217
```solidity { .api }
218
/**
219
* @dev Extension that allows the governor to update voting parameters
220
*/
221
abstract contract GovernorSettingsUpgradeable {
222
function __GovernorSettings_init(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) internal onlyInitializing;
223
224
/**
225
* @dev Update the voting delay
226
*/
227
function setVotingDelay(uint256 newVotingDelay) external;
228
229
/**
230
* @dev Update the voting period
231
*/
232
function setVotingPeriod(uint256 newVotingPeriod) external;
233
234
/**
235
* @dev Update the proposal threshold
236
*/
237
function setProposalThreshold(uint256 newProposalThreshold) external;
238
}
239
```
240
241
#### Counting Mechanisms
242
243
```solidity { .api }
244
/**
245
* @dev Simple counting mechanism with Against/For/Abstain votes
246
*/
247
abstract contract GovernorCountingSimpleUpgradeable {
248
function __GovernorCountingSimple_init() internal onlyInitializing;
249
250
/**
251
* @dev Returns the vote totals for a proposal
252
*/
253
function proposalVotes(uint256 proposalId) external view returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes);
254
255
/**
256
* @dev Returns whether account has cast a vote on proposalId
257
*/
258
function hasVoted(uint256 proposalId, address account) external view returns (bool);
259
}
260
```
261
262
#### Quorum Management
263
264
```solidity { .api }
265
/**
266
* @dev Extension that uses a fraction of the token's total supply as quorum
267
*/
268
abstract contract GovernorVotesQuorumFractionUpgradeable {
269
function __GovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue) internal onlyInitializing;
270
271
/**
272
* @dev Returns the current quorum numerator
273
*/
274
function quorumNumerator() external view returns (uint256);
275
276
/**
277
* @dev Returns the quorum denominator (fixed at 100)
278
*/
279
function quorumDenominator() external view returns (uint256);
280
281
/**
282
* @dev Changes the quorum numerator
283
*/
284
function updateQuorumNumerator(uint256 newQuorumNumerator) external;
285
}
286
```
287
288
#### Advanced Counting Mechanisms
289
290
```solidity { .api }
291
/**
292
* @dev Fractional voting mechanism that allows partial votes
293
*/
294
abstract contract GovernorCountingFractionalUpgradeable {
295
function __GovernorCountingFractional_init() internal onlyInitializing;
296
297
/**
298
* @dev Cast fractional votes (sum must equal weight)
299
*/
300
function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) external returns (uint256);
301
}
302
303
/**
304
* @dev Overridable counting mechanism for delegation override
305
*/
306
abstract contract GovernorCountingOverridableUpgradeable {
307
function __GovernorCountingOverridable_init() internal onlyInitializing;
308
309
/**
310
* @dev Overrides delegated votes for specific proposals
311
*/
312
function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) external returns (uint256);
313
}
314
```
315
316
#### Advanced Quorum
317
318
```solidity { .api }
319
/**
320
* @dev Super quorum extension for critical proposals
321
*/
322
abstract contract GovernorSuperQuorumUpgradeable {
323
function __GovernorSuperQuorum_init() internal onlyInitializing;
324
325
/**
326
* @dev Returns whether proposal requires super quorum
327
*/
328
function requiresSuperQuorum(uint256 proposalId) external view returns (bool);
329
}
330
331
/**
332
* @dev Super quorum with fraction-based calculation
333
*/
334
abstract contract GovernorVotesSuperQuorumFractionUpgradeable {
335
function __GovernorVotesSuperQuorumFraction_init(uint256 superQuorumNumerator) internal onlyInitializing;
336
337
/**
338
* @dev Updates the super quorum numerator
339
*/
340
function updateSuperQuorumNumerator(uint256 newSuperQuorumNumerator) external;
341
}
342
```
343
344
#### Proposal Security
345
346
```solidity { .api }
347
/**
348
* @dev Prevents late quorum changes to avoid governance attacks
349
*/
350
abstract contract GovernorPreventLateQuorumUpgradeable {
351
function __GovernorPreventLateQuorum_init(uint256 voteExtension) internal onlyInitializing;
352
353
/**
354
* @dev Returns the vote extension period
355
*/
356
function lateQuorumVoteExtension() external view returns (uint256);
357
358
/**
359
* @dev Updates the vote extension period
360
*/
361
function setLateQuorumVoteExtension(uint256 newVoteExtension) external;
362
}
363
364
/**
365
* @dev Adds guardian functionality for proposal protection
366
*/
367
abstract contract GovernorProposalGuardianUpgradeable {
368
function __GovernorProposalGuardian_init(address guardian) internal onlyInitializing;
369
370
/**
371
* @dev Returns the current guardian
372
*/
373
function guardian() external view returns (address);
374
375
/**
376
* @dev Updates the guardian address
377
*/
378
function setGuardian(address newGuardian) external;
379
380
/**
381
* @dev Guardian can cancel malicious proposals
382
*/
383
function cancel(address[] calldata targets, uint256[] calldata values, bytes[] calldata calldatas, bytes32 descriptionHash) external returns (uint256);
384
}
385
```
386
387
#### Proposal Management
388
389
```solidity { .api }
390
/**
391
* @dev Sequential proposal ID generation
392
*/
393
abstract contract GovernorSequentialProposalIdUpgradeable {
394
function __GovernorSequentialProposalId_init() internal onlyInitializing;
395
396
/**
397
* @dev Returns the next proposal ID
398
*/
399
function nextProposalId() external view returns (uint256);
400
}
401
402
/**
403
* @dev Storage-based governance for reduced gas costs
404
*/
405
abstract contract GovernorStorageUpgradeable {
406
function __GovernorStorage_init() internal onlyInitializing;
407
408
/**
409
* @dev Stores proposal data in contract storage
410
*/
411
function getProposalData(uint256 proposalId) external view returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas);
412
}
413
414
/**
415
* @dev Keyed nonces for advanced signature schemes
416
*/
417
abstract contract GovernorNoncesKeyedUpgradeable {
418
function __GovernorNoncesKeyed_init() internal onlyInitializing;
419
420
/**
421
* @dev Returns nonce for account and key
422
*/
423
function nonces(address account, bytes32 key) external view returns (uint256);
424
425
/**
426
* @dev Cast vote by signature with keyed nonce
427
*/
428
function castVoteBySigWithKey(uint256 proposalId, uint8 support, address voter, bytes32 key, bytes memory signature) external returns (uint256);
429
}
430
```
431
432
#### Timelock Integration
433
434
```solidity { .api }
435
/**
436
* @dev Integration with AccessManager for timelock operations
437
*/
438
abstract contract GovernorTimelockAccessUpgradeable {
439
function __GovernorTimelockAccess_init(IAccessManager manager) internal onlyInitializing;
440
441
/**
442
* @dev Returns the access manager
443
*/
444
function accessManager() external view returns (IAccessManager);
445
446
/**
447
* @dev Updates the access manager
448
*/
449
function setAccessManager(IAccessManager newManager) external;
450
}
451
```
452
453
## Usage Examples
454
455
### Basic DAO Governor
456
457
```solidity
458
import {GovernorUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";
459
import {GovernorSettingsUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";
460
import {GovernorCountingSimpleUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorCountingSimpleUpgradeable.sol";
461
import {GovernorVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol";
462
import {GovernorVotesQuorumFractionUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
463
464
contract MyGovernor is
465
GovernorUpgradeable,
466
GovernorSettingsUpgradeable,
467
GovernorCountingSimpleUpgradeable,
468
GovernorVotesUpgradeable,
469
GovernorVotesQuorumFractionUpgradeable
470
{
471
function initialize(
472
IVotes _token,
473
uint256 _votingDelay,
474
uint256 _votingPeriod,
475
uint256 _proposalThreshold,
476
uint256 _quorumPercentage
477
) initializer public {
478
__Governor_init("MyGovernor");
479
__GovernorSettings_init(_votingDelay, _votingPeriod, _proposalThreshold);
480
__GovernorCountingSimple_init();
481
__GovernorVotes_init(_token);
482
__GovernorVotesQuorumFraction_init(_quorumPercentage);
483
}
484
485
// Required overrides
486
function votingDelay() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) {
487
return super.votingDelay();
488
}
489
490
function votingPeriod() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint256) {
491
return super.votingPeriod();
492
}
493
494
function quorum(uint256 blockNumber) public view override(GovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable) returns (uint256) {
495
return super.quorum(blockNumber);
496
}
497
}
498
```
499
500
### Governor with Timelock
501
502
```solidity
503
import {GovernorTimelockControlUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol";
504
import {TimelockControllerUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/TimelockControllerUpgradeable.sol";
505
506
contract Timelocked Governor is MyGovernor, GovernorTimelockControlUpgradeable {
507
function initialize(
508
IVotes _token,
509
TimelockControllerUpgradeable _timelock,
510
uint256 _votingDelay,
511
uint256 _votingPeriod,
512
uint256 _proposalThreshold,
513
uint256 _quorumPercentage
514
) initializer public {
515
MyGovernor.initialize(_token, _votingDelay, _votingPeriod, _proposalThreshold, _quorumPercentage);
516
__GovernorTimelockControl_init(_timelock);
517
}
518
519
// Required overrides for timelock integration
520
function state(uint256 proposalId) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (ProposalState) {
521
return super.state(proposalId);
522
}
523
524
function proposalNeedsQueuing(uint256 proposalId) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (bool) {
525
return super.proposalNeedsQueuing(proposalId);
526
}
527
528
function _queueOperations(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint48) {
529
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
530
}
531
532
function _executeOperations(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {
533
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
534
}
535
536
function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint256) {
537
return super._cancel(targets, values, calldatas, descriptionHash);
538
}
539
}
540
```