CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-openzeppelin-solidity

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.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

governance.mddocs/

Governance

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.

Core Imports

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";

Capabilities

Governor Framework

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);
}

Proposal States

enum ProposalState {
    Pending,
    Active,
    Canceled,
    Defeated,
    Succeeded,
    Queued,
    Expired,
    Executed
}

Events

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 Controller

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;
}

Timelock Roles

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");

Events

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);

Governor Extensions

Governor Settings

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;
}

Governor Counting Simple

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);
}

Governor Votes

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);
}

Governor Votes Quorum Fraction

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;
}

Governor Timelock Control

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);
}

Governor Prevent Late Quorum

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;
}

Governor Proposal Threshold

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

abstract contract GovernorProposalThreshold is Governor {
    function proposalThreshold() public view virtual override returns (uint256);
}

Governor Votes Comp

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);
}

Governor Timelock Compound

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);
}

Governor Compatibility Bravo

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);
}

Usage Example

Basic DAO Setup

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();
    }
}

Creating and Executing Proposals

// 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"))
);

Governance Best Practices

  1. Voting Power: Use vote-enabled tokens (ERC20Votes) to determine voting power
  2. Quorum: Set appropriate quorum thresholds to ensure legitimacy
  3. Timelock: Use timelock delays to allow for community review and emergency responses
  4. Proposal Threshold: Set reasonable proposal thresholds to prevent spam
  5. Voting Period: Balance adequate deliberation time with operational efficiency
  6. Emergency Procedures: Implement emergency mechanisms for critical vulnerabilities

Integration with Token Voting

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);
    }
}

Error Handling

Governance contracts may revert with various errors:

  • Governor: GovernorAlreadyCastVote(address voter), GovernorDisabledDeposit(), GovernorInvalidProposalLength(uint256 targets, uint256 calldatas, uint256 values), etc.
  • TimelockController: TimelockInsufficientDelay(uint256 delay, uint256 minDelay), TimelockInvalidOperation(bytes32 operationId), etc.
  • Access Control: Standard AccessControl errors for role-based permissions

Install with Tessl CLI

npx tessl i tessl/npm-openzeppelin-solidity

docs

access-control.md

crosschain.md

finance.md

governance.md

index.md

metatx.md

proxy.md

security.md

tokens.md

utilities.md

tile.json