Building a DAO Treasury That Survives Bear Markets and Governance Attacks
We build DAO treasuries that withstand bear markets and governance attacks. One well-known protocol lost 35% of its treasury value due to 80% concentration in its native token during a downturn — our goal is to prevent such scenarios. Optimizing diversification can save a protocol between $500k and $2M per year during market volatility. But it's not just about diversification: governance attacks, flash loan manipulations, and multisig configuration errors are real threats we eliminate at the architecture stage.
The right architecture starts with separating the treasury into access levels and ends with automating execution through streaming. Below are concrete solutions: multi-layer architecture, smart contracts with timelock and streaming, and KPI monitoring. We implement these components in every project, adapting to the specific DAO. Get a free consultation on treasury architecture right now.
Multi-Layer Treasury Architecture
A DAO treasury consists of several levels with different access rights:
Level 1: Core Treasury (Gnosis Safe + Governor)
The main asset vault is managed via on-chain governance. Any expenditure requires a full governance cycle: proposal → voting → timelock → execution. A TimelockController is a mandatory intermediary. Gnosis Safe here is the last vault, not a management tool. This is important: the Safe should not be signers-managed for core funds.
Governance Governor ──propose──► TimelockController ──execute──► Gnosis Safe
▲ (48h delay) │
│ ▼
Token holders Treasury assets
Level 2: Operational Budget (Sub-DAO Safe)
A separate Gnosis Safe for operational expenses with a cap. Managed by a core team with a 3/5 multisig. Refilled from the Core Treasury via a governance proposal once a quarter.
Level 3: Streaming Payments (Sablier / Superfluid)
Salaries and grants via token streaming — contributors receive a continuous flow of tokens that can be stopped at any moment. No manual payouts needed. Streaming payments through Sablier are better than manual payouts — they reduce operational overhead and eliminate delays. For example, a DAO with a team of 20 saves up to $200k per year in operational costs.
Why Streaming Payments Are Better Than Manual Payouts
Manual payouts require constant attention from the treasury manager: signing each transaction, accounting, potential delays. Streaming via Sablier V2 automates the process: funds flow evenly, and cancellation is instantaneous. This is especially important for a distributed team — the contributor sees token inflow in real time and is not dependent on human factors.
Treasury Smart Contracts
Treasury Controller
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/governance/TimelockController.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract DAOTreasury is AccessControl {
using SafeERC20 for IERC20;
bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
mapping(address => uint256) public monthlySpendLimit;
mapping(address => mapping(uint256 => uint256)) public monthlySpent;
event FundsDisbursed(address indexed token, address indexed recipient, uint256 amount, string reason);
event AllocationUpdated(address indexed token, uint256 amount, string strategy);
constructor(address _governor, address _operator) {
_grantRole(DEFAULT_ADMIN_ROLE, _governor);
_grantRole(GOVERNOR_ROLE, _governor);
_grantRole(OPERATOR_ROLE, _operator);
}
function disburse(
address token,
address recipient,
uint256 amount,
string calldata reason
) external onlyRole(GOVERNOR_ROLE) {
IERC20(token).safeTransfer(recipient, amount);
emit FundsDisbursed(token, recipient, amount, reason);
}
function operationalDisburse(
address token,
address recipient,
uint256 amount
) external onlyRole(OPERATOR_ROLE) {
uint256 currentMonth = block.timestamp / 30 days;
uint256 spent = monthlySpent[token][currentMonth];
require(spent + amount <= monthlySpendLimit[token], "Monthly limit exceeded");
monthlySpent[token][currentMonth] = spent + amount;
IERC20(token).safeTransfer(recipient, amount);
emit FundsDisbursed(token, recipient, amount, "operational");
}
function setMonthlyLimit(address token, uint256 limit)
external
onlyRole(GOVERNOR_ROLE)
{
monthlySpendLimit[token] = limit;
}
receive() external payable {}
}
Budget Streams via Sablier V2
import { ISablierV2LockupLinear } from "@sablier/v2-core/interfaces/ISablierV2LockupLinear.sol";
import { LockupLinear, Broker } from "@sablier/v2-core/types/DataTypes.sol";
contract TreasuryStreaming {
ISablierV2LockupLinear public immutable sablier;
IERC20 public immutable daoToken;
function createContributorStream(
address contributor,
uint128 totalAmount,
uint40 startTime,
uint40 endTime,
uint40 cliffDuration,
bool cancelable
) external returns (uint256 streamId) {
daoToken.approve(address(sablier), totalAmount);
LockupLinear.CreateWithDurations memory params = LockupLinear.CreateWithDurations({
sender: address(this),
recipient: contributor,
totalAmount: totalAmount,
asset: daoToken,
cancelable: cancelable,
transferable: false,
durations: LockupLinear.Durations({
cliff: cliffDuration,
total: endTime - startTime
}),
broker: Broker(address(0), ud60x18(0))
});
streamId = sablier.createWithDurations(params);
}
function cancelStream(uint256 streamId) external {
sablier.cancel(streamId);
}
}
How to Ensure Treasury Diversification?
Holding most assets in the native token is a common mistake of young DAOs. During a bear market, such a treasury loses purchasing power. Recommended structure:
| Asset | Allocation | Rationale |
|---|---|---|
| Stablecoins (USDC, DAI) | 40-50% | Operational expenses, runway |
| ETH | 20-30% | Liquid reserve, yield via staking |
| Native token | 20-30% | Governance, incentives |
| Diversified DeFi (wBTC) | 0-10% | Optional |
Yield on Stablecoin Part
Idle stablecoins are missed yield. Popular strategies: Aave/Compound (lending, 3-8% APY on USDC), Maker DSR, Yearn Finance. Each strategy change must go through a governance proposal.
Monitoring and Analytics
interface TreasurySnapshot {
timestamp: number;
assets: { token: string; balance: bigint; usdValue: number }[];
totalUsdValue: number;
runwayMonths: number;
}
async function getTreasurySnapshot(
provider: ethers.Provider,
treasuryAddress: string,
tokenList: string[]
): Promise<TreasurySnapshot> {
const assets = await Promise.all(
tokenList.map(async (token) => {
const contract = new ethers.Contract(token, ERC20_ABI, provider);
const balance = await contract.balanceOf(treasuryAddress);
const price = await getTokenPrice(token);
return { token, balance, usdValue: Number(ethers.formatEther(balance)) * price };
})
);
const totalUsdValue = assets.reduce((sum, a) => sum + a.usdValue, 0);
const monthlyBurn = await getMonthlyBurnRate();
return { timestamp: Date.now(), assets, totalUsdValue, runwayMonths: totalUsdValue / monthlyBurn };
}
KPI Dashboard
| Metric | Target | Alert |
|---|---|---|
| Runway | > 24 months | < 12 months |
| Stable ratio | > 40% | < 25% |
| Monthly burn | Known and agreed | +20% overshoot |
| Yield APY | > 4% on stablecoins | < 2% |
| Token concentration | < 40% | > 60% |
Why Is Timelock Critical for Security?
Proposal threshold — creating a proposal to withdraw funds requires a stake (1%+ supply). Otherwise, an attacker with a small number of tokens can push through a malicious proposal.
Timelock — mandatory delay before execution. Minimum 48 hours, for large amounts — 7 days. This gives the community time to react.
Spending caps — even via governance, no more than a certain percentage of the treasury can be withdrawn in a single proposal. Large expenditures are broken into parts.
Veto mechanism — a Security Council (4/7 multisig) has the right to veto governance decisions during the timelock. Used only for clearly malicious proposals.
contract TreasuryGuardian {
address public immutable securityCouncil;
TimelockController public immutable timelock;
function vetoOperation(bytes32 operationId) external {
require(msg.sender == securityCouncil, "Not security council");
timelock.cancel(operationId);
emit OperationVetoed(operationId);
}
}
Our Process
- Analysis — audit of current treasury structure and risks.
- Design — architecture of levels, tool selection.
- Implementation — deployment of smart contracts and Gnosis Safe configuration.
- Testing — internal audit and attack simulation using fuzzing (Echidna) to find rare bugs.
- Deploy and training — launch on mainnet and team training.
Contact us to discuss your DAO and get a preliminary architecture assessment.
What Is Included in Our Work?
- Architectural documentation and treasury level schema.
- Deployment and configuration of smart contracts (Treasury Controller, Streaming via Sablier).
- Gnosis Safe setup with multisig and timelock.
- Integration of monitoring and KPI dashboard.
- Team training on secure management.
- One month of technical support after launch.
Our team has many years of experience in blockchain development, has implemented over 20 DAO projects, and is certified in Solidity (OpenZeppelin, Consensys). We guarantee security and transparency of the architecture — all contracts undergo internal audit.
Get a free consultation on treasury architecture today. Contact us to assess your project — timelines range from 3 to 8 weeks depending on complexity.







