DeFi Governance Explained
Token voting, delegation, timelocks. How DeFi protocols make decisions on-chain.
Intermediate • 15 min read
🎯 What You'll Learn
- Understand governance token mechanics
- Learn about proposal and voting processes
- Identify governance attack vectors
- Design safer governance systems
Why Governance Matters
DeFi protocols need to evolve: fix bugs, add features, adjust parameters. But who decides?
Traditional: Company board decides
DeFi: Token holders vote
```bash
Governance tokens give holders the power to propose and vote on protocol changes.
---
## Governance Token Basics
| Concept | Meaning |
|---------|---------|
| **Voting Power** | Usually 1 token = 1 vote |
| **Delegation** | Assign your votes to someone else |
| **Quorum** | Minimum votes needed to pass |
| **Timelock** | Delay before execution |
| **Proposal Threshold** | Tokens needed to create proposal |
---
The governance paradox: low participation is both a feature and a risk. Most token holders don't vote, which makes governance efficient (no gridlock). But it also means a small minority can pass malicious proposals if defenders aren't watching.
Apathy is the enemy of secure governance.
---
## Governance Process
Typical flow:
<div class="flow-diagram">
<span class="flow-node">Proposal Created</span>
<span class="flow-arrow">→</span>
<span class="flow-node">Voting Period (3-7 days)</span>
<span class="flow-arrow">→</span>
<span class="flow-node">Timelock Queue (2+ days)</span>
<span class="flow-arrow">→</span>
<span class="flow-node success">Executed</span>
</div>
```solidity
// OpenZeppelin Governor example
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public returns (uint256 proposalId) {
require(getVotes(msg.sender) >= proposalThreshold(), "Below threshold");
// Create proposal...
}
function castVote(uint256 proposalId, uint8 support) public {
// 0 = Against, 1 = For, 2 = Abstain
}
```diff
---
## Common Governance Frameworks
### On-Chain: OpenZeppelin Governor
```yaml
Full on-chain voting and execution
Immutable, transparent
Used by: Uniswap, Compound
Cost: High gas for voting
```text
### Off-Chain: Snapshot
```yaml
Gasless voting (signatures only)
Execution requires multisig
Used by: Most smaller DAOs
Cost: Free to vote
```text
### Hybrid
```text
Snapshot for signaling
On-chain for final execution
Best of both worlds
```diff
---
## Governance Attacks
### 1. Flash Loan Voting
```solidity
// Attacker
1. Flash loan 1M tokens
2. Delegate to self
3. Vote on malicious proposal
4. Return tokens in same tx
// Defense: Voting power checkpointed at block N-1
// (You must hold tokens BEFORE proposal)
```text
### 2. Vote Buying
```text
Bribe contract:
"Vote YES, I pay you $100 per token"
Dark forest:
Private deals to buy votes off-chain
```text
### 3. Governance Sniping
```python
Wait for low participation period (holidays)
Submit and pass proposal with minimal votes
Defenders don't notice until too late
```bash
---
## Common Misconceptions
**Myth:** "Timelocks make governance secure."
**Reality:** Timelocks only help if someone is watching. If no one notices a malicious proposal during the 2-day delay, it still executes.
**Myth:** "Token voting is democratic."
**Reality:** 1 token = 1 vote means whales dominate. Top 10 holders often control >50% of votes. It's plutocracy, not democracy.
**Myth:** "On-chain governance is always better."
**Reality:** On-chain governance is transparent but expensive. For minor decisions, off-chain governance (with multisig execution) is more practical.
---
## Security Best Practices
### 1. Timelock + Guardian
```solidity
// Governor with emergency pause
modifier onlyGuardianOrTimelock() {
require(
msg.sender == guardian || msg.sender == timelock,
"Unauthorized"
);
_;
}
function emergencyPause() external onlyGuardian {
// Stop protocol immediately
// Governance can unpause later
}
```text
### 2. Quorum + Voter Thresholds
```solidity
// Require meaningful participation
uint256 public proposalThreshold = 100000e18; // 100K tokens to propose
uint256 public quorumNumerator = 4; // 4% of supply must vote
```text
### 3. Voting Delay
```solidity
// Delay between proposal and voting start
function votingDelay() public pure returns (uint256) {
return 1 days; // Time for community to discuss
}
```bash
---
## Comparison Table
| Feature | Governor | Compound | Snapshot |
|---------|----------|----------|----------|
| **Chain** | On-chain | On-chain | Off-chain |
| **Cost** | High | High | Free |
| **Execution** | Automatic | Automatic | Multisig |
| **Flexibility** | High | Medium | High |
---
## Practice Exercises
### Exercise 1: Analyze a DAO
```yaml
Pick a DAO (Uniswap, Aave, Compound)
Find:
1. Proposal threshold (tokens needed)
2. Voting period
3. Quorum
4. Top 5 holders' voting power %
```text
### Exercise 2: Attack Scenario
```yaml
Total supply: 1M tokens
Quorum: 4% (40K tokens)
Proposal threshold: 10K tokens
Largest holder: 50K tokens
Can largest holder pass any proposal alone?
What's the defense?
Key Takeaways
- Governance tokens = voting power - Usually 1:1
- Timelocks protect against instant attacks - But need watchers
- Low participation = vulnerability - Encourage delegation
- Plutocracy is the default - Consider alternative designs
What’s Next?
Continue learning: DeFi Risk Management
Expert content: DAO Security
Want to go deeper?
Weekly infrastructure insights for engineers who build trading systems.
Free forever. Unsubscribe anytime.
You're in. Check your inbox.
Questions about this lesson? Working on related infrastructure?
Let's discuss