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
- Governance design (1-2 weeks). Define voting model, parameters, committee structure, Guardian scheme.
- Contract development (2-3 weeks). Governor + Timelock + Governance token + attack-scenario tests.
- Security (1-2 weeks). Internal review of all scenarios, flash loan tests.
- Audit (2-3 weeks). External audit is mandatory.
- Frontend and integration (2-3 weeks). Tally.xyz, Snapshot, SafeSnap.
- 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 support
We 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.







