Traditional governance models like token-weighted snapshot voting suffer from voter apathy, low participation, and a focus on short-term outcomes. Conviction voting, pioneered by projects like Commons Stack and 1Hive, addresses this by treating governance as a continuous signal. Instead of casting a single vote, participants stake their tokens on funding proposals they support. The "conviction" for a proposal grows over time as tokens remain staked, simulating how real-world support for an idea builds momentum. This mechanism naturally filters out fleeting interests and surfaces projects with durable, long-term backing from the community.
How to Implement Conviction Voting for Long-Term Projects
Introduction to Conviction Voting
Conviction voting is a novel governance mechanism for continuous funding allocation, designed to prioritize projects based on sustained community support rather than one-time votes.
The core mathematical model calculates a proposal's conviction score using a logistic growth function. The score increases asymptotically the longer tokens are staked, but resets instantly if tokens are withdrawn. Key parameters govern the system: the alpha decay factor determines how quickly conviction builds, the maxRatio sets the maximum percentage of the common pool any proposal can request, and the weight influences the curve's steepness. In practice, a proposal only passes and receives funding once its conviction score surpasses a dynamic threshold that is proportional to the amount of funds it requests from the shared treasury.
Implementing conviction voting requires a smart contract system that manages token staking, tracks time, and calculates scores. Below is a simplified Solidity snippet illustrating the core conviction update logic, often executed on each block or in periodic epochs:
solidityfunction _updateConviction(uint256 proposalId) internal { Proposal storage p = proposals[proposalId]; uint256 timeElapsed = block.timestamp - p.lastUpdated; // Apply decay to existing conviction p.conviction = p.conviction * (alpha ** timeElapsed) / DECIMALS; // Add new conviction from staked tokens p.conviction += p.tokensStaked * timeElapsed; p.lastUpdated = block.timestamp; }
This function shows the continuous decay of old conviction and the accumulation of new support based on staked tokens and time.
For long-term projects, such as multi-year development grants or public goods funding, conviction voting is particularly effective. It mitigates proposal fatigue by allowing the community to signal support once and let that support accrue value over weeks or months. Successful implementations can be studied in 1Hive's Celeste platform and the Gardens ecosystem. When designing your system, critical decisions include choosing a token (native vs. LP shares), integrating with a Treasury Manager like the DAOhaus v2 Moloch vault, and setting sane economic parameters to prevent a single proposal from draining the pool.
To get started, you can fork and adapt existing open-source implementations. The 1Hive Gardens Agreements and Conviction Voting Aragon OSx apps provide production-ready modules. Alternatively, the Commons Stack's Conviction Voting library offers a standalone Solidity contract. When deploying, thorough testing with tools like Hardhat or Foundry is essential, especially for simulating long-term conviction growth and attack vectors like whale manipulation or proposal spamming.
The primary advantage of conviction voting is its alignment with long-term stewardship. It rewards consistent belief, reduces governance overhead, and creates a funding cadence that matches project milestones. However, it introduces complexity in parameter tuning and requires active community education. For DAOs focused on sustainable development, research, or infrastructure, it provides a robust alternative to the shortcomings of periodic voting cycles.
How to Implement Conviction Voting for Long-Term Projects
Before building a conviction voting system, you need a foundational understanding of its core components and the technical environment required for implementation.
Conviction voting is a governance mechanism designed for continuous funding allocation, where voting power accumulates over time a voter commits their tokens to a proposal. Unlike one-time snapshot voting, it measures continuous sentiment, making it ideal for funding long-term projects, grants, or recurring expenses within a DAO. The key concept is that a voter's influence on a proposal grows the longer they keep their vote staked on it, but is locked and cannot be used elsewhere. This system naturally surfaces proposals with sustained, organic community support.
To implement this, you will need a smart contract development environment. Start with Hardhat or Foundry for local development and testing. You'll write the core logic in Solidity, managing states for proposals, voter stakes, and the algorithm that calculates conviction. Essential dependencies include OpenZeppelin's contracts for secure token standards (ERC20Votes for snapshotting) and access control. A basic understanding of quadratic voting or bonding curves is helpful, as conviction voting's growth function often uses a similar mathematical foundation for calculating voting power over time.
The core algorithm requires a function that updates a proposal's total conviction score periodically. This is typically calculated off-chain in a subgraph (using The Graph Protocol) or an off-chain server to avoid prohibitive gas costs. The formula often involves summing the square root of each voter's time-weighted token balance. You'll need to design a system for users to stake, unstake, and switch their tokens between proposals, with careful consideration of attack vectors like proposal spamming or stake manipulation.
For the frontend, you will need to connect to a Web3 provider like ethers.js or viem to interact with your contracts. A good user interface must clearly show proposal details, current conviction scores, and a simple way for users to allocate their stake. Consider using a framework like Next.js or Vite with wagmi for state management. You will also need to integrate a data indexer to fetch and display the dynamically updating conviction scores for each proposal without requiring constant on-chain calls.
Finally, thorough testing is non-negotiable. Use forked mainnet environments to simulate real token distributions and write tests for critical flows: stake accumulation, conviction decay after unstaking, proposal execution thresholds, and edge cases. Security audits are crucial before deployment. For inspiration and existing implementations, study the source code of 1Hive's Gardens and Commons Stack's Conviction Voting module, which are open-source benchmarks for this mechanism.
How to Implement Conviction Voting for Long-Term Projects
A technical guide to implementing the conviction voting algorithm, a mechanism for continuous, weighted decision-making in DAOs and long-term funding initiatives.
Conviction voting is a continuous decision-making mechanism designed for allocating shared resources, such as a DAO treasury. Unlike one-time snapshot votes, it uses a time-weighted voting power system where a participant's voting "conviction" for a proposal accumulates the longer their tokens are staked on it. This algorithm, pioneered by projects like Commons Stack, is ideal for funding long-term projects because it surfaces community consensus over time, filtering out fleeting trends and ensuring only proposals with sustained support receive funding. The core formula calculates a decaying exponential function of staked tokens over time.
The fundamental algorithm can be implemented by tracking a stake amount and a lastStakedTimestamp for each supporter of a proposal. The conviction C at the current time t is calculated as: C = stake * (1 - e^(-k * (t - lastStakedTimestamp))). Here, k is a decay constant that controls how quickly conviction builds and fades; a smaller k means slower, more deliberate consensus formation. When a user unstakes, their conviction resets. The total conviction for a proposal is the sum of all individual supporter convictions. A proposal passes when its total conviction exceeds a dynamically calculated threshold, often a function of the total funds requested and the treasury size.
To implement this, you need a smart contract system with several key functions. A stake(uint proposalId, uint amount) function should update the user's stake, calculate the conviction accrued since their last action, and add it to the proposal's total. An unstake function does the reverse. A critical off-chain or oracle-based component must periodically call an executeProposal function that checks if any active proposals have reached the passing threshold. The threshold formula T = (totalRequestedFunds * alpha) / treasuryBalance helps prevent over-spending, where alpha is a governance-set parameter scaling demand.
For long-term project funding, conviction voting introduces proposal lifecycle management. Proposals typically have an active phase for accumulating conviction and an executed or expired state. You should implement an emergency cancel function for malicious proposals and a mechanism to return staked tokens if a proposal expires unfunded. When integrating with a treasury, use a streaming payment pattern upon execution instead of a lump sum, aligning incentives for continued project delivery. Smart contract audits are essential, as the continuous state updates and math operations are vulnerable to rounding errors and manipulation.
Developers can build on existing frameworks to accelerate integration. The 1Hive Gardens platform provides open-source, audited conviction voting contracts for the Aragon ecosystem. For a custom implementation, consider using a conviction voting SDK like those from Commons Stack to handle the complex exponential decay calculations off-chain, submitting only verified results on-chain. Key parameters to expose for governance are the decay rate k, the threshold coefficient alpha, and the minimum proposal duration. Testing should simulate long-term staking behavior to ensure the system robustly identifies genuine, sustained community support.
Reference Implementations and Tools
Concrete implementations, models, and developer tools for building conviction voting systems that favor long-term commitment over short-term signaling. Each reference focuses on production-grade mechanics, not theory.
Key System Parameters and Their Impact
Critical parameters for a Snapshot-based conviction voting implementation and their effect on proposal funding and governance security.
| Parameter | Low Value / Short Duration | Medium Value / Duration | High Value / Long Duration |
|---|---|---|---|
Max Ratio | 10% | 30% | 50% |
Spending Limit | Low proposal diversity, safe treasury | Balanced growth and safety | Aggressive funding, higher risk |
Decay Function | Linear (predictable, simple) | Quadratic (favors sustained support) | Logarithmic (protects against flash loans) |
Minimum Conviction | 5% of total supply | 15% of total supply | 25% of total supply |
Proposal Duration | 3 days | 7 days | 14 days |
Conviction Growth Speed | Fast (hours) | Moderate (days) | Slow (weeks) |
Stake-Vote Decay Period | 1 week | 1 month | 3 months |
How to Implement Conviction Voting for Long-Term Projects
A guide to building a conviction voting system on-chain, enabling continuous funding decisions based on sustained community support.
Conviction voting is a governance mechanism for allocating funds from a shared treasury, where a voter's influence grows the longer they maintain their vote for a proposal. Unlike simple yes/no snapshots, it measures sustained preference over time, making it ideal for funding long-term projects, grants, or recurring expenses in DAOs. The core contract architecture manages a pool of proposals, tracks each voter's staked tokens per proposal, and calculates a dynamic "conviction" score that determines which proposal is eligible for funding at any given moment.
The system's state is defined by several key data structures. A Proposal struct typically stores the recipient address, requested amount, and a history of staked support. A mapping tracks each voter's staked balance per proposal (stakedBalances[voter][proposalId]). The most critical value is the conviction score, calculated periodically (e.g., per block) using a decay formula: conviction = previous_conviction * decay_factor + new_stake. A common decay factor like 0.9 ensures older support fades if not maintained, while new stakes provide an immediate boost.
The primary function for users is stakeForProposal(uint256 proposalId, uint256 amount). This transfers amount of the governance token from the user to the contract, updating the stakedBalances mapping and triggering a recalculation of that proposal's total conviction. A corresponding withdrawStake function allows users to remove their support, which also reduces the conviction score. The contract must use a pull payment pattern for security; when a proposal's conviction exceeds a dynamic threshold (often based on the total treasury size), it is marked as fundable, but the funds are only transferred when an executor calls a executeProposal function.
Setting the correct threshold function is crucial for system stability. A simple model sets the required conviction as a percentage of the total tokens staked in the system (alpha * totalStaked). A more sophisticated model ties it to the requested amount and treasury balance, such as using the formula threshold = (requestedAmount * totalStaked) / (beta * treasuryBalance), making larger requests harder to pass. These parameters (alpha, beta, decay_factor) should be adjustable via governance and require careful tuning to balance responsiveness with treasury security.
When implementing, integrate with a token contract for staking (often an ERC-20) and a treasury contract (like a Gnosis Safe) for holding funds. Use OpenZeppelin's SafeERC20 for secure transfers. Emit clear events (Staked, Withdrawn, ProposalExecuted) for off-chain indexing by frontends. For production, consider gas optimization techniques like storing conviction scores in scaled integers to avoid decimals and updating scores in a batched manner to reduce computational overhead per transaction.
To test the system, simulate long-term behavior using a framework like Hardhat or Foundry. Write tests that: verify conviction decays correctly over multiple blocks, ensure the threshold function prevents draining the treasury, and check that only fundable proposals can be executed. Reference implementations like the 1Hive Gardens Agreement and Conviction Voting modules provide practical, audited codebases to study. Ultimately, a well-architected conviction voting contract creates a fluid, demand-driven funding mechanism aligned with long-term community sentiment.
How to Implement Conviction Voting for Long-Term Projects
This guide provides a technical walkthrough for implementing a conviction voting system, a mechanism designed to fund public goods and long-term initiatives by measuring and aggregating sustained community support over time.
Conviction voting is a quadratic funding mechanism where a voter's influence grows the longer they continuously support a proposal. Unlike one-time snapshot voting, it uses a conviction score that accumulates based on the duration and size of a token stake. This design inherently favors projects with durable, organic support, making it ideal for funding long-term development, research, or community initiatives. The core contract logic involves tracking a time-decayed sum of stakes for each proposal. Popular implementations, like those from Commons Stack and used by 1Hive, calculate conviction using a half-life formula, ensuring older support decays if not actively maintained.
To build a basic system, you'll need a smart contract with key state variables: a mapping of proposalId to a struct containing the total stakedTokens and the last updated timestamp. The conviction calculation often uses the formula: conviction = stakedTokens * (1 - e^(-k * time)), where k is a decay constant. When a user stakes tokens on a proposal, you must first trigger a conviction update for that proposal by applying the decay to the existing stake since the last update, then add the new stake. A critical function is _updateConviction(uint256 proposalId) which should be called at the start of any stake, unstake, or conviction check.
Here is a simplified Solidity snippet for the core update logic:
solidityfunction _updateConviction(uint256 proposalId) internal { Proposal storage p = proposals[proposalId]; uint256 timeElapsed = block.timestamp - p.lastUpdated; if (timeElapsed > 0) { // Apply exponential decay: newStake = oldStake * e^(-decayRate * timeElapsed) uint256 decayFactor = DECAY_BASE ** timeElapsed; // Pre-calculated constant p.stakedTokens = (p.stakedTokens * decayFactor) / DECAY_BASE_PRECISION; p.lastUpdated = block.timestamp; } }
This function ensures the staked amount decays correctly before any new operations, maintaining an accurate, time-weighted conviction score.
Integrate this with a proposal factory and a funding pool. Proposals should have a threshold—a target conviction score that triggers a payout from a shared Common Pool. Once a proposal's conviction surpasses this threshold, an executable transaction (e.g., transferring funds to a beneficiary) can be enacted. Your front-end must display real-time conviction growth, often using a subgraph from The Graph to index stake events and calculate scores off-chain for efficient queries. Voter UX is crucial: implement clear visuals for conviction growth curves and easy staking/unstaking actions via a wallet like MetaMask.
For production, audit and test extensively. Key security considerations include: ensuring decay math is safe from overflow/underflow, protecting the update function from reentrancy, and adding a timelock or multisig for executing funded proposals. Use a framework like Hardhat or Foundry for unit tests that simulate long-term staking scenarios. Reference the open-source Conviction Voting module from 1Hive on GitHub for a complete, audited implementation. This system creates a powerful flywheel for sustainable project funding, aligning community sentiment with long-term value creation.
Implementation Examples by Platform
Using Aragon's Modular Framework
Aragon OSx provides a modular governance framework where conviction voting can be implemented as a custom plugin. The system uses a proposal lifecycle managed by the DAO's core contract, with voting power derived from token staking in a vault.
Key Implementation Steps:
- Deploy an Aragon DAO with a TokenVoting plugin for basic setup.
- Develop a custom ConvictionVotingPlugin smart contract that inherits from
PluginUUPSUpgradeable. - Implement the core logic for calculating conviction (
alphadecay, threshold formula) and processing proposals. - Integrate the plugin with the DAO via
dao.installPlugin().
Example Plugin Structure:
solidity// Simplified interface for an Aragon conviction voting plugin contract ConvictionVotingPlugin is PluginUUPSUpgradeable { mapping(uint256 => Proposal) public proposals; mapping(address => mapping(uint256 => uint256)) public stakes; function createProposal(bytes calldata _metadata, uint256 _requestedAmount) external; function stakeTokens(uint256 _proposalId, uint256 _amount) external; function executeProposal(uint256 _proposalId) external; // Internal function to calculate current conviction function _calculateConviction(uint256 _proposalId) internal view returns (uint256) { ... } }
Considerations: Leveraging Aragon's upgradeability and permission management reduces custom security overhead but requires adherence to its architecture.
Common Implementation Mistakes and Security Considerations
Conviction voting is a powerful tool for decentralized governance, but its implementation is nuanced. This guide addresses frequent developer pitfalls and critical security considerations for building robust, long-term conviction voting systems.
Incorrect decay parameters are a common source of frustration. Conviction is calculated as a running sum that decays over time, typically using a formula like conviction_t = alpha * conviction_{t-1} + new_votes. The decay factor (alpha) is crucial.
- Too high (e.g., 0.99): Conviction decays very slowly, making the system sluggish and unresponsive to changing community sentiment. It can lead to "zombie proposals" that remain funded long after support wanes.
- Too low (e.g., 0.90): Conviction decays too quickly, preventing long-term projects from ever accumulating enough support to pass. It favors short-term, flash-in-the-pan ideas.
Best Practice: Start with a half-life calculation. An alpha of ~0.95 means conviction halves roughly every 14 days if no new votes are added. Test extensively with simulated proposal activity before mainnet deployment. The Commons Stack's conviction-voting app uses a default alpha of 0.95.
Frequently Asked Questions
Common technical questions and solutions for developers building long-term governance projects using conviction voting mechanisms.
Conviction is calculated by accumulating a voter's token weight over time, typically using a continuous exponential decay formula. The core logic involves integrating the voting power deposited against a proposal, where older deposits decay. A common implementation uses a formula like:
solidityfunction calculateConviction(uint256 amount, uint256 timeElapsed, uint256 decayRate) internal pure returns (uint256) { // decayRate is a constant like 0.9 (for 10% decay per unit time) return amount * (decayRate ** timeElapsed); }
Key parameters:
- Decay Rate: Often set between 0.95 and 0.99 per day, determining how quickly conviction fades.
- Time Elapsed: Measured in blocks or seconds since the vote was cast.
- Snapshotting: Systems like Aragon's Conviction Voting take periodic snapshots (e.g., daily) to efficiently update totals without on-chain computation for every block.
Conclusion and Next Steps
Conviction voting offers a powerful mechanism for funding long-term, public goods projects. This guide has covered the core concepts, smart contract architecture, and key parameters. The next step is to deploy and integrate the system into your governance framework.
To implement conviction voting, start with a clear funding pool and proposal lifecycle. Deploy the core smart contracts, such as a modified version of the Conviction Voting app from 1Hive, on your target chain. Configure the essential parameters: the maxRatio (e.g., 0.2 for 20% of the pool), decay rate (e.g., 0.999 per block), and weight for your native token. These settings directly control the speed of conviction accumulation and the maximum budget a single proposal can capture.
Integration with your existing DAO tooling is critical. The conviction voting contract must interact with your token contract for staking and a voting app (like Aragon's Voting or OpenZeppelin Governor) for proposal submission. Use a front-end library, such as the 1Hive UI components, to build an interface where members can easily stake tokens on proposals and visualize the real-time conviction growth. Ensure your subgraph indexes staking events and proposal states for efficient data queries.
For long-term projects, consider advanced configurations. Implement a proposal threshold to prevent spam and a cool-down period after a proposal is funded. Use streaming payments via tools like Superfluid or Sablier to distribute funds incrementally as conviction is maintained, aligning incentives with continuous project delivery. Regularly analyze metrics like the average conviction time to funding and adjust your decay and maxRatio parameters to optimize the flow of capital.
Testing is non-negotiable. Use a testnet and a framework like Hardhat or Foundry to simulate weeks or months of staking activity. Write scripts that emulate user behavior to ensure the conviction math works as expected and that the system is resilient to edge cases. Security audits for the smart contracts and the economic model are essential before mainnet deployment to protect the community's funds.
The final step is governance activation. Propose and pass a vote in your existing DAO to allocate an initial treasury pool to the conviction voting contract and officially adopt it as a funding mechanism. Educate your community on how to participate effectively, emphasizing that conviction voting rewards patient capital and sustained belief in a project's long-term value over short-term sentiment.