Secure Smart Contract library providing battle-tested implementations of industry-standard Solidity contracts including ERC20, ERC721, ERC1155 tokens, access control mechanisms, proxy patterns, and governance systems for Ethereum and EVM-compatible blockchains.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Import governance contracts using Solidity import statements:
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/TimelockController.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";Core governance system providing flexible on-chain governance with proposal management, voting mechanisms, and execution capabilities.
abstract contract Governor is Context, ERC165, EIP712, IGovernor {
function name() public view virtual returns (string memory);
function version() public view virtual returns (string memory);
function hashProposal(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public pure virtual returns (uint256);
function state(uint256 proposalId) public view virtual returns (ProposalState);
function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
function proposalThreshold() public view virtual returns (uint256);
function votingDelay() public view virtual returns (uint256);
function votingPeriod() public view virtual returns (uint256);
function quorum(uint256 blockNumber) public view virtual returns (uint256);
function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256);
function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);
function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description) public virtual returns (uint256);
function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public payable virtual returns (uint256);
function cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public virtual returns (uint256);
function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256);
function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason) public virtual returns (uint256);
function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params) public virtual returns (uint256);
function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) public virtual returns (uint256);
function castVoteWithReasonAndParamsBySig(uint256 proposalId, uint8 support, string calldata reason, bytes memory params, uint8 v, bytes32 r, bytes32 s) public virtual returns (uint256);
}enum ProposalState {
Pending,
Active,
Canceled,
Defeated,
Succeeded,
Queued,
Expired,
Executed
}event ProposalCreated(uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description);
event ProposalCanceled(uint256 proposalId);
event ProposalExecuted(uint256 proposalId);
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
event VoteCastWithParams(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params);Timelock mechanism for governance operations ensuring a delay between proposal approval and execution for security and transparency.
contract TimelockController is AccessControl {
function isOperation(bytes32 id) public view virtual returns (bool registered);
function isOperationPending(bytes32 id) public view virtual returns (bool pending);
function isOperationReady(bytes32 id) public view virtual returns (bool ready);
function isOperationDone(bytes32 id) public view virtual returns (bool done);
function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp);
function getMinDelay() public view virtual returns (uint256 duration);
function hashOperation(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt) public pure virtual returns (bytes32 hash);
function hashOperationBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt) public pure virtual returns (bytes32 hash);
function schedule(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt, uint256 delay) public virtual;
function scheduleBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt, uint256 delay) public virtual;
function cancel(bytes32 id) public virtual;
function execute(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt) public payable virtual;
function executeBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt) public payable virtual;
function updateDelay(uint256 newDelay) external virtual;
}bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE");event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay);
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);
event Cancelled(bytes32 indexed id);
event MinDelayChange(uint256 oldDuration, uint256 newDuration);Configurable governance parameters for voting delay, voting period, and proposal threshold.
abstract contract GovernorSettings is Governor {
function setVotingDelay(uint256 newVotingDelay) public virtual onlyGovernance;
function setVotingPeriod(uint256 newVotingPeriod) public virtual onlyGovernance;
function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance;
}Simple counting mechanism supporting Against, For, and Abstain votes.
abstract contract GovernorCountingSimple is Governor {
function COUNTING_MODE() public pure virtual override returns (string memory);
function proposalVotes(uint256 proposalId) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes);
}Integration with vote-enabled tokens (like ERC20Votes) for determining voting power.
abstract contract GovernorVotes is Governor {
constructor(IVotes _token);
function token() public view virtual returns (IVotes);
}Quorum calculation based on a fraction of the total token supply.
abstract contract GovernorVotesQuorumFraction is GovernorVotes {
function quorumNumerator() public view virtual returns (uint256);
function quorumDenominator() public view virtual returns (uint256);
function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance;
}Integration between Governor and TimelockController for delayed execution.
abstract contract GovernorTimelockControl is Governor {
constructor(TimelockController _timelock);
function timelock() public view virtual override returns (address);
function proposalEta(uint256 proposalId) public view virtual override returns (uint256);
function queue(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash) public virtual returns (uint256);
}Prevents late quorum manipulation by extending the voting period when quorum is reached near the deadline.
abstract contract GovernorPreventLateQuorum is Governor {
function lateQuorumVoteExtension() public view virtual returns (uint64);
function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256);
function setLateQuorumVoteExtension(uint64 newVoteExtension) external virtual onlyGovernance;
}Sets minimum voting power required to create proposals, preventing spam.
abstract contract GovernorProposalThreshold is Governor {
function proposalThreshold() public view virtual override returns (uint256);
}Compound-compatible voting weight extraction from ERC20VotesComp tokens.
abstract contract GovernorVotesComp is Governor {
constructor(ERC20VotesComp _token);
function token() public view virtual returns (IERC20);
function getVotes(address account, uint256 blockNumber) public view virtual override returns (uint256);
}Integration with Compound-style timelock for legacy compatibility.
abstract contract GovernorTimelockCompound is Governor {
constructor(TimelockInterface _timelock);
function timelock() public view virtual override returns (address);
function proposalEta(uint256 proposalId) public view virtual override returns (uint256);
}Full compatibility layer providing GovernorBravo interface for existing integrations.
abstract contract GovernorCompatibilityBravo is Governor, GovernorTimelockControl {
function propose(address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) public virtual returns (uint256);
function queue(uint256 proposalId) public virtual;
function execute(uint256 proposalId) public payable virtual;
function cancel(uint256 proposalId) public virtual;
function getActions(uint256 proposalId) external view virtual returns (address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas);
function getReceipt(uint256 proposalId, address voter) external view virtual returns (Receipt memory);
}pragma solidity ^0.8.0;
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
contract MyDAO is
Governor,
GovernorSettings,
GovernorCountingSimple,
GovernorVotes,
GovernorVotesQuorumFraction,
GovernorTimelockControl
{
constructor(
IVotes _token,
TimelockController _timelock,
uint256 _votingDelay,
uint256 _votingPeriod,
uint256 _proposalThreshold,
uint256 _quorumPercentage
)
Governor("MyDAO")
GovernorSettings(_votingDelay, _votingPeriod, _proposalThreshold)
GovernorVotes(_token)
GovernorVotesQuorumFraction(_quorumPercentage)
GovernorTimelockControl(_timelock)
{}
function votingDelay() public view override(IGovernor, GovernorSettings) returns (uint256) {
return super.votingDelay();
}
function votingPeriod() public view override(IGovernor, GovernorSettings) returns (uint256) {
return super.votingPeriod();
}
function quorum(uint256 blockNumber) public view override(IGovernor, GovernorVotesQuorumFraction) returns (uint256) {
return super.quorum(blockNumber);
}
function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
return super.proposalThreshold();
}
}// Create a proposal
address[] memory targets = new address[](1);
uint256[] memory values = new uint256[](1);
bytes[] memory calldatas = new bytes[](1);
targets[0] = address(treasury);
values[0] = 0;
calldatas[0] = abi.encodeWithSelector(Treasury.withdraw.selector, recipient, amount);
uint256 proposalId = governor.propose(
targets,
values,
calldatas,
"Proposal #1: Withdraw funds from treasury"
);
// Vote on the proposal (after voting delay)
governor.castVote(proposalId, 1); // 1 = For
// Queue the proposal (if using timelock)
governor.queue(
targets,
values,
calldatas,
keccak256(bytes("Proposal #1: Withdraw funds from treasury"))
);
// Execute the proposal (after timelock delay)
governor.execute(
targets,
values,
calldatas,
keccak256(bytes("Proposal #1: Withdraw funds from treasury"))
);pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
contract GovernanceToken is ERC20Votes {
constructor() ERC20("GovernanceToken", "GOV") EIP712("GovernanceToken", "1") {
_mint(msg.sender, 1000000 * 10**18);
}
function _afterTokenTransfer(address from, address to, uint256 amount) internal override(ERC20Votes) {
super._afterTokenTransfer(from, to, amount);
}
function _mint(address to, uint256 amount) internal override(ERC20Votes) {
super._mint(to, amount);
}
function _burn(address account, uint256 amount) internal override(ERC20Votes) {
super._burn(account, amount);
}
}Governance contracts may revert with various errors:
GovernorAlreadyCastVote(address voter), GovernorDisabledDeposit(), GovernorInvalidProposalLength(uint256 targets, uint256 calldatas, uint256 values), etc.TimelockInsufficientDelay(uint256 delay, uint256 minDelay), TimelockInvalidOperation(bytes32 operationId), etc.Install with Tessl CLI
npx tessl i tessl/npm-openzeppelin-solidity