DAO Contract Development: Governor, Timelock, Voting

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1All 1305 services
DAO Contract Development: Governor, Timelock, Voting
Complex
~1-2 weeks
Frequently Asked Questions

Blockchain Development Services

Blockchain Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1349
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    949
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1183
  • image_logo-advance_0.webp
    B2B Advance company logo design
    642
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    921

DAO on paper looks simple: tokens = votes, majority decides. In practice, it's one of the most complex areas of smart contracts—not because the code is particularly hard, but because the cost of a governance mechanics error is catastrophically high. A proposal passes with a quorum logic bug, and an attacker drains the treasury. This happened with Beanstalk, where a flash loan governance attack stole $182M.Beanstalk incident Developing DAO contracts is about designing an economically secure decision-making system. We provide a turnkey service: from economic model design to audit and launch. Our experience: over 10 years in blockchain development, over 50 successful projects, including integration with OpenZeppelin Governor and SafeSnap. We guarantee audits by leading firms.

Decentralized autonomous organization

How DAO Architecture Works

Governor + Timelock

The de facto standard is OpenZeppelin Governor with TimelockController. Governor manages the proposal lifecycle (creation, voting, queuing), while Timelock adds a delay between proposal approval and execution.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

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 DAOGovernor is
    Governor,
    GovernorSettings,
    GovernorCountingSimple,
    GovernorVotes,
    GovernorVotesQuorumFraction,
    GovernorTimelockControl
{
    constructor(
        IVotes _token,
        TimelockController _timelock
    )
        Governor("DAO Governor")
        GovernorSettings(
            1,          // votingDelay: 1 block (~12 sec on Ethereum)
            50400,      // votingPeriod: ~7 days in blocks
            100_000e18  // proposalThreshold: min 100K tokens for proposal
        )
        GovernorVotes(_token)
        GovernorVotesQuorumFraction(10)  // 10% of total supply = quorum
        GovernorTimelockControl(_timelock)
    {}

    function quorum(uint256 blockNumber)
        public view override(Governor, GovernorVotesQuorumFraction)
        returns (uint256)
    {
        return super.quorum(blockNumber);
    }

    function state(uint256 proposalId)
        public view override(Governor, GovernorTimelockControl)
        returns (ProposalState)
    {
        return super.state(proposalId);
    }

    function _execute(uint256 proposalId, address[] memory targets,
        uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
        internal override(Governor, GovernorTimelockControl)
    {
        super._execute(proposalId, targets, values, calldatas, descriptionHash);
    }

    function _cancel(address[] memory targets, uint256[] memory values,
        bytes[] memory calldatas, bytes32 descriptionHash)
        internal override(Governor, GovernorTimelockControl)
        returns (uint256)
    {
        return super._cancel(targets, calldatas, descriptionHash);
    }

    function _executor()
        internal view override(Governor, GovernorTimelockControl)
        returns (address)
    {
        return super._executor();
    }
}

TimelockController Setup

Timelock is a critical component. It gives the community time to react to an approved proposal before execution. Minimum delay for treasury operations is 48 hours, for contract upgrades it's 72 hours.

// Deploy TimelockController
// minDelay: 172800 (48 hours in seconds)
// proposers: [address(governor)]
// executors: [address(0)] — anyone can execute after delay
// admin: address(0) — no superadmin, only through Timelock

TimelockController timelock = new TimelockController(
    172800,
    proposers,  // only Governor can queue
    executors,  // address(0) = anyone can execute
    address(0)  // admin revoked
);

executors: [address(0)] means anyone can execute the operation after the delay—this is correct. Otherwise, a specific address would create a centralization point that must press "execute".

Proposal Lifecycle

Pending → Active → Succeeded/Defeated → Queued → Executed
                          ↓
                       Canceled
  • Pending: proposal created, waits for votingDelay blocks. Vote snapshot is taken at the last block before transition to Active.
  • Active: voting open for votingPeriod blocks. Vote options: For, Against, Abstain.
  • Succeeded: quorum reached, For > Against.
  • Queued: in Timelock queue, waits for minDelay. During this period, a Guardian (if any) can cancel.
  • Executed: executed on-chain.

How to Protect Against Flash Loan Attacks

The Beanstalk scenario: an attacker takes a flash loan for a huge amount, gains temporary governance control (delegateVote for governance weight), creates and immediately passes a malicious proposal, then repays the loan—all in one transaction.

Key defense: snapshot timing. GovernorVotes uses getPastVotes(account, proposalSnapshot)—voting weight is determined at the snapshot block, not the voting block. votingDelay = 1 (one block) already breaks the flash loan attack: you can't borrow tokens and use them in the same block for the snapshot. Additional measures: Timelock delay (48-72 hours), proposal threshold (minimum balance to create proposals), and quorum tied to total supply.

Which Voting Models to Choose?

Three main models: token-weighted, quadratic, and optimistic. Token-weighted voting is simple and predictable, but large holders dominate. Quadratic voting is more equitable—cost of N votes is N²—but requires Sybil resistance. Optimistic governance executes proposals automatically unless vetoed, reducing voter apathy.

Token-weighted voting on L2 (Arbitrum, Optimism) costs 10x less than on L1, while quadratic is only 2x more expensive than simple voting.

Parameter Token-weighted Quadratic Optimistic
Decision speed High Medium Instant
Resistance to whale dominance Low High Medium
Implementation complexity Low High (needs Sybil) Medium
Gas cost on L1 $5-20 $10-40 $2-5 (off-chain)
Parameter Recommended Value Note
votingDelay 1 block Flash loan protection
votingPeriod 50400 blocks (~7 days) Sufficient for global community
proposalThreshold 100,000 tokens Reduces spam
quorum 10% of total supply Balance between safety and passage

How Does a Multisig Guardian Work?

Fully on-chain governance is vulnerable in early stages: few tokens in circulation, low turnout, easy to manipulate. Standard practice—Guardian multisig (Gnosis Safe 3/5 or 4/7) that can cancel queued proposals, but cannot initiate or execute them.

// In TimelockController: CANCELLER_ROLE for Guardian Safe
timelock.grantRole(timelock.CANCELLER_ROLE(), guardianSafe);

Guardian should not have PROPOSER_ROLE or EXECUTOR_ROLE—only CANCELLER. This creates asymmetric protection: Guardian protects against attacks but does not control governance. As the community grows, Guardian is gradually phased out.

Sub-DAOs and Specialized Committees

A monolithic Governor for all decisions is an antipattern. Typical multi-level structure: Core DAO Governor (major decisions, 7-14 day voting), Treasury Committee (fast operations < $100K), Technical Committee (audit, emergency pause), Grants Committee (budget $5-20K, off-chain voting via Snapshot).

Gasless Voting via EIP-712

The main problem of on-chain voting is gas cost. On Ethereum mainnet, one vote costs $5-20. Most DAOs solve this with off-chain voting (Snapshot) and on-chain execution. Hybrid approach: voting on Snapshot (free, EIP-712 signature), result executed via SafeSnap. For on-chain voting on L2 (Arbitrum, Optimism, Base), gas is already acceptable—$0.05-0.50 per transaction.

What's Included

  • Governance model design: parameters, committees, Guardian scheme.
  • Smart contract development: Governor, Timelock, token, attack-scenario tests.
  • Internal security review and formal verification of the most critical modules.
  • External audit (optional—with our recommendation of top firms).
  • Integration with Snapshot, Tally.xyz, SafeSnap.
  • Documentation: technical spec, deploy runbook, emergency procedures description.
  • Team training: how to create proposals, interpret results, respond to incidents.
  • Post-launch support: monitoring, updates when standards change (EIP).

Process

  1. Governance design (1-2 weeks). Define voting model, parameters, committee structure, Guardian scheme.
  2. Contract development (2-3 weeks). Governor + Timelock + Governance token + attack-scenario tests.
  3. Security (1-2 weeks). Internal review of all scenarios, flash loan tests.
  4. Audit (2-3 weeks). External audit is mandatory.
  5. Frontend and integration (2-3 weeks). Tally.xyz, Snapshot, SafeSnap.
  6. Gradual launch. Start with Guardian multisig, reduce centralization per roadmap.

Full cycle: 3-4 months. Cost is calculated individually based on governance model complexity and whether an existing token is available. Gas optimization can save up to 30%, and audit cost reduction up to 20% due to our preparation.

Ready to start? Contact us for a detailed discussion of your DAO.

More about post-launch supportWe provide monitoring and contract updates when standards change.

Get a consultation: contact us to discuss your project—we'll evaluate it for free and offer the optimal solution. Order DAO contract development with audit guarantee and our 10+ years of experience.

DAO Development: Governance That Works

We have extensive experience in DAO development, having executed over 30 integrations of Governor, Safe, and Snapshot for protocols with TVL ranging from $1M to $500M. The problem is typical: the protocol is launched, liquidity exists, the token is distributed. The next step is handing control to the community. In practice, this means someone has to write contracts that prevent 5% of holders from draining the treasury through a single vote, while not locking legitimate upgrades for 18 months. The balance is nontrivial.

Why do most DAOs become oligarchies?

Typical scenario: fork OpenZeppelin Governor, deploy, launch Snapshot — and end up with a DAO effectively run by 3 addresses. The problem isn't the code but the tokenomics and parameters.

Quorum too high or too low. Compound set quorum at 400,000 COMP. With low turnout, proposals fail for months. With low quorum, one large holder can pass any question. The correct quorum depends on actual token distribution and average turnout, not a nice number. We analyze voting history, locked vs. circulating ratio, and select a dynamic quorum via GovernorVotesQuorumFraction.

Flash loan governance attack. Classic: attacker takes a flash loan, obtains voting power for one block, creates and passes a proposal. Protection: votingDelay of at least 1-2 blocks plus a snapshot at the proposal creation block, not at the voting block. OpenZeppelin's GovernorVotes handles the snapshot correctly, but if you write a custom contract, it's easy to miss. Beanstalk lost $182M due to lack of whitelist targets in the timelock — this case became the industry standard mistake.

Timelock without executor whitelist. If TimelockController does not restrict the list of allowed target contracts, an approved proposal can call any function. We always configure TimelockController with a whitelist of addresses and a minimum delay of 48 hours for protocols with TVL > $10M. For larger ones, 7 days, providing time to challenge via hard fork or multisig emergency.

On-chain governance architecture

Standard stack: OpenZeppelin Governor + TimelockController + ERC-20Votes (or ERC-721Votes for NFT-based governance). We use Foundry for development and testing — it allows forking mainnet and simulating attacks against the real state of contracts.

ERC-20Votes token
      │
      ▼
GovernorBravo / OZ Governor  ──→  TimelockController  ──→  Treasury / Protocol
      │
      ▼
  Snapshot (off-chain signaling)

Governor handles voting logic: propose, castVote, queue, execute. Timelock adds a delay between proposal approval and execution — a window for dissenters to exit. Delegated voting via ERC-20Votes is critical for protocols with many passive holders; without it, quorum is physically unreachable.

Snapshot + on-chain: hybrid model

Fully on-chain voting costs gas. For protocols with active communities, this means either high participation barriers or L2. Hybrid model: Snapshot for signaling votes (off-chain, gasless via EIP-712 signatures), on-chain only for execution. We prefer SafeSnap (Zodiac module from Gnosis) — the result is verified via Reality.eth (optimistic oracle) and automatically executed through Safe without a trusted party.

Multi-sig: Gnosis Safe as an operational layer

Most DAOs use Gnosis Safe for treasury. Standard configuration: M-of-N, where N is 7-9 signers from different time zones, M is 4-5. Fewer is unsafe. More is an operational nightmare for urgent transactions. Safe supports modules: Zodiac, Delay, Roles. Through the Roles module, you can grant a specific address the right to call only certain treasury functions — for example, only transfer up to a certain amount, without the right to delegatecall.

Important: Safe multisig and Governor are separate layers. Governor manages the protocol (upgrades, parameters). Safe manages the treasury (payments, grants). Mixing them into one contract is an architectural mistake that can cost millions.

How to protect a DAO from flash loan attacks?

We use multiple layers of protection. First, votingDelay of at least 2 blocks (OZ recommends 1, but we set 2 for extra safety). Second, the snapshot is taken at the proposal creation block, not the voting block — this blocks flash loan attacks because the loan is taken in the same block as voting. Third, GovernorPreventLateQuorum extends the voting period if quorum is reached in the last few blocks — without this extension, a large holder could wait until the end of the period and change the outcome with a single vote.

Governor Extensions: almost always needed

Extension Purpose Note
GovernorTimelockControl Execution delay Mandatory for TVL > $1M
GovernorVotesQuorumFraction Dynamic quorum Better than fixed number
GovernorPreventLateQuorum Protection against last-minute votes EIP-4824 recommends
GovernorSettings On-chain parameter changes Without it, only upgrade

On-chain vs Off-chain voting: when to choose each

Parameter On-chain (OZ Governor) Off-chain (Snapshot)
Gas cost per vote $5-50 on Ethereum Free (signature)
Decentralization Full (minus gas) Requires trusted executor
Finality Atomic Requires bridge (Reality.eth)
Attack complexity Flash loan Sybil attack (solvable)

Choice depends on community budget and security requirements. For protocols with TVL > $50M, we recommend on-chain with L2 (Arbitrum, Optimism) — voting cost drops to $0.05-0.5.

Development process and parameter audit

Work starts not with code but with tokenomics: current token distribution, real turnout of similar protocols, list of operations that should require governance and those that should not. We analyze data via Dune and Nansen to determine realistic quorum and thresholds.

After parameterization: implementation of Governor based on OZ with custom extensions, integration with existing token (or deployment of a new one with ERC-20Votes), configuration of Safe multisig, setup of Snapshot space with correct strategy (often erc20-balance-of is insufficient — a delegation strategy is needed).

Testing includes simulation of governance attacks: flash loan quorum, proposal spam, malicious executor. Foundry allows forking mainnet and running attacks against real contract state. Deploying Governor without parameter audit is a standard mistake. Auditors look at code. But no one checks if a quorum of 10% of totalSupply is unreachable given the current locked/circulating ratio.

We guarantee that parameters are tuned to your community and provide a detailed report justifying every threshold. Experience shows that correct parameterization reduces governance attack risk by 80% (based on our data over 5 years of work).

What you will get in the end

  • Smart contracts: Governor, Timelock, Token (ERC-20Votes/ERC-721Votes) with tests and documentation
  • Configured Safe multisig with modules (Zodiac, Delay, Roles if needed)
  • Snapshot space with custom voting strategy
  • Governance parameter audit: quorum, voting period, delay, delegation mechanics
  • Integration with existing protocol (treasury, staking, bridges)
  • Team support and training (4 hours of consultation)
  • Documentation on governance and emergency procedures

Timeline

Basic DAO system (Governor + Timelock + Safe + Snapshot) — from 3 to 6 weeks. With custom Zodiac modules, non-standard voting strategy, integration with existing protocol — from 6 to 12 weeks. Audit takes separately 2-4 weeks.

Contact us to audit your current configuration or order DAO development with security guarantees — we have completed over 50 such projects and know where the risks hide.