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

Launching a Snapshot-Based Off-Chain Voting System

A technical guide for developers and DAO organizers on configuring a Snapshot space, implementing custom voting strategies, and integrating with communication platforms for off-chain governance.
Chainscore © 2026
introduction
TUTORIAL

Launching a Snapshot-Based Off-Chain Voting System

A step-by-step guide to creating a gas-free, community-driven governance system using Snapshot.

Snapshot is the leading platform for off-chain, gasless governance, used by protocols like Uniswap, Aave, and Curve. It allows token holders to signal their preferences on proposals without paying transaction fees, making participation accessible. Votes are signed messages stored on IPFS and validated against a specific block number (a "snapshot") to determine voter eligibility. This creates a flexible, cost-effective layer for community sentiment and decision-making before any on-chain execution is required.

The core of a Snapshot space is its voting strategy. This is a smart contract or custom logic that defines who can vote and how voting power is calculated. Common strategies include: erc20-balance-of (simple token balance), erc20-with-balance (requires a minimum balance), and erc721 (NFT ownership). You can also create custom strategies using the Snapshot strategy template to implement complex logic like time-weighted averages or multi-token governance.

To launch your space, first connect your wallet to snapshot.org. You'll need an ENS domain (e.g., myprotocol.eth) to act as your space's unique identifier. In the settings, configure key parameters: admins (wallet addresses that can edit settings), moderators (can delete proposals), voting delay (time before voting starts), and voting period (typically 3-5 days). Set your chosen voting strategy and its parameters, such as the contract address for the governance token.

Creating a proposal requires a title, body (using Markdown or IPFS hash), choices (e.g., "For," "Against," "Abstain"), and the snapshot block number. The snapshot block is critical; it freezes token balances at a past block height, preventing manipulation by buying tokens after a proposal is posted. Always set this to a block mined shortly before you create the proposal. Discuss drafts with your community on forums like Discord or the Snapshot #proposal channel before the final submission.

While Snapshot votes are not directly enforceable on-chain, they are a powerful coordination tool. Many protocols use a two-step process: 1) an off-chain Snapshot vote to gauge sentiment and achieve consensus, followed by 2) an on-chain vote via a Timelock Controller or Governor contract to execute the decision. This separation allows for safe, deliberate governance. Always verify proposal details and voter eligibility strategies before participating, as they define the rules of your digital democracy.

prerequisites
GOVERNANCE

Prerequisites for Setting Up a Snapshot Space

Before launching a community voting system, you must configure the foundational elements of your Snapshot space. This guide covers the essential technical and strategic requirements.

A Snapshot space is the central hub for your community's off-chain governance. It requires a unique identifier, a connected Ethereum Name Service (ENS) domain, and a designated admin wallet. The ENS domain (e.g., my-dao.eth) serves as your space's permanent, human-readable URL on Snapshot. The admin wallet, typically a multi-signature wallet for security, holds the ownership rights to this ENS domain and has exclusive control over the space's settings, proposals, and moderators.

You must define your voting strategy by selecting or creating a strategy plugin. Snapshot provides default strategies like erc20-balance-of (one token, one vote) and erc20-with-balance (requires a minimum token balance). For custom logic—such as quadratic voting, NFT-based voting, or multi-token governance—you will need to develop a custom strategy. This involves writing a JavaScript function that fetches and calculates voting power from on-chain data, which is then verified by Snapshot's infrastructure.

Configure the space's voting settings to match your governance model. Key parameters include the proposal threshold (minimum voting power to create a proposal), quorum (minimum participation for a vote to be valid), and voting period (duration proposals are active, typically 3-5 days). You must also decide on the voting system, such as single-choice voting, approval voting, or ranked-choice voting. These settings are crucial for ensuring legitimate and efficient decision-making.

For security and transparency, set up a moderator role and define validation rules. Moderators can edit proposals and manage the space in the admin's absence. Validation rules, written in JavaScript, act as a pre-check for proposals, rejecting submissions that don't meet criteria like proper formatting or required metadata. Finally, integrate your space with your community's front-end and communication tools (like a Discord bot or a forum plugin) to notify members and streamline the proposal lifecycle.

step-1-space-creation
FOUNDATION

Step 1: Create and Configure Your Snapshot Space

The first step in launching an off-chain governance system is to create your dedicated Snapshot space, which serves as the central hub for all proposals and votes.

A Snapshot space is a dedicated page for your DAO or project's off-chain governance. It is not a smart contract but a configurable front-end that uses signed messages to record votes. To begin, navigate to snapshot.org and connect your wallet. You must connect with an address that holds a significant amount of your project's governance token, as this will be used to prove ownership when creating the space. The connected wallet becomes the initial Admin with full control over the space's settings.

After connecting, click "Create a space". You will be prompted to enter key identifiers: the Space ID and Space Name. The Space ID becomes part of your space's URL (e.g., snapshot.org/#/your-space-id.eth) and is immutable. For maximum trust and decentralization, register an ENS domain (e.g., daoname.eth) and use it as your Space ID. The Space Name is the display name shown on the interface. Choose these carefully, as they represent your project's governance brand.

The core configuration happens in the Settings tab. Here, you define the voting strategies and validation rules. Under Strategies, you specify how voting power is calculated. A common setup is the erc20-balance-of strategy, which assigns one vote per governance token held at a specific block number. You can add multiple strategies and assign weights to them. For example, you could combine an ERC-20 balance strategy with an erc721 strategy for NFT holders, creating a hybrid governance model.

Next, configure the Validation settings. This defines which members can create proposals. The default and most common setting is basic, which requires the proposal creator to hold a minimum threshold of voting power (e.g., 1,000 tokens). You can also implement more complex validation using the nft or contract-call strategies to gate proposal creation to specific NFT holders or a custom smart contract. This prevents spam and ensures only engaged community members can initiate votes.

Finally, customize the Information and Appearance sections. Add a clear description of your space's purpose, links to your website and social media, and a logo. Under Networks, select the blockchain networks where your voting strategies are active (e.g., Ethereum Mainnet, Arbitrum, Polygon). Once all settings are reviewed, you must sign a message with your admin wallet to publish the space. Your Snapshot space is now live and ready for the next step: setting up voting strategies and proposal types.

step-2-voting-strategies
CORE CONFIGURATION

Implement Voting Strategies

Define the logic that determines voting power and proposal eligibility for your DAO.

A voting strategy is the core logic that determines how voting power is calculated for each participant in your Snapshot space. Instead of a simple one-token-one-vote system, strategies allow you to implement complex, customized governance models. Common strategies include: - Token-based: Voting power is proportional to the amount of a specified ERC-20 token (e.g., $GOV) held. - Multichain: Aggregates token balances across multiple networks (Ethereum, Polygon, Arbitrum). - Whitelist: Grants a fixed voting power to a predefined list of addresses. - Delegation: Allows token holders to delegate their voting power to other addresses.

Strategies are defined in your space's settings using a JSON configuration. Each strategy requires a name (like erc20-balance-of) and params specifying the contract address, network, and other necessary details. For a basic ERC-20 strategy on Ethereum, your configuration would look like this:

json
{
  "name": "erc20-balance-of",
  "params": {
    "address": "0x...",
    "symbol": "GOV",
    "decimals": 18,
    "network": "1"
  }
}

The network field uses Chain IDs (1 for Ethereum Mainnet). You can combine multiple strategies, where a voter's total power is the sum of all strategies they qualify for.

For more advanced logic, you can implement a custom strategy by writing a smart contract. This contract must expose a getVotingPower function that returns an integer representing the voting power for a given address, block number, and parameters. This enables complex models like: - Time-weighted voting (power based on token age). - NFT-based governance (e.g., one vote per NFT owned). - Hybrid models combining token balance with off-chain credentials. Deploy your custom strategy contract, verify it on a block explorer, and reference its address in your Snapshot space settings.

After defining your strategies, you must configure proposal validation. This determines which addresses are allowed to create proposals. The most common validation is a simple token threshold: a user must hold a minimum balance (e.g., 100 $GOV) to submit a proposal. This prevents spam. You set this in your space settings under 'Validation' by selecting a strategy (like your main erc20-balance-of) and defining the minScore required. More complex validations can be built using custom contracts, allowing for multi-signature requirements or role-based permissions.

Thoroughly test your strategy configuration before launching live proposals. Use Snapshot's Testnet feature by creating a separate space on Goerli or Sepolia. Mint test tokens to various addresses and verify that the calculated voting power in proposal previews matches expectations. Testing ensures your governance model works as intended and prevents disputes after a proposal goes live. Remember, strategies define the rules of your democracy; their accuracy and fairness are paramount for legitimate decentralized governance.

STRATEGY TYPES

Snapshot Voting Strategy Comparison

Comparison of common strategies for weighting votes in a Snapshot space.

StrategyDescriptionComplexitySybil ResistanceTypical Use Case

erc20-balance-of

1 token = 1 vote, based on a snapshot block.

Low

Token-weighted governance for DAOs.

erc721-balance-of

1 NFT = 1 vote, per unique NFT in a collection.

Low

Medium

NFT-gated communities or collections.

whitelist

Pre-defined list of addresses with equal voting power.

Low

Core team or multisig signer votes.

multichain

Aggregates balances from the same address across multiple chains.

Medium

Cross-chain DAOs or protocols.

delegation

Allows token holders to delegate voting power to other addresses.

High

Large-scale DAOs with voter delegation.

quadratic

Voting power = sqrt(balance), reducing whale dominance.

High

Medium

Communities prioritizing egalitarian outcomes.

step-3-proposal-workflow
GOVERNANCE EXECUTION

Step 3: Establish a Proposal Creation Workflow

A structured workflow for creating proposals is essential for maintaining governance quality and community trust. This step defines the process from ideation to publication on Snapshot.

The proposal creation workflow standardizes how governance ideas become formal votes. Start by defining clear proposal templates in your community's documentation. A standard template should include sections for: a descriptive title, a concise abstract, detailed specifications, a clear voting mechanism (e.g., single-choice, weighted), and a discussion period before the snapshot is taken. Using a template ensures all necessary information is present, reducing ambiguity and improving voter comprehension. Tools like Discourse forums or Commonwealth are excellent for hosting this pre-proposal discussion phase.

Next, establish proposal validation rules. These are automated or manual checks run before a proposal is published on Snapshot. Key validations include: verifying the proposer's voting power meets a minimum threshold (e.g., 1% of total delegated tokens), ensuring the proposal text adheres to the template, and confirming the linked discussion thread has been active for a mandated period (e.g., 48-72 hours). You can implement these checks using Snapshot's validation strategies or through a custom bot in your community's Discord or Telegram.

For technical execution, the workflow culminates in creating the proposal on the Snapshot hub. Use the Snapshot.js library or the official interface. The core action is calling the propose method on the Snapshot smart contract, which requires specific parameters: the space ID (your DAO's unique identifier), the proposal title and body, the choices for voting, the start and end block numbers (or timestamps), and the snapshot block number for voting power calculation. Always calculate the snapshot block carefully—it determines which token balances are counted.

Here is a simplified code example for creating a proposal programmatically using the Snapshot.js client:

javascript
import snapshot from '@snapshot-labs/snapshot.js';

const hub = 'https://hub.snapshot.org'; // or your custom hub
const client = new snapshot.Client712(hub);

const receipt = await client.proposal(wallet, spaceId, {
  title: 'Proposal to Increase Grant Funding',
  body: 'Full proposal specification...',
  choices: ['Yes', 'No', 'Abstain'],
  start: Math.floor(Date.now() / 1000), // Start now
  end: Math.floor(Date.now() / 1000) + 259200, // End in 3 days
  snapshot: await provider.getBlockNumber(), // Current block
  type: 'single-choice',
  discussion: 'https://forum.dao.org/t/1234',
  plugins: JSON.stringify({})
});

After publication, integrate the proposal into your community's communication channels. Pin the Snapshot link in the relevant Discord channel, announce it on Twitter, and update any governance dashboards. This ensures maximum visibility and participation. Finally, document every proposal's lifecycle—from discussion thread to final vote tally—in a transparent log. This creates an auditable history, reinforces process legitimacy, and provides valuable data for analyzing governance health and voter engagement trends over time.

step-4-bot-integration
COMMUNICATION LAYER

Step 4: Integrate with Discord and Telegram

Automate proposal notifications and results distribution to your community's primary communication channels.

After setting up your Snapshot space and creating proposals, the next step is to ensure your community is actively engaged. Manual announcements are inefficient and error-prone. Automated integration with Discord and Telegram is essential for broadcasting new proposals, voting reminders, and final results directly to your members. This keeps the governance process transparent and accessible, driving higher participation rates. You can achieve this using webhooks, which are user-defined HTTP callbacks triggered by specific events in your Snapshot space.

For Discord integration, you will need to create a webhook in your server's channel settings. Copy the webhook URL. In your Snapshot space settings, navigate to the 'Webhooks' section and add a new webhook. Configure it to send a POST request to your Discord webhook URL whenever a proposal's state changes (e.g., from 'pending' to 'active' or 'closed'). The payload should be formatted as a Discord embed for clean presentation. You can use a service like Zapier or Make for no-code automation, or write a simple serverless function using platforms like Vercel or AWS Lambda to receive the Snapshot webhook and forward it to Discord.

Telegram integration follows a similar pattern but uses the Telegram Bot API. First, create a new bot via @BotFather to get your bot token. Then, create a public channel or group and add your bot as an administrator. Obtain the channel's unique chat_id. Your automation service or custom script must now send a message via the sendMessage method of the Telegram Bot API whenever a Snapshot event occurs. The message should include key details: proposal title, link, voting options, and the current status. For both platforms, ensure your messages are informative but not spammy to maintain channel quality.

Here is a basic Node.js code snippet for a serverless function that handles a Snapshot webhook and posts to Telegram:

javascript
const axios = require('axios');
module.exports = async (req, res) => {
  const { title, link, state } = req.body; // Data from Snapshot webhook
  const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
  const CHAT_ID = process.env.TELEGRAM_CHAT_ID;
  const message = `*New Proposal ${state.toUpperCase()}*\n${title}\nVote here: ${link}`;
  const url = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
  await axios.post(url, { chat_id: CHAT_ID, text: message, parse_mode: 'Markdown' });
  res.status(200).send('OK');
};

Testing is critical. Use Snapshot's testnet (https://testnet.snapshot.org) to create a dummy proposal and verify that your webhook triggers correctly and messages appear in your Discord and Telegram channels as expected. Monitor for failed deliveries and set up alerts. Finally, document the integration process for your team and consider open-sourcing the configuration to build trust with your community, showing them exactly how governance notifications are automated and delivered.

step-5-off-to-on-chain
IMPLEMENTATION

Step 5: Bridging Off-Chain Votes to On-Chain Execution

This step details the technical process of securely translating the results of a Snapshot vote into an on-chain transaction, enabling trustless execution of governance decisions.

After a Snapshot vote concludes, the final result is a Merkle tree data structure stored on IPFS. The root of this tree, or Merkle root, cryptographically commits to the entire voting outcome. To execute the proposal on-chain, a relayer (often a community multisig or a designated executor contract) must submit a transaction containing this Merkle root and a Merkle proof for the specific proposal action. This proof verifies that the proposed action was indeed part of the approved vote, without needing to publish all voter data on-chain, which would be prohibitively expensive.

The core on-chain component is an executor contract. This contract stores the accepted Merkle root and validates any execution attempt. A common pattern is to use OpenZeppelin's MerkleProof library. The executor's critical function checks the provided proof against the stored root and the proposed calldata. Only if the proof is valid does the contract proceed to make the low-level call to the target contract (e.g., a Treasury or Governor contract). This design ensures execution is permissionless for anyone with a valid proof, while being impossible for unauthorized proposals.

Here is a simplified example of an executor contract's core function:

solidity
function execute(
    address target,
    bytes calldata payload,
    bytes32[] calldata proof
) external {
    bytes32 leaf = keccak256(abi.encodePacked(target, payload));
    require(
        MerkleProof.verify(proof, merkleRoot, leaf),
        "Invalid proof"
    );
    (bool success, ) = target.call(payload);
    require(success, "Execution failed");
}

The leaf is the hash of the target address and the calldata. The relayer must provide the exact sequence of hashes (proof) that reconstructs the path from this leaf to the known root.

Security considerations are paramount. The process relies on a trusted setup for submitting the Merkle root. Typically, a multisig wallet controlled by DAO stewards is authorized to update the root in the executor contract after a vote ends. This creates a clear trust boundary: the multisig only attests to the correctness of the off-chain vote result. Once the root is set, execution is trust-minimized. It's also critical that the executor contract has no special privileges beyond calling the target; it should not hold funds or have upgradeability mechanisms that could subvert the executed action.

In practice, many projects use battle-tested solutions like the SafeSnap module developed by Gnosis Guild. SafeSnap integrates directly with Gnosis Safe multisigs and the Snapshot protocol, providing a UI and secure contract templates for this bridging process. Using an audited module reduces risk and development overhead. The execution flow becomes: 1) Snapshot vote ends, 2) DAO multisig confirms and sets the Merkle root in SafeSnap, 3) Any community member can trigger the execution transaction with the valid proof, making the process transparent and resilient.

Finally, consider gas optimization and accessibility. The relayer who submits the execution transaction pays the gas fee. To encourage participation, some DAOs implement a gas reimbursement policy from their treasury, rewarding successful relayers. Furthermore, services like Gelato Network can be used to automate the execution transaction, ensuring it happens promptly after the root is set, without relying on a volunteer. This completes the loop, transforming off-chain consensus into enforceable, on-chain state changes.

DEVELOPER TROUBLESHOOTING

Snapshot Implementation FAQ

Common technical questions and solutions for developers building or managing off-chain voting systems with Snapshot.

This is typically a data indexing issue. Snapshot bots index votes from the Ethereum block specified in your snapshot parameter. Common causes include:

  • Incorrect Snapshot Block: The snapshot block number in your proposal must be a past block. Using a future or current block will result in 0 votes.
  • RPC Issues: The Snapshot indexer relies on the RPC endpoint configured for your space. If the RPC is slow, rate-limited, or returning incorrect state, votes won't be indexed.
  • Strategy Errors: A custom voting strategy with a bug in its getVotes function will return 0. Test your strategy in the playground first.

Fix: Verify the snapshot block is finalized, check your space's RPC health, and debug your strategy logic.

conclusion-next-steps
SYSTEM OVERVIEW

Conclusion and Next Steps

Your off-chain voting system is now operational. This section summarizes the key components you've built and outlines how to expand its functionality.

You have successfully deployed a complete Snapshot-based voting system. The core components include: a Strategy contract (e.g., VotingPowerStrategy) that defines voter eligibility and vote weighting logic, a Space on Snapshot that serves as the frontend interface for proposal creation and voting, and the off-chain Snapshot Hub which securely stores proposal and vote data using IPFS and signs it with your chosen wallet. This architecture separates the complex, gas-intensive logic of voting from the blockchain, making it cost-effective and accessible while leveraging the security of on-chain data for verification.

To ensure your system's robustness, focus on security and maintenance. Regularly audit your strategy contract for logic errors and update it if your tokenomics change. Monitor your Snapshot Space's settings, including admins, moderators, and voting validation methods. For high-value governance, consider implementing a timelock on executed proposals or a multi-sig for execution. It's also crucial to educate your community on how to verify their voting power and understand the proposal lifecycle, from creation to execution via an Ethereum Execution contract.

To extend your system's capabilities, explore advanced Snapshot features. Implement quadratic voting or ranked-choice voting through custom strategies to reduce whale dominance. Use delegation to allow token holders to delegate their voting power to representatives. For cross-chain governance, investigate strategies that read balances from multiple networks like Polygon or Arbitrum using providers like the Multicall3 contract. You can also create plugin for custom validation or integrate with tools like SafeSnap for trustless on-chain execution.

The next practical step is to run a test proposal with your community. Create a dummy proposal in your Space, have users connect their wallets and vote, and verify the results. Use this as an opportunity to gather feedback on the user experience. Simultaneously, document the entire process—from the strategy logic to proposal creation—for your community. Resources like the official Snapshot documentation and their GitHub repository are invaluable for troubleshooting and exploring new features as you scale your governance operations.

How to Launch a Snapshot Off-Chain Voting System | ChainScore Guides