DAO Development
A DAO is smart contracts plus a social layer. Contracts ensure execution of decisions without trusting specific people; the social layer forms consensus before anything goes on-chain. Technically, you can build a DAO in a week using Governor Bravo or OpenZeppelin Governor. But most DAOs with solid codebases die precisely due to poor governance design, not code quality.
Here we'll examine both layers: what exactly is implemented on-chain, which patterns work in production, and where governance design matters more than code.
On-chain Governor Architecture
OpenZeppelin Governor as Foundation
OpenZeppelin Governor (OZ 4.x+) is a modular framework: core logic plus interchangeable modules for voting, counting, quorum, and timelock. Most production DAOs today use it or Governor Bravo (Compound).
Minimal configuration:
contract MyDAO is
Governor,
GovernorSettings, // votingDelay, votingPeriod, proposalThreshold
GovernorCountingSimple, // FOR / AGAINST / ABSTAIN
GovernorVotes, // ERC20Votes or ERC721Votes
GovernorVotesQuorumFraction, // quorum as % of total supply
GovernorTimelockControl // TimelockController integration
{
constructor(IVotes _token, TimelockController _timelock)
Governor("MyDAO")
GovernorSettings(7200, 50400, 1000e18) // 1 day delay, 1 week voting, 1000 token threshold
GovernorVotes(_token)
GovernorVotesQuorumFraction(4) // 4% quorum
GovernorTimelockControl(_timelock)
{}
}
ERC20Votes: Voting Snapshots
ERC20Votes extends standard ERC-20 by adding a _delegate mechanism and checkpoint history. Every transfer or delegation creates a checkpoint. Voting uses voting power at the proposalSnapshot block, not current balance — this prevents buying tokens specifically for voting.
// Users must delegate themselves (or others) to activate voting power
token.delegate(msg.sender);
// Voting power at snapshot moment
uint256 power = token.getPastVotes(account, proposalSnapshot);
Important: tokens without delegation don't participate in voting. This often surprises new users. UX should remind users about delegation on first wallet use.
TimelockController: Execution Delay
Timelock is mandatory for production DAOs. An approved proposal doesn't execute immediately; it's queued and executed after a delay (typically 2-7 days). This window allows the community to notice potentially dangerous proposals and exit the protocol before execution.
TimelockController roles:
- PROPOSER — who can queue proposals (usually only Governor contract)
-
EXECUTOR — who can execute (often
address(0)— anyone) - CANCELLER — who can cancel (multisig team as safety valve)
Minimum delay is a safety parameter. 48 hours is the absolute minimum for protocols with real funds. Compound and Aave use 2-7 days.
Proposal Lifecycle
Create proposal → votingDelay (to fix snapshot) →
votingPeriod (FOR/AGAINST/ABSTAIN) →
(if passed) queue in timelock →
timelockDelay →
execute
A proposal contains arrays of calls: targets[], values[], calldatas[]. One proposal can execute arbitrary on-chain actions atomically — change protocol parameters, transfer treasury funds, upgrade contracts.
// Proposal: change protocol fee from 0.3% to 0.5%
address[] memory targets = new address[](1);
targets[0] = address(protocolFeeManager);
uint256[] memory values = new uint256[](1);
values[0] = 0;
bytes[] memory calldatas = new bytes[](1);
calldatas[0] = abi.encodeWithSignature("setFee(uint256)", 50); // 0.5% = 50 bps
governor.propose(targets, values, calldatas, "Increase protocol fee to 0.5%");
Treasury Management
A DAO typically manages a treasury — protocol reserves. Standard pattern: the treasury is the TimelockController itself (holds ETH and tokens), or a separate contract like Gnosis Safe with Governor as the only owner.
Gnosis Safe + Governor Integration
For small DAOs or early stage: Gnosis Safe with multisig plus the Zodiac SafeSnap module, which executes Snapshot.org votes on-chain. It's cheaper (gasless off-chain voting) and sufficient until enough active token holders accumulate for on-chain governance.
The transition from multisig to full on-chain governance is a separate milestone. Typical path: multisig (launch) → multisig + Snapshot (community growth) → full on-chain Governor (mature protocol).
Diversification and Stability
A treasury consisting 100% of native tokens is high-risk. A bear market collapses the runway. Production DAOs diversify: 20-30% USDC/DAI for operations, remainder as native tokens. Diversification happens through governance-approved proposals for DEX swaps or OTC deals.
Delegation and Off-chain Coordination
Delegate System
Most token holders don't vote directly. Compound introduced the delegate concept: token holders delegate voting power to known participants (researchers, core contributors, DAO specialists) who actively participate in governance.
Delegate profile is a Discourse/Mirror post with positions on key issues. Implemented through ERC20Votes.delegate(). Delegation doesn't transfer tokens — only voting power.
Off-chain Governance (Snapshot)
Snapshot.org enables gasless voting through message signatures. Used for signal votes (temperature checks) unrelated to on-chain actions. Strategies: erc20-balance-of, erc20-votes-with-overrides, delegation, and dozens of custom strategies.
Typical two-step process:
- Temperature check on Snapshot — assess sentiment, gasless
- On-chain proposal — if temperature check passes with 60%+ support
Governance Security
Flash Loan Attack on Governance
Attack: flash loan → gain temporary control of large token amounts → delegate to self → create or push proposal → repay loan. For proposal creation: proposalThreshold must be high enough. For voting: proposalSnapshot is fixed in the past; flash loan doesn't help (no delegation history in current block).
ERC20Votes is protected from flash loan voting attacks precisely through the checkpoint mechanism. Vulnerability exists only at proposalThreshold if set too low.
Proposal Spam and DOS
Without proposal creation threshold, protocols drown in spam. proposalThreshold (minimum tokens to create proposals) is mandatory. Typical values: 0.1% - 1% of total supply.
Governance Takeover
If an attacker accumulates >50% voting power (or >quorum with low turnout), they can pass any proposal. Defenses:
- High quorum (4-10% of supply)
- Timelock with sufficient delay (7 days)
- Guardian multisig with CANCELLER role in TimelockController
-
GovernorPreventLateQuorum— extends voting period if quorum reached in last moments (prevents last-minute whale swings)
Upgrades via DAO
Smart contracts upgrade via DAO proposal plus timelock. Upgrade patterns:
UUPS/Transparent Proxy + DAO owner. Governor is proxy owner. Proposal calls upgradeTo(newImplementation). Timelock gives community time to review new code before activation.
Modular architecture without proxy. Each module is replaced via governance: proposal changes module address in registry contract. Less risky than full upgrade.
Stack and Typical Timeline
Basic on-chain DAO: OpenZeppelin Governor + TimelockController + ERC20Votes. 2-3 weeks development, 2-3 weeks audit.
DAO with treasury management, delegation UI, Snapshot integration, Guardian multisig: 6-10 weeks development.
Full DAO platform with custom modules, veToken governance, gauge system, bribe market: 3-6 months.
| Component | Technology | Mandatory |
|---|---|---|
| Governor | OZ Governor / Governor Bravo | Yes |
| Voting token | ERC20Votes | Yes |
| Timelock | TimelockController | Yes, for production |
| Off-chain voting | Snapshot.org | Recommended |
| Treasury | Safe multisig or Timelock | Yes |
| Delegation UI | Tally / Boardroom / Custom | Recommended |
| Forum | Discourse / Commonwealth | Yes (social layer) |
Technical stack: Solidity 0.8.x + Foundry + OpenZeppelin 5.x. Frontend: wagmi + viem + React. Indexing: The Graph subgraph for proposals and votes (frontend can't show history without subgraph without event iteration).
Cost is calculated after defining governance model and scope.







