Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

How to Architect a Delegated Voting System

This guide details the smart contract architecture and incentive design for a secure on-chain delegated voting system, from delegation registries to slashing mechanisms.
Chainscore © 2026
introduction
DEVELOPER GUIDE

How to Architect a Delegated Voting System

A technical guide to designing and implementing a secure and efficient delegated voting (liquid democracy) system on-chain.

A delegated voting system, often called liquid democracy, allows token holders to vote directly on proposals or delegate their voting power to a trusted representative. This architecture combines direct democracy's granularity with representative democracy's efficiency. Core components include a voter registry to track token balances, a delegation graph to map voter-to-delegate relationships, and a vote aggregation engine that calculates the final weight of each vote, factoring in nested delegations. Smart contracts on platforms like Ethereum, Solana, or Cosmos are typically used to enforce these rules transparently and immutably.

The delegation mechanism is the system's backbone. When a user delegates, they do not transfer tokens; they assign their voting power to another address. This creates a directed graph where edges represent trust. A critical design decision is whether to allow transitive delegation (where a delegate can further delegate, creating chains) or restrict it to one level. Systems like Snapshot with delegation or DAO frameworks like OpenZeppelin Governor support delegation, requiring careful state management to prevent circular references and gas inefficiencies when tallying votes across deep delegation chains.

Implementing vote tallying requires traversing the delegation graph. A naive recursive on-chain calculation can be prohibitively expensive. Optimizations include using an off-chain indexer (like The Graph) to pre-compute voting power snapshots at a specific block height before a proposal goes live. The contract then stores a merkle root of these weights. Alternatively, you can implement an EIP-712-based signing scheme where delegates submit votes with aggregated weights, verified against a stored snapshot. The key is to separate the state-heavy graph resolution from the voting transaction to control gas costs.

Security considerations are paramount. Architects must guard against vote manipulation through delegation flooding or the nothing-at-stake problem where delegates have no skin in the game. Implementing a cool-down period for changing delegations after a proposal is submitted prevents last-minute power grabs. Furthermore, consider sybil-resistance; a pure token-weighted system can be gamed by splitting holdings. Pairing with a proof-of-personhood system or implementing a minimum stake duration can mitigate this. Audits for reentrancy and logic errors in the vote counting function are essential.

For practical implementation, start with a vote token (ERC-20, SPL) and a main DelegationVoting contract. Key functions include delegate(address to), undelegate(), castVote(uint proposalId, uint support). Store delegations in a mapping (address delegatee => address delegate). For tallying, a common pattern is to use a checkpointed voting power system (like Compound's Comp token), which creates a history of balances per block, allowing past voting power to be reconstructed reliably and efficiently for any proposal.

prerequisites
PREREQUISITES

How to Architect a Delegated Voting System

Before building a delegated voting system, you need a solid foundation in smart contract development and a clear understanding of the governance models you intend to implement.

A delegated voting system, also known as a liquid democracy, allows token holders to vote directly on proposals or delegate their voting power to trusted representatives. This architecture is fundamental to protocols like Compound and Uniswap. Core prerequisites include proficiency in a smart contract language like Solidity or Vyper, experience with development frameworks such as Hardhat or Foundry, and familiarity with the ERC-20 and ERC-721 token standards, which often represent governance rights. You should also understand basic cryptographic primitives like digital signatures for vote delegation.

You must design the core data structures that underpin the system. This typically involves a Voter struct to track delegation status and voting weight, a Proposal struct to store the proposal's state, lifecycle, and vote tally, and a mapping to link delegates to their delegators. Key decisions include whether voting power is snapshotted at proposal creation (like OpenZeppelin's ERC20Votes) or calculated live, and how to handle the delegation chain to prevent circular references and gas inefficiencies. Understanding time-locks and quorum requirements is also essential for proposal execution.

Security is paramount. Common vulnerabilities include vote manipulation through flash loan attacks, where an attacker borrows tokens to gain temporary voting power. Mitigations involve using a time-weighted or block-snapshot voting power model. You must also guard against reentrancy in vote casting and ensure proper access control for critical functions like proposal creation. Thorough testing with tools like slither for static analysis and writing comprehensive unit/integration tests that simulate delegation scenarios are non-negotiable steps before deployment to a testnet.

core-architecture
CORE SYSTEM ARCHITECTURE

How to Architect a Delegated Voting System

A technical guide to designing the core components of a secure and efficient on-chain delegated voting system, covering smart contract architecture, delegation mechanics, and key security considerations.

A delegated voting system, or liquid democracy, allows token holders to vote directly on proposals or delegate their voting power to representatives. The core architecture requires several key smart contracts: a voting token (often an ERC-20 or ERC-1155), a delegation registry to track delegate assignments, and a governance module to manage proposals and tally votes. The delegation registry is the system's heart, mapping each voter's address to their chosen delegate's address and managing the flow of voting power. This separation of concerns—token, registry, and governance—creates a modular and upgradeable design pattern used by protocols like Compound and Uniswap.

The delegation mechanism must efficiently handle vote weighting. A naive approach sums balances at vote time, which is gas-intensive. A more efficient design uses snapshotting: the system records each voter's token balance and delegate choice at a specific block number when a proposal is created. This snapshot becomes the immutable source of truth for vote power, preventing manipulation via token transfers during the voting period. The contract must also manage delegation chains, where A delegates to B, who delegates to C; the system must correctly resolve the final delegate (C) and prevent circular references that could lock voting power.

Security is paramount. Contracts must guard against double voting, where a user votes both personally and through a delegate. Implementing a check that nullifies a delegate's voting power if the delegator votes directly is essential. Another critical consideration is vote delegation griefing, where a malicious delegate could vote contrary to their delegators' interests. While on-chain systems cannot prevent this, incorporating a timelock on delegation changes prevents last-minute delegate swaps to manipulate outcomes. Using OpenZeppelin's governance contracts as a foundation can mitigate common vulnerabilities.

For implementation, here's a simplified interface for a delegation registry core function:

solidity
function delegate(address delegatee) external {
    require(delegatee != msg.sender, "Cannot delegate to self");
    _delegates[msg.sender] = delegatee;
    emit DelegateChanged(msg.sender, delegatee);
}

function getVotes(address account, uint256 blockNumber) public view returns (uint256) {
    address delegatee = _delegates[account];
    if (delegatee == address(0)) {
        delegatee = account;
    }
    return _getPriorBalance(delegatee, blockNumber);
}

This shows the basic logic for setting a delegate and fetching vote power from a historical snapshot.

Advanced architectures integrate gasless voting via meta-transactions or EIP-712 signed messages to reduce voter participation costs. Furthermore, systems can implement quadratic voting or conviction voting models within the delegation framework to weight votes differently. When architecting the system, you must also plan for upgrade paths using a proxy pattern (like UUPS or Transparent Proxy) and consider front-running protections for delegation transactions. The final design should be audited, with particular focus on the snapshot mechanism and delegation state transitions to ensure mathematical correctness and security under all conditions.

key-concepts
DELEGATED VOTING

Key Concepts

Delegated voting systems separate voting power from direct participation, enabling scalable and efficient on-chain governance. These are the core architectural components.

01

Voting Power Tokenization

Governance rights are represented by a fungible token (e.g., ERC-20) or non-fungible token (ERC-721). This token is the source of voting power. Key considerations include:

  • Snapshot vs. on-chain voting: Snapshot uses off-chain signatures for gasless proposals, while on-chain voting executes transactions directly.
  • Delegation mechanics: Users can delegate their voting power to another address, which can be revocable or permanent.
  • Example: Compound's COMP token uses a checkpointed ERC-20 where delegated balances are recorded at each block.
02

Delegation Registry & Logic

A smart contract maintains the mapping between token holders and their chosen delegates. This system must handle:

  • State management: Tracking current and historical delegations, often using a struct like mapping(address => address) public delegates.
  • Gas optimization: Using patterns like checkpointing to make historical lookups efficient without storing every change.
  • Delegation strategies: Support for self-delegation, delegation to specific addresses, or delegation to contract-based strategies (like a "liquid delegation" pool).
03

Proposal Lifecycle & Quorums

A formal process for creating, voting on, and executing governance actions. The lifecycle typically includes:

  • Proposal creation: Submitting executable calldata with a minimum proposal threshold (e.g., 10,000 tokens).
  • Voting period: A fixed window (e.g., 7 days) where delegated votes are cast.
  • Quorum and thresholds: A successful proposal must meet a quorum (minimum participation, like 4% of supply) and a vote differential (e.g., more For than Against votes).
  • Timelock execution: Approved proposals often pass through a timelock contract (like OpenZeppelin's) for a security delay before execution.
04

Vote Aggregation & Tallying

The mechanism that calculates the final result from all delegated votes. This involves:

  • Weight calculation: Determining each voter's power based on their token balance at a specific block (the proposal snapshot block).
  • Vote options: Typically For, Against, and Abstain. Some systems use quadratic voting or ranked-choice voting for more nuanced outcomes.
  • Gas-efficient tallying: Using a pull-over-push model where votes are counted on-demand rather than in a single transaction to avoid gas limits.
  • Example: Uniswap's Governor Bravo contract stores votes in a struct and tallies them when the proposal is queued.
05

Security Considerations & Attacks

Delegated systems introduce unique attack vectors that must be mitigated in the architecture:

  • Vote buying & bribery: On-chain votes are public, enabling coercion. Solutions include commit-reveal schemes or privacy layers.
  • Flash loan attacks: An attacker borrows tokens to meet a proposal threshold, then votes and repays the loan. Mitigated by using vote snapshots from a past block.
  • Delegate centralization: Risk of power concentrating in a few "whale" delegates. Can be countered with vote delegation caps.
  • Governance fatigue: Low participation can lead to apathy. Systems like optimistic governance or meta-governance can help.
contract-implementation
SMART CONTRACT IMPLEMENTATION

How to Architect a Delegated Voting System

A technical guide to building a secure and gas-efficient delegated voting system using Solidity, covering core contracts, delegation mechanics, and vote tallying.

A delegated voting system, or liquid democracy, allows token holders to vote directly on proposals or delegate their voting power to a trusted representative. This architecture is fundamental to many DAO governance models, such as those used by Compound and Uniswap. The core smart contract components required are: a Voting Token (often an ERC-20 or ERC-20 snapshot), a Delegation Registry to track delegate relationships, and a Governor contract to manage proposals and tally votes. This separation of concerns improves security and upgradability.

The delegation mechanism is the system's backbone. A standard approach is to extend the ERC-20Votes or ERC-5805 (EIP-6372) standard, which introduces a delegate(address delegatee) function and maintains a history of checkpoints for each account's voting power. When a user delegates, their voting power is not transferred; instead, the delegate's voting power is calculated as the sum of all undelegated balances plus the balances of all accounts that have delegated to them. This is efficiently tracked using checkpoint arrays that record historical balances at each block number, enabling gas-efficient lookups for past votes.

Proposal and voting logic is handled by a Governor contract, like OpenZeppelin's Governor implementation. When a proposal is created, it snapshots the current block number. To cast a vote, the contract calls getVotes(account, snapshotBlock), which queries the delegation contract for the account's voting power at that historical block. Votes can be cast directly by token holders or by their delegates. A critical security consideration is preventing double voting: a delegate cannot also vote with their own tokens if they have been delegated to, as the system tallies power by source, not by the voting address.

Optimizing for gas efficiency is crucial. Key strategies include using checkpoint compression (only writing a new checkpoint when balance/delegation changes), implementing batch delegation functions, and allowing signature-based voting via EIP-712 to save users gas. Furthermore, the system must handle edge cases like delegation loops (which should be rejected) and ensure that delegated voting power cannot be used after tokens are transferred (enforced by the snapshot mechanism).

To deploy a complete system, you would typically use battle-tested libraries. A standard stack includes an ERC-20Votes token, the Governor contract with a TimelockController for proposal execution delay, and optionally a GovernorCountingSimple module for vote counting. All contracts should undergo rigorous testing, including simulations of complex delegation chains and attack vectors like flash loan voting manipulation, which can be mitigated by using a timestamp or block-number based snapshot with a sufficient delay.

ARCHITECTURE PATTERNS

Delegation Model Comparison

A comparison of three core delegation models for on-chain governance, detailing their technical trade-offs.

FeatureDirect DelegationDelegation PoolLiquid Delegation

Voting Power Transfer

Direct, one-to-one

Pooled, one-to-many

Tokenized, transferable

Delegator Control

Full revocation rights

Vote with pool or exit

Sell or transfer delegation token

Gas Cost for Delegator

~80k gas (one-time)

~50k gas (join pool)

~120k gas (initial mint)

Voter Turnout Impact

Low (passive delegation)

High (pool professionalizes voting)

Variable (market-driven)

Sybil Resistance

Weak

Strong (pool minimums)

Strong (token cost barrier)

Protocol Examples

Compound, Uniswap

Lido on L2s, Gitcoin

Element DAO, mStable

Implementation Complexity

Low

Medium

High

incentives-slashing
ARCHITECTURE GUIDE

Designing Delegate Incentives and Slashing

A technical guide to designing the economic mechanisms that secure delegated governance systems, focusing on incentive alignment and slashing conditions.

Delegated voting systems, like those used by Compound and Uniswap, rely on token holders assigning their voting power to active participants. The core architectural challenge is aligning the incentives of these delegates with the long-term health of the protocol. A well-designed system must reward competent, engaged participation while penalizing malicious or negligent behavior. This requires a deliberate combination of positive incentives (rewards) and negative incentives (slashing) encoded directly into the protocol's smart contracts.

Positive incentives typically involve distributing a portion of protocol fees or newly minted tokens to active delegates. The key is to structure rewards to promote desirable actions. For example, a system might pay delegates for:

  • Voting on proposals within a specific timeframe.
  • Delegating voting power to other qualified participants (creating a delegation tree).
  • Maintaining a high participation rate over multiple voting epochs. Rewards should be transparent, predictable, and sufficient to cover the operational costs of being an informed delegate.

Slashing is the mechanism for enforcing accountability. It involves the protocol permanently destroying or locking a portion of a delegate's staked tokens (or the tokens of those who delegated to them) for violating predefined rules. Common slashing conditions include:

  • Double voting or voting contradictorily on the same proposal.
  • Malicious voting that is proven to harm the protocol (e.g., approving a malicious upgrade).
  • Extended inactivity, failing to vote on a critical mass of proposals. The slashing severity must be carefully calibrated—too harsh, and it deters participation; too lenient, and it's ineffective.

Implementing these mechanics requires precise smart contract logic. Below is a simplified Solidity example outlining a slashing function for inactivity. It assumes delegates have a staked bond and tracks their votes in an epoch.

solidity
// Simplified slashing for inactivity
function slashInactiveDelegate(address delegate, uint256 epochThreshold) external {
    require(msg.sender == slashingManager, "Unauthorized");
    
    uint256 lastActiveEpoch = delegateLastVoteEpoch[delegate];
    uint256 currentEpoch = getCurrentEpoch();
    
    // Slash if delegate hasn't voted in the last `epochThreshold` epochs
    if (currentEpoch - lastActiveEpoch > epochThreshold) {
        uint256 slashAmount = delegateBond[delegate] * SLASH_PERCENTAGE / 100;
        delegateBond[delegate] -= slashAmount;
        totalBurned += slashAmount;
        
        emit DelegateSlashed(delegate, slashAmount, "Inactivity");
    }
}

This function checks if a delegate's last vote was beyond a tolerated number of epochs and applies a percentage slash to their bond. The SLASH_PERCENTAGE is a critical governance parameter.

The final design step is parameter tuning. Governance must decide values like reward rates, slashing percentages, and inactivity thresholds. These are often set initially by the core team and later controlled by governance votes. Effective systems use graduated slashing (higher penalties for more severe offenses) and forfeited rewards as a lighter penalty before full slashing. Continuous analysis of delegate behavior and protocol health is essential for iterating on these parameters to maintain a secure and active governance layer.

integration-patterns
INTEGRATION WITH VOTING AND SNAPSHOT

How to Architect a Delegated Voting System

A technical guide to designing and implementing a secure, gas-efficient delegated governance system for DAOs and on-chain protocols.

A delegated voting system allows token holders to delegate their voting power to representatives, enabling efficient governance for large, distributed communities. The core architecture involves three key components: a voting token (e.g., an ERC-20 or ERC-721), a delegation registry to track who votes for whom, and a voting contract that calculates voting power based on these delegations. This separation of concerns is critical for flexibility and security, allowing the voting logic to be upgraded independently of the token or delegation tracking. Popular frameworks like OpenZeppelin Governor provide a modular foundation for building these systems.

The delegation mechanism can be implemented using a simple mapping in a smart contract: mapping(address => address) public delegates. When a user calls delegate(address to), their voting power is transferred to the delegatee. To calculate the voting power of a delegate, the system must sum the balances of all accounts that have delegated to them, plus the delegatee's own balance. This is often done via a getVotes(address account, uint256 blockNumber) function that uses snapshots to prevent double-spending of votes. Gas optimization is a major concern, as naive implementations that loop over all delegators can become prohibitively expensive.

Integrating with Snapshot, an off-chain gasless voting platform, requires a specific architectural pattern. Your on-chain contracts must expose a type function that returns "snapshot" and a getVotesAtBlock function that Snapshot can call via a provider to fetch historical voting power. This allows Snapshot to create proposals where votes are weighted by the delegate's total voting power at a specific block height, all without requiring users to pay gas. The on-chain system remains the single source of truth for delegation state, while Snapshot handles the proposal creation and signature-based voting interface.

Security considerations are paramount. Key risks include vote manipulation through delegation changes during a voting period and flash loan attacks where an attacker borrows tokens to gain temporary voting power. Mitigations include using a vote snapshot block (a fixed block number before the proposal starts for determining voting power) and implementing delegation cooldowns or lock-up periods. Always audit the interaction between the token, the delegation contract, and the voting module, as complex delegation logic can introduce unexpected edge cases and reentrancy vulnerabilities.

For development, start with a tested base like OpenZeppelin's Governor contract with a GovernorVotes module, which integrates with an ERC-20Votes token. The ERC20Votes extension automatically handles delegation and vote snapshots. A basic deployment flow involves: 1) Deploying the ERC20Votes token, 2) Deploying a Governor contract that points to the token, and 3) Configuring proposal parameters (voting delay, period, quorum). You can then extend this system by writing custom quorum logic or integrating with off-chain data via Chainlink Oracles for more complex governance conditions.

In practice, successful delegated governance requires clear documentation and user-friendly tooling. Front-end applications should allow users to easily delegate, propose, and vote. Consider using subgraphs from The Graph to index delegation events and voting history for efficient UI queries. Remember, the goal is to create a system that is not only secure and decentralized but also accessible, encouraging broad participation from your protocol's community.

DEVELOPER FAQ

Frequently Asked Questions

Common technical questions and solutions for architects building delegated voting systems on-chain.

The primary distinction lies in the delegation power metric. In a token-weighted system, voting power is directly proportional to the quantity of a fungible token (like a governance token) a user holds or delegates. This is common in DAOs like Uniswap or Compound.

In a reputation-based system, voting power is derived from a non-transferable score, often called "Rep" or "voting power," which is earned through contributions or staking and cannot be bought. This model, used by protocols like Colony, aims to align influence with proven participation rather than capital. The choice impacts sybil resistance, plutocracy risks, and long-term governance alignment.

conclusion
ARCHITECTURE REVIEW

Conclusion and Next Steps

This guide has outlined the core components for building a secure and efficient delegated voting system on-chain. The next steps involve refining the implementation and exploring advanced governance models.

You have now implemented the foundational architecture for a delegated voting system. The core components include a VotingToken for stake-weighted power, a VotingRegistry to manage delegation, and a ProposalManager to execute on-chain votes. This modular design separates concerns, making the system easier to audit and upgrade. Key security considerations like preventing double-voting and ensuring delegation updates are atomic have been addressed. The next phase is to rigorously test this system on a testnet, simulating various attack vectors and voter participation scenarios.

To enhance this basic architecture, consider integrating with existing governance frameworks. Forge a Governor contract compatible with OpenZeppelin's Governor standard to leverage a battle-tested proposal lifecycle and timelock controller. This provides built-in security patterns for proposal queuing and execution delays. Alternatively, explore integrating with snapshot delegation for gas-free voting signaling, using your on-chain registry as the source of truth for voting power. Tools like Tally and Boardroom can provide a frontend interface for delegate discovery and voter analytics.

Advanced features can significantly improve system resilience and participation. Implement a rage-quit mechanism, allowing token holders to withdraw their stake if a malicious proposal passes, as seen in Moloch DAOs. Consider conviction voting, where voting power increases the longer a voter supports a proposal, to filter for long-term alignment. For high-value decisions, a multisig council can be added as a fallback execution layer. Always subject upgrades to the governance process itself, ensuring the system remains decentralized and community-controlled.

Your development roadmap should prioritize security audits. Engage professional firms like ChainSecurity or Trail of Bits to review the complete system, especially the delegation math and proposal execution logic. Use formal verification tools for critical state transitions. Establish a bug bounty program on platforms like Immunefi to incentivize white-hat hackers. Document the system thoroughly for delegates and voters, explaining gas costs, voting periods, and dispute resolution processes. Clear documentation is as critical as secure code for adoption.

Finally, analyze real-world data from live governance systems. Study delegate behavior in Compound or Uniswap to understand voter apathy and concentration. Monitor gas costs for voting operations to optimize for accessibility. The goal is to create a system that is not only technically robust but also economically sustainable and politically engaging. Start with a limited scope, govern a treasury or parameter set, and expand functionality through community proposals. The architecture you build today will define the community's ability to evolve tomorrow.

How to Architect a Delegated Voting System | ChainScore Guides