or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdcrosschain.mdfinance.mdgovernance.mdindex.mdmetatx.mdproxy.mdsecurity.mdtokens.mdutilities.md

governance.mddocs/

0

# Governance

1

2

OpenZeppelin Contracts provides a comprehensive governance framework enabling decentralized decision-making through on-chain voting mechanisms, proposal management, and timelock controllers for secure governance operations.

3

4

## Core Imports

5

6

Import governance contracts using Solidity import statements:

7

8

```solidity

9

import "@openzeppelin/contracts/governance/Governor.sol";

10

import "@openzeppelin/contracts/governance/TimelockController.sol";

11

import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";

12

import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";

13

import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";

14

import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";

15

import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";

16

```

17

18

## Capabilities

19

20

### Governor Framework

21

22

Core governance system providing flexible on-chain governance with proposal management, voting mechanisms, and execution capabilities.

23

24

```solidity { .api }

25

abstract contract Governor is Context, ERC165, EIP712, IGovernor {

26

function name() public view virtual returns (string memory);

27

function version() public view virtual returns (string memory);

28

function hashProposal(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public pure virtual returns (uint256);

29

function state(uint256 proposalId) public view virtual returns (ProposalState);

30

function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);

31

function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);

32

function proposalThreshold() public view virtual returns (uint256);

33

function votingDelay() public view virtual returns (uint256);

34

function votingPeriod() public view virtual returns (uint256);

35

function quorum(uint256 blockNumber) public view virtual returns (uint256);

36

function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256);

37

function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);

38

function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) public virtual returns (uint256);

39

function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public payable virtual returns (uint256);

40

function cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public virtual returns (uint256);

41

function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256);

42

function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) public virtual returns (uint256);

43

function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) public virtual returns (uint256);

44

function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) public virtual returns (uint256);

45

function castVoteWithReasonAndParamsBySig(uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s) public virtual returns (uint256);

46

}

47

```

48

49

#### Proposal States

50

51

```solidity { .api }

52

enum ProposalState {

53

Pending,

54

Active,

55

Canceled,

56

Defeated,

57

Succeeded,

58

Queued,

59

Expired,

60

Executed

61

}

62

```

63

64

#### Events

65

66

```solidity { .api }

67

event ProposalCreated(uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description);

68

event ProposalCanceled(uint256 proposalId);

69

event ProposalExecuted(uint256 proposalId);

70

event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);

71

event VoteCastWithParams(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params);

72

```

73

74

### Timelock Controller

75

76

Timelock mechanism for governance operations ensuring a delay between proposal approval and execution for security and transparency.

77

78

```solidity { .api }

79

contract TimelockController is AccessControl {

80

function isOperation(bytes32 id) public view virtual returns (bool registered);

81

function isOperationPending(bytes32 id) public view virtual returns (bool pending);

82

function isOperationReady(bytes32 id) public view virtual returns (bool ready);

83

function isOperationDone(bytes32 id) public view virtual returns (bool done);

84

function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp);

85

function getMinDelay() public view virtual returns (uint256 duration);

86

function hashOperation(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt) public pure virtual returns (bytes32 hash);

87

function hashOperationBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt) public pure virtual returns (bytes32 hash);

88

function schedule(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt, uint256 delay) public virtual;

89

function scheduleBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt, uint256 delay) public virtual;

90

function cancel(bytes32 id) public virtual;

91

function execute(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt) public payable virtual;

92

function executeBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt) public payable virtual;

93

function updateDelay(uint256 newDelay) external virtual;

94

}

95

```

96

97

#### Timelock Roles

98

99

```solidity { .api }

100

bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");

101

bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");

102

bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");

103

bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE");

104

```

105

106

#### Events

107

108

```solidity { .api }

109

event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay);

110

event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);

111

event Cancelled(bytes32 indexed id);

112

event MinDelayChange(uint256 oldDuration, uint256 newDuration);

113

```

114

115

### Governor Extensions

116

117

#### Governor Settings

118

119

Configurable governance parameters for voting delay, voting period, and proposal threshold.

120

121

```solidity { .api }

122

abstract contract GovernorSettings is Governor {

123

function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance;

124

function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance;

125

function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance;

126

}

127

```

128

129

#### Governor Counting Simple

130

131

Simple counting mechanism supporting Against, For, and Abstain votes.

132

133

```solidity { .api }

134

abstract contract GovernorCountingSimple is Governor {

135

function COUNTING_MODE() public pure virtual override returns (string memory);

136

function proposalVotes(uint256 proposalId) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes);

137

}

138

```

139

140

#### Governor Votes

141

142

Integration with vote-enabled tokens (like ERC20Votes) for determining voting power.

143

144

```solidity { .api }

145

abstract contract GovernorVotes is Governor {

146

constructor(IVotes _token);

147

function token() public view virtual returns (IVotes);

148

}

149

```

150

151

#### Governor Votes Quorum Fraction

152

153

Quorum calculation based on a fraction of the total token supply.

154

155

```solidity { .api }

156

abstract contract GovernorVotesQuorumFraction is GovernorVotes {

157

function quorumNumerator() public view virtual returns (uint256);

158

function quorumDenominator() public view virtual returns (uint256);

159

function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance;

160

}

161

```

162

163

#### Governor Timelock Control

164

165

Integration between Governor and TimelockController for delayed execution.

166

167

```solidity { .api }

168

abstract contract GovernorTimelockControl is Governor {

169

constructor(TimelockController _timelock);

170

function timelock() public view virtual override returns (address);

171

function proposalEta(uint256 proposalId) public view virtual override returns (uint256);

172

function queue(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public virtual returns (uint256);

173

}

174

```

175

176

#### Governor Prevent Late Quorum

177

178

Prevents late quorum manipulation by extending the voting period when quorum is reached near the deadline.

179

180

```solidity { .api }

181

abstract contract GovernorPreventLateQuorum is Governor {

182

function lateQuorumVoteExtension() public view virtual returns (uint64);

183

function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256);

184

function setLateQuorumVoteExtension(uint64 newVoteExtension) external virtual onlyGovernance;

185

}

186

```

187

188

#### Governor Proposal Threshold

189

190

Sets minimum voting power required to create proposals, preventing spam.

191

192

```solidity { .api }

193

abstract contract GovernorProposalThreshold is Governor {

194

function proposalThreshold() public view virtual override returns (uint256);

195

}

196

```

197

198

#### Governor Votes Comp

199

200

Compound-compatible voting weight extraction from ERC20VotesComp tokens.

201

202

```solidity { .api }

203

abstract contract GovernorVotesComp is Governor {

204

constructor(ERC20VotesComp _token);

205

function token() public view virtual returns (IERC20);

206

function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256);

207

}

208

```

209

210

#### Governor Timelock Compound

211

212

Integration with Compound-style timelock for legacy compatibility.

213

214

```solidity { .api }

215

abstract contract GovernorTimelockCompound is Governor {

216

constructor(TimelockInterface _timelock);

217

function timelock() public view virtual override returns (address);

218

function proposalEta(uint256 proposalId) public view virtual override returns (uint256);

219

}

220

```

221

222

#### Governor Compatibility Bravo

223

224

Full compatibility layer providing GovernorBravo interface for existing integrations.

225

226

```solidity { .api }

227

abstract contract GovernorCompatibilityBravo is Governor, GovernorTimelockControl {

228

function propose(address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) public virtual returns (uint256);

229

function queue(uint256 proposalId) public virtual;

230

function execute(uint256 proposalId) public payable virtual;

231

function cancel(uint256 proposalId) public virtual;

232

function getActions(uint256 proposalId) external view virtual returns (address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas);

233

function getReceipt(uint256 proposalId, address voter) external view virtual returns (Receipt memory);

234

}

235

```

236

237

## Usage Example

238

239

### Basic DAO Setup

240

241

```solidity

242

pragma solidity ^0.8.0;

243

244

import "@openzeppelin/contracts/governance/Governor.sol";

245

import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";

246

import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";

247

import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";

248

import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";

249

import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";

250

251

contract MyDAO is

252

Governor,

253

GovernorSettings,

254

GovernorCountingSimple,

255

GovernorVotes,

256

GovernorVotesQuorumFraction,

257

GovernorTimelockControl

258

{

259

constructor(

260

IVotes _token,

261

TimelockController _timelock,

262

uint256 _votingDelay,

263

uint256 _votingPeriod,

264

uint256 _proposalThreshold,

265

uint256 _quorumPercentage

266

)

267

Governor("MyDAO")

268

GovernorSettings(_votingDelay, _votingPeriod, _proposalThreshold)

269

GovernorVotes(_token)

270

GovernorVotesQuorumFraction(_quorumPercentage)

271

GovernorTimelockControl(_timelock)

272

{}

273

274

function votingDelay() public view override(IGovernor, GovernorSettings) returns (uint256) {

275

return super.votingDelay();

276

}

277

278

function votingPeriod() public view override(IGovernor, GovernorSettings) returns (uint256) {

279

return super.votingPeriod();

280

}

281

282

function quorum(uint256 blockNumber) public view override(IGovernor, GovernorVotesQuorumFraction) returns (uint256) {

283

return super.quorum(blockNumber);

284

}

285

286

function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {

287

return super.proposalThreshold();

288

}

289

}

290

```

291

292

### Creating and Executing Proposals

293

294

```solidity

295

// Create a proposal

296

address[] memory targets = new address[](1);

297

uint256[] memory values = new uint256[](1);

298

bytes[] memory calldatas = new bytes[](1);

299

300

targets[0] = address(treasury);

301

values[0] = 0;

302

calldatas[0] = abi.encodeWithSelector(Treasury.withdraw.selector, recipient, amount);

303

304

uint256 proposalId = governor.propose(

305

targets,

306

values,

307

calldatas,

308

"Proposal #1: Withdraw funds from treasury"

309

);

310

311

// Vote on the proposal (after voting delay)

312

governor.castVote(proposalId, 1); // 1 = For

313

314

// Queue the proposal (if using timelock)

315

governor.queue(

316

targets,

317

values,

318

calldatas,

319

keccak256(bytes("Proposal #1: Withdraw funds from treasury"))

320

);

321

322

// Execute the proposal (after timelock delay)

323

governor.execute(

324

targets,

325

values,

326

calldatas,

327

keccak256(bytes("Proposal #1: Withdraw funds from treasury"))

328

);

329

```

330

331

## Governance Best Practices

332

333

1. **Voting Power**: Use vote-enabled tokens (ERC20Votes) to determine voting power

334

2. **Quorum**: Set appropriate quorum thresholds to ensure legitimacy

335

3. **Timelock**: Use timelock delays to allow for community review and emergency responses

336

4. **Proposal Threshold**: Set reasonable proposal thresholds to prevent spam

337

5. **Voting Period**: Balance adequate deliberation time with operational efficiency

338

6. **Emergency Procedures**: Implement emergency mechanisms for critical vulnerabilities

339

340

## Integration with Token Voting

341

342

```solidity

343

pragma solidity ^0.8.0;

344

345

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";

346

347

contract GovernanceToken is ERC20Votes {

348

constructor() ERC20("GovernanceToken", "GOV") EIP712("GovernanceToken", "1") {

349

_mint(msg.sender, 1000000 * 10**18);

350

}

351

352

function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20Votes) {

353

super._afterTokenTransfer(from, to, amount);

354

}

355

356

function _mint(address to, uint256 amount) internal override(ERC20Votes) {

357

super._mint(to, amount);

358

}

359

360

function _burn(address account, uint256 amount) internal override(ERC20Votes) {

361

super._burn(account, amount);

362

}

363

}

364

```

365

366

## Error Handling

367

368

Governance contracts may revert with various errors:

369

370

- **Governor**: `GovernorAlreadyCastVote(address voter)`, `GovernorDisabledDeposit()`, `GovernorInvalidProposalLength(uint256 targets, uint256 calldatas, uint256 values)`, etc.

371

- **TimelockController**: `TimelockInsufficientDelay(uint256 delay, uint256 minDelay)`, `TimelockInvalidOperation(bytes32 operationId)`, etc.

372

- **Access Control**: Standard AccessControl errors for role-based permissions