Foundational models and mechanisms that structure decentralized decision-making and token holder influence.
Delegated Voting and Vote Escrow Models
Core Governance Concepts
Delegated Voting
Token delegation allows holders to transfer their voting power to a representative without transferring asset custody. This model, used by protocols like Compound and Uniswap, enables efficient governance by concentrating expertise. Delegates create voting strategies and signal intent, while users retain the right to redelegate or vote directly at any time.
Vote-Escrow (veToken) Model
The vote-escrow mechanism ties governance power to the duration of token lock-up. Pioneered by Curve Finance, it creates a veCRV token representing time-locked CRV. Longer lock-ups grant greater voting weight and often protocol fee rewards, aligning long-term holders with the platform's sustained health and incentivizing committed capital.
Governance Tokens
Governance tokens are fungible assets that confer voting rights within a protocol's decentralized autonomous organization (DAO). For example, holding UNI allows proposals on Uniswap's treasury and fee switches. Their value is derived from utility in steering protocol parameters, fee distribution, and treasury allocation, not from cash flow rights.
Proposal Lifecycle
A formal governance process typically involves temperature checks, formal proposal submission, a voting period, and timelock execution. Proposals can adjust fees (like Aave's reserve factors), add new markets, or allocate treasury funds. This structured lifecycle prevents rash changes and allows for community deliberation and security reviews before code execution.
Quorum & Voting Thresholds
Quorum requirements mandate a minimum percentage of circulating token supply to participate for a vote to be valid. Supermajority thresholds (e.g., 66% or 75%) are often required for significant parameter changes. These mechanisms protect against low-participation attacks and ensure major decisions reflect broad consensus, as seen in MakerDAO's governance.
Bribing & Vote Markets
Vote-markets emerge in veToken systems where third-party protocols offer incentives (bribes) to veToken holders to direct their voting power. For instance, a DeFi protocol may bribe veCRV holders to vote for its pool's gauge weight increase on Curve. This creates a secondary financial layer atop governance, monetizing voting influence.
Implementing a Vote-Escrow System
Process overview
Design the Core Smart Contract Architecture
Define the foundational contracts for token locking and voting power.
Detailed Instructions
Begin by architecturing the core Vote-Escrow (ve) token contract. This contract will manage the locking of a governance token (e.g., ERC20Votes) in exchange for a non-transferable veToken representing voting power. Define the primary data structures: a LockedBalance struct to store the locked amount and unlock timestamp, and a mapping from user addresses to their lock data.
- Sub-step 1: Inherit from OpenZeppelin's
ERC20VotesandERC20Permitfor the base token. Create a newveTokencontract that isERC721(non-transferable) or a custom non-transferable token standard. - Sub-step 2: Implement the
create_lock(uint256 _value, uint256 _unlock_time)function. It must transfer_valueof the base token from the user to the contract and mint a veToken NFT. - Sub-step 3: Calculate voting power. The standard formula is
voting_power = locked_amount * (unlock_time - block.timestamp) / MAX_LOCK_TIME. Store this value for each user epoch.
soliditystruct LockedBalance { uint256 amount; uint256 end; } mapping(address => LockedBalance) public locked; function _votingPowerOf(address _user) internal view returns (uint256) { LockedBalance memory lock = locked[_user]; if (lock.end <= block.timestamp) return 0; return (lock.amount * (lock.end - block.timestamp)) / MAX_LOCK_TIME; }
Tip: Use a
MAX_LOCK_TIMEconstant (e.g., 4 years in seconds) to normalize voting power, creating an incentive for longer lock durations.
Implement the Time-Based Voting Power Decay Mechanism
Code the logic for voting power that decreases linearly until unlock.
Detailed Instructions
The core economic mechanism is time-weighted voting power. Unlike a simple locked balance, power must decay linearly to zero at the unlock time, preventing permanent influence. This requires calculating power on-the-fly based on the current block timestamp.
- Sub-step 1: Modify the
balanceOforgetVotesfunction in your veToken contract to call the internal_votingPowerOffunction. This ensures any external query gets the current, decayed power. - Sub-step 2: For historical vote snapshots (e.g., for past proposals), you must checkpoint the voting power. Implement a
checkpoint()function that records a user's power at the current block number. Store checkpoints in an array for each user. - Sub-step 3: When a user increases their lock amount or extends their lock time (
increase_amount,increase_unlock_time), you must create a new checkpoint. Calculate the new slope and bias for the linear decay function and update the global state.
solidityfunction getVotes(address account) public view override returns (uint256) { // Return the linearly decaying voting power at the current block return _votingPowerOf(account); } function checkpoint() public { // Write a new checkpoint for the msg.sender at block.number _writeCheckpoint(msg.sender, _votingPowerOf(msg.sender)); }
Tip: For gas efficiency in complex DeFi integrations, consider emitting a
VotePowerChangedevent on every lock modification so indexers can track power without constant contract calls.
Integrate with a Governance Module for Delegated Voting
Connect the veToken to a governance contract that allows vote delegation.
Detailed Instructions
The veToken contract holds voting power; a separate Governor contract uses it to execute on-chain proposals. Use OpenZeppelin's Governor framework. The veToken must implement the IVotes interface, providing getVotes, getPastVotes, and delegate functions.
- Sub-step 1: Ensure your veToken contract inherits from OpenZeppelin's
Votesabstract contract or manually implements theIVotesinterface. Thedelegatefunction should allow users to delegate their decaying voting power to another address. - Sub-step 2: Deploy a
Governorcontract (e.g.,GovernorVotesQuorumFraction) that is initialized with the address of the veToken as thetokenparameter. This links governance power directly to the escrowed tokens. - Sub-step 3: Configure governance parameters in the Governor contract:
votingDelay(blocks before voting starts),votingPeriod(blocks voting is active), andquorumFraction(percentage of total veToken supply required to pass). For a ve system, aquorumFractionof 4% is a common starting point.
solidityimport "@openzeppelin/contracts/governance/Governor.sol"; import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol"; contract VeGovernor is Governor, GovernorVotes { constructor(IVotes _token) Governor("VeGovernor") GovernorVotes(_token) {} // ... set votingDelay, votingPeriod, quorumNumerator }
Tip: Use
GovernorVotesQuorumFractionto easily set a quorum based on a fraction of the total historical veToken supply, which is more secure than using the current supply.
Add Incentives and Fee Distribution for Lockers
Implement a rewards system to distribute protocol fees to veToken holders.
Detailed Instructions
A critical feature for adoption is fee distribution to veToken lockers, often in the form of protocol revenue (e.g., trading fees). This requires a FeeDistributor contract that calculates rewards proportionally to a user's time-weighted lock.
- Sub-step 1: Design a contract that accepts fee tokens (e.g., USDC, ETH) from the protocol. It should track the total
veTokensupply at each week using checkpoints, similar to the voting power logic. - Sub-step 2: For each new fee deposit, calculate the amount per
veTokenfor that time period. Accumulate unclaimed rewards for each user based on their lock amount and duration during that period. - Sub-step 3: Implement a
claim()function allowing users to withdraw their accrued rewards. To prevent gas-intensive loops, use a merkle drop mechanism or store a cumulative reward per token that users can subtract their already-claimed amount from.
solidity// Simplified reward accumulation mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; uint256 public rewardPerTokenStored; function _updateReward(address account) internal { rewardPerTokenStored = rewardPerToken(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } } function earned(address account) public view returns (uint256) { return (balanceOf(account) * (rewardPerToken() - userRewardPerTokenPaid[account])) / 1e18 + rewards[account]; }
Tip: For production, audit a proven implementation like Curve Finance's
FeeDistributor.vy(Vyper) to understand the precise time-weighted math and gas optimizations.
Deploy, Verify, and Create Initial Governance Proposal
Finalize the system deployment and bootstrap the first governance cycle.
Detailed Instructions
After development and testing, deploy the contract suite to a testnet and eventually mainnet. Use a structured deployment script to correctly initialize interdependent contracts and transfer ownership to the Governor.
- Sub-step 1: Write a deployment script (using Hardhat or Foundry) that deploys the base ERC20 token, the veToken contract, the Governor contract, and the FeeDistributor in the correct order. The veToken needs the base token address, and the Governor needs the veToken address.
- Sub-step 2: Verify all contracts on a block explorer like Etherscan. Use constructor arguments ABI encoding to ensure the verification passes and the contract interactions are transparent for users.
- Sub-step 3: Create the first governance proposal to bootstrap the system. This proposal should typically transfer control of the core protocol contracts (e.g., fee settings, admin functions) to the newly deployed Governor contract. Use the
proposefunction on the Governor, specifying the target contracts, calldata, and description.
javascript// Example Hardhat deployment snippet async function main() { const Token = await ethers.getContractFactory("ERC20Votes"); const token = await Token.deploy("Governance Token", "GT"); await token.deployed(); const VeToken = await ethers.getContractFactory("VoteEscrow"); const veToken = await VeToken.deploy(token.address, "veGT", "veGT", "1"); await veToken.deployed(); const Governor = await ethers.getContractFactory("VeGovernor"); const governor = await Governor.deploy(veToken.address); await governor.deployed(); }
Tip: Before the first proposal, ensure several trusted community members have created locks to establish an initial quorum. Consider a whitelisted proposal creation period initially to prevent spam.
Governance Model Comparison
Comparison of Delegated Voting and Vote Escrow governance models across key operational parameters.
| Feature | Delegated Voting (e.g., Compound) | Vote Escrow (e.g., Curve) | Hybrid Model (e.g., Uniswap) |
|---|---|---|---|
Voting Power Basis | Delegated token balance | Locked token amount & duration (veTokens) | Delegated balance + optional lock for multipliers |
Typical Quorum | 2-10% of circulating supply | 30-40% of locked supply | 4% of delegated supply |
Proposal Threshold | 65,000 COMP (~0.65% supply) | 2,500 veCRV (~0.025% locked supply) | 2.5M UNI (0.25% supply) or 25,000 delegated |
Vote Lockup Period | None (delegation is revocable) | 1 week to 4 years (determines weight) | None for delegation, up to 4 years for fee switch votes |
Incentive Mechanism | Governance token emissions | Protocol fee distribution to lockers | Fee switch revenue to locked token holders |
Vote Delegation | Explicit to an EOA or contract | Implicit; non-transferable veNFT | Explicit to an EOA or contract |
Gas Efficiency | High (single on-chain vote) | Low (frequent re-locking for max weight) | Medium (delegation is one-time, locks are long-term) |
Whale Influence Mitigation | Quadratic voting proposals | Time-based weighting (1 token * sqrt(lock time)) | Delegation caps & treasury grant programs |
Guidance by Role
Understanding Your Role
As a token holder, your primary action is delegating your voting power. You lock tokens in a vote-escrow contract (like Curve's veCRV or Balancer's veBAL) to receive governance power proportional to your lock duration. This power can be delegated to a trusted party without transferring custody.
Key Actions
- Locking Tokens: Commit your governance tokens (e.g., CRV, BAL) for a set period (up to 4 years) to mint veTokens. Longer locks grant more voting weight.
- Selecting a Delegate: Research and delegate your voting power to a knowledgeable community member or DAO. This delegate votes on proposals affecting protocol fees, emissions, and parameters.
- Claiming Rewards: Earn a share of protocol revenue (e.g., trading fees) and potential token emissions directed to your chosen gauge, often distributed pro-rata based on your veToken balance.
Example
A holder of 1000 CRV tokens locking them for 4 years would mint the maximum amount of veCRV. They could delegate this voting power to a delegate known for effective gauge weight voting, influencing which liquidity pools receive higher CRV emissions.
Protocol Case Studies
Analysis of major DeFi protocols implementing delegated voting and vote-escrow tokenomics, detailing their governance mechanics and real-world outcomes.
Curve Finance
Pioneered the veToken model where locked CRV tokens (veCRV) grant boosted yields and voting power on gauge weights.
- Vote-locking: Users lock CRV for up to 4 years for proportional power.
- Gauge Weight Voting: veCRV holders direct CRV emissions to liquidity pools.
- Bribing Ecosystem: Creates a secondary market where protocols incentivize veCRV holders for votes.
- This model aligns long-term holders with protocol health but can lead to centralization of emission control.
Balancer
Adopted a veBAL model where 80/20 BAL-ETH BPT tokens are locked for governance rights and fee distribution.
- Locked BPTs: Represent a share of the protocol-owned liquidity and voting power.
- Fee Redirects: veBAL holders can direct protocol fee revenue to chosen gauges.
- Gauge System: Controls BAL emissions to incentivize specific pool liquidity.
- This structure ties governance influence directly to a protocol-owned liquidity position, enhancing economic security.
Convex Finance
A vote-aggregator and yield optimizer built on top of Curve's system, demonstrating delegated voting at scale.
- Vote Delegation: Users deposit CRV or LP tokens; Convex votes with aggregated veCRV.
- cvxCRV: A liquid wrapper representing a claim on locked CRV and its rewards.
- Bribe Coordination: Centralizes bribe collection from protocols and distributes rewards to stakers.
- This case shows how delegation layers can abstract complexity but also create systemic dependencies and centralization risks.
Frax Finance
Implements a veFXS model with a multi-governance layer for its stablecoin ecosystem and Fraxswap.
- Dual Governance: veFXS holders and FRAX stablecoin holders share power over certain parameters.
- AMO Governance: Votes control the operations of Algorithmic Market Operations controllers.
- Fraxswap Gauges: veFXS directs emissions to Fraxswap liquidity pools.
- This model integrates stablecoin users into governance, aiming for broader stakeholder alignment beyond just token lockers.
Ribbon Finance
Utilizes a veRBN model to govern its decentralized options vault protocol and treasury management.
- Treasury Direction: veRBN holders vote on treasury asset allocation and yield strategies.
- Fee Sharing: A portion of protocol fees is distributed to veRBN lockers.
- Gauge Weights for Pools: Influences RBN rewards for liquidity providers on selected DEXs.
- This case study highlights applying vote-escrow to govern a protocol's capital allocation and revenue distribution directly.
Angle Protocol
Employs a veANGLE model with a focus on governing its decentralized stablecoin, agEUR, and surplus distribution.
- Surplus Allocation: Votes determine the distribution of protocol surplus between buybacks, burns, and grants.
- Core Parameter Control: Governance sets fees, collateral ratios, and oracle choices for minting.
- Merkl Rewards: veANGLE holders direct ANGLE incentives to liquidity providers via Merkl distributions.
- This illustrates a vote-escrow system managing a complex stablecoin mechanism and a community-owned treasury.
How to Delegate or Escrow Voting Power
Process overview
Connect Wallet and Review Protocol Interface
Access the governance platform and verify your voting power.
Detailed Instructions
First, connect your Web3 wallet (e.g., MetaMask) to the protocol's governance interface, such as Tally or the protocol's native dApp. Navigate to the governance section, often labeled "Vote" or "Delegate." Your voting power is typically derived from your token balance. Check the interface to confirm your available voting weight, which may be displayed as a raw token amount or a normalized voting power value. This step is crucial for understanding your influence before delegation.
- Sub-step 1: Connect your wallet and ensure you are on the correct network (e.g., Ethereum Mainnet).
- Sub-step 2: Locate and review your current token balance and associated voting power.
- Sub-step 3: Verify the contract addresses for the governance token and staking contracts from official sources.
Tip: Bookmark the official governance portal URL to avoid phishing sites that could compromise your tokens.
Choose Between Delegation and Vote Escrow
Understand the key differences and select the appropriate model.
Detailed Instructions
Decide whether to use a simple delegation model or a vote-escrow (veToken) model. In delegation, you assign your voting rights to another address (a delegate) without locking tokens; they can vote on proposals on your behalf. In veToken models, you must lock your tokens for a specified duration (e.g., 1-4 years) to receive non-transferable veTokens, which grant boosted voting power. The lock-up period is a time-weight multiplier; longer locks yield more power per token. Assess your goals: delegation offers flexibility, while escrow provides greater influence and often protocol fee rewards.
- Sub-step 1: Review the protocol's documentation to confirm which model(s) it supports.
- Sub-step 2: For veTokens, calculate potential voting power based on your intended lock duration.
- Sub-step 3: Identify trusted delegates by reviewing their voting history and statements if choosing delegation.
Tip: In veToken systems, your voting power decays over time as the lock expiration approaches, influencing long-term strategy.
Execute the Delegation or Lock Transaction
Perform the on-chain transaction to assign voting power.
Detailed Instructions
For delegation, call the delegate(address delegatee) function on the governance token contract, specifying the recipient's address. This is often a simple write transaction from your wallet. For vote escrow, the process involves a deposit and lock. You will call a function like create_lock(uint256 _value, uint256 _unlock_time) on the escrow contract (e.g., Curve's VotingEscrow). The _value is the token amount to lock, and _unlock_time is a future UNIX timestamp. This transaction mints veTokens to your address. Always verify gas estimates and ensure you have sufficient ETH for the transaction fee.
- Sub-step 1: For delegation, input the delegatee's ENS name or checksummed address.
- Sub-step 2: For escrow, use a tool to calculate the exact UNIX timestamp for your desired lock period.
- Sub-step 3: Review the transaction details in your wallet before signing, checking the contract interaction.
solidity// Example delegation call for an ERC20Votes-compatible token IERC20Votes(tokenAddress).delegate(delegateeAddress);
Tip: Test with a small amount first if the interface allows, especially for locking transactions which are irreversible until maturity.
Verify the On-Chain State
Confirm the transaction succeeded and your voting power is correctly allocated.
Detailed Instructions
After the transaction is confirmed, verify the new state on-chain. Use a block explorer like Etherscan to check the transaction logs. For delegation, look for a DelegateChanged event. Your token balance remains in your wallet, but voting power is assigned. For vote escrow, look for a Deposit or Supply event; your base tokens are now locked. Then, return to the governance interface or query the contract directly to confirm your updated voting weight. For veTokens, call the balanceOf(address addr) function on the escrow contract. For delegated power, call getVotes(address account) on the governance token contract at the current block.
- Sub-step 1: Paste your transaction hash into a block explorer and confirm its success status.
- Sub-step 2: On the governance UI, refresh the page and check if your voting power display has updated.
- Sub-step 3: Use a read function in a tool like Etherscan's "Read Contract" tab to query your voting power directly.
Tip: Voting power snapshots are often taken at a specific block per proposal; your power is based on your balance/delegation at that historical block, not necessarily the current state.
Manage and Update Your Delegation or Lock
Learn how to re-delegate, extend locks, or exit positions.
Detailed Instructions
Your initial choice is not permanent. For delegation, you can re-delegate to a different address at any time by submitting a new delegate transaction; the change is effective from the next block. For vote-escrow positions, management is more complex. You cannot withdraw tokens before the unlock time, but you may often increase the lock amount or extend the lock duration. Some protocols allow merging locks. To extend, call a function like increase_unlock_time(uint256 _unlock_time). To add more tokens, use increase_amount(uint256 _value). Always review the contract's specific functions, as early exit is typically impossible without community approval via governance.
- Sub-step 1: To change a delegate, simply execute a new delegation to the new address.
- Sub-step 2: To extend a veToken lock, calculate the new unlock timestamp and submit the transaction.
- Sub-step 3: Monitor your lock expiration and plan ahead for potential re-locking to maintain voting influence.
solidity// Example calls for a veToken contract (like Curve) // Increase lock amount VotingEscrow(escrowAddress).increase_amount(additionalTokenAmount); // Extend lock time VotingEscrow(escrowAddress).increase_unlock_time(newUnlockTimestamp);
Tip: In ve systems, the maximum voting power boost is achieved at the maximum lock duration (e.g., 4 years). Extending an existing lock resets the time-weight calculation.
Governance Model FAQs
Delegated voting is a representative model where token holders delegate their voting power to a trusted third party, who votes on their behalf. Vote escrow is a commitment model where users lock their tokens for a set period to receive non-transferable voting power, often scaled by lock duration.
- Delegation separates economic interest from governance participation.
- Vote escrow directly ties governance influence to demonstrated long-term commitment.
- In practice, a DAO like Curve uses a veToken model (veCRV), while Uniswap uses delegation.
For example, locking 1000 CRV for 4 years grants significantly more voting power than delegating the same amount.