auto-voting-relayers

Complete domain knowledge for VeBetterDAO's auto-voting and relayer system. Use when working on relayer dashboard, relayer node, auto-voting contracts (XAllocationVoting, VoterRewards, RelayerRewardsPool), or anything related to relayers, auto-voting, gasless voting, or relayer rewards. Triggers on: relayer, auto-voting, autovoting, gasless voting, relayer rewards, RelayerRewardsPool, castVoteOnBehalfOf, relayer dashboard, relayer node, veDelegate comparison.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "auto-voting-relayers" with this command: npx skills add vechain/vechain-ai-skills/vechain-vechain-ai-skills-auto-voting-relayers

VeBetterDAO Auto-Voting & Relayer System

Complete domain knowledge for the auto-voting and relayer ecosystem. This skill provides context for working on any component of the system: smart contracts, relayer node, relayer dashboard, or documentation.

System Overview

VeBetterDAO's auto-voting system lets users automate their weekly X Allocation voting. Users pick favorite apps once, toggle auto-voting on, and relayers (off-chain services) handle the rest: casting votes, claiming rewards, all gasless. Relayers earn a fee from the reward pool. Tokens never leave the user's wallet.

Auto-voting applies only to X Allocation rounds. Governance proposals remain manual-only.

Architecture

Users (toggle auto-voting, set preferences)
    |
    v
Smart Contracts (on-chain logic)
    - XAllocationVoting (v8): auto-voting state, vote execution
    - VoterRewards (v6): reward claiming, fee deduction
    - RelayerRewardsPool (v1): relayer registration, reward distribution
    |
    v
Relayer Nodes (off-chain execution)
    - relayer-node/ (standalone CLI, no monorepo dependency)
    - Monitor rounds, batch vote/claim, loop every 5 min
    |
    v
Relayer Dashboard (monitoring/analytics)
    - apps/relayer-dashboard/ (static Next.js, GitHub Pages)
    - Round analytics, relayer stats, ROI tracking

How It Works (Non-Technical)

For Users

  1. Hold 1+ VOT3, complete 3+ sustainable actions, pass VeBetterPassport
  2. Choose up to 15 apps, toggle auto-voting on
  3. Takes effect next round (not current)
  4. Each week: relayer votes for you, claims your rewards to your wallet
  5. Fee: 10% of rewards (max 100 B3TR/week) - covers all gas costs
  6. While active: no manual voting/claiming allowed
  7. Manual claim fallback: available 5 days after round end if relayer hasn't processed

Auto-Disable Triggers

  • VOT3 drops below 1
  • All selected apps become ineligible
  • Sustainable action threshold not met
  • Bot detection by app owner

For Relayers

  1. Register on-chain by calling registerRelayer() on RelayerRewardsPool (open to anyone)
  2. Run relayer-node with wallet (MNEMONIC or RELAYER_PRIVATE_KEY)
  3. Node auto-discovers users, batches votes + claims
  4. Earn weighted points: vote = 3 pts, claim = 1 pt
  5. After ALL users served, claim proportional share of reward pool
  6. All-or-nothing: if any user missed, nobody gets paid

Apps as Relayers

Apps can register as relayers, ask users to set them as preference, and run a node. They earn relayer fees instead of paying veDelegate for votes. Important: apps should ADD themselves to preference lists, not replace other apps.

vs veDelegate

FeatureveDelegateVeBetterDAO Auto-Voting
X Allocation votingYesYes
Governance votingYes (always "abstain")No (manual only)
Compounding (B3TR->VOT3)AutoManual
Token custodyLeaves walletStays in wallet
CentralizationSingle entityMany relayers
Cost to appsApps pay veDelegateApps earn fees

veDelegate: docs.vedelegate.vet / github.com/vechain-energy/vedelegate-for-dapps

Smart Contracts Detail

XAllocationVoting.sol (v8)

Auto-voting added in v8 via AutoVotingLogicUpgradeable module.

Storage (in AutoVotingLogic library):

  • _autoVotingEnabled: Checkpointed per-user status (changes take effect next round)
  • _userVotingPreferences: Array of app IDs per user (max 15, validated, no duplicates)
  • _totalAutoVotingUsers: Checkpointed total count

Key functions:

toggleAutoVoting(address user)                         // Enable/disable
setUserVotingPreferences(bytes32[] memory appIds)      // Set apps (1-15)
castVoteOnBehalfOf(address voter, uint256 roundId)     // Relayer executes vote
getUserVotingPreferences(address)                      // View preferences
isUserAutoVotingEnabled(address)                       // Current status
isUserAutoVotingEnabledForRound(address, uint256)      // Status at round snapshot
getTotalAutoVotingUsersAtRoundStart()                  // Count at last emission
getTotalAutoVotingUsersAtTimepoint(uint48)             // Historical count

Vote execution (castVoteOnBehalfOf):

  1. Validate early access (registered relayer during window)
  2. Get user preferences, filter eligible apps
  3. Split voting power equally across eligible apps
  4. Cast via internal _countVote()
  5. Register VOTE action on RelayerRewardsPool (3 weight points)

VoterRewards.sol (v6)

V6 added relayer fee integration. Fee deduction happens HERE during claimReward().

V6 storage: xAllocationVoting, relayerRewardsPool

Fee flow in claimReward(uint256 cycle, address voter):

  1. Check user had auto-voting at round start (checkpointed)
  2. Calculate raw rewards (voting + GM reward)
  3. If auto-voting: fee = min(totalReward * 10/100, 100 B3TR)
  4. Fee proportionally split between voting and GM reward
  5. Fee approved + deposited to RelayerRewardsPool.deposit(fee, cycle)
  6. registerRelayerAction(msg.sender, voter, cycle, CLAIM) - credits caller with 1 weight point
  7. Net reward transferred to voter wallet

Important: msg.sender calling claimReward() IS the relayer credited for CLAIM action.

Early access: During window, validateClaimDuringEarlyAccess() reverts if caller is the voter or not a registered relayer.

RelayerRewardsPool.sol (v1)

Manages registration, action tracking, reward distribution.

Storage:

totalRewards[roundId]                    // Pool amount (funded by fees)
relayerWeightedActions[roundId][relayer] // Per-relayer weighted work
totalWeightedActions[roundId]            // Expected weighted total
completedWeightedActions[roundId]        // Completed weighted total
registeredRelayers[address]              // Registration mapping
relayerAddresses[]                       // All registered addresses
voteWeight = 3                           // Points per vote action
claimWeight = 1                          // Points per claim action
earlyAccessBlocks = 432,000              // ~5 days on VeChain
relayerFeePercentage = 10               // 10%
feeCap = 100 ether                       // 100 B3TR

Reward formula:

relayerShare = (relayerWeightedActions / completedWeightedActions) * totalRewards

Claimability: isRewardClaimable(roundId) requires:

  • Round ended (emissions.isCycleEnded(roundId))
  • All work done (completedWeightedActions >= totalWeightedActions)

Registration (open to anyone):

  • registerRelayer() — self-registration, callable by anyone
  • unregisterRelayer(address) — callable by admin or the relayer itself
  • setTotalActionsForRound(roundId, userCount) - sets expected = userCount x 2 actions, userCount x 4 weighted
  • reduceExpectedActionsForRound(roundId, userCount) - for ineligible users
  • registerRelayerAction(relayer, voter, roundId, action) - record work
  • deposit(amount, roundId) - fund pool

Early access:

  • Vote window: roundSnapshot + earlyAccessBlocks
  • Claim window: roundDeadline + earlyAccessBlocks
  • During: only registered relayers, user can't self-act
  • After: anyone can act

Auto-Voting Lifecycle (Per Round)

Round N: User enables auto-voting + sets preferences (checkpointed)
Round N+1:
  1. startNewRound() - snapshot locks auto-voting status
  2. setTotalActionsForRound(roundId, userCount)
  3. Relayers call castVoteOnBehalfOf() for each user
     - Ineligible users: reduceExpectedActionsForRound()
     - Each successful vote: +3 weighted points to relayer
  4. Round ends (deadline block)
  5. Relayers call VoterRewards.claimReward() for each user
     - Fee deducted and deposited to pool
     - Each successful claim: +1 weighted point to relayer
  6. All actions complete -> pool unlocked
  7. Relayers call RelayerRewardsPool.claimRewards()

Relayer Node (relayer-node/)

Standalone CLI tool. No monorepo dependency.

Deps: @vechain/sdk-core, @vechain/sdk-network, @vechain/vebetterdao-contracts

relayer-node/src/
  index.ts      # Entry, env parsing, main loop, SIGINT
  config.ts     # Mainnet + testnet-staging addresses
  contracts.ts  # 26 view functions + event pagination
  relayer.ts    # Batch vote/claim with isolation/retry
  display.ts    # Terminal UI (box drawing + chalk)
  types.ts      # Shared interfaces

Env vars: MNEMONIC / RELAYER_PRIVATE_KEY, RELAYER_NETWORK, RUN_ONCE, DRY_RUN

Cycle: Discover users from events -> filter voted -> batch castVoteOnBehalfOf -> batch claimReward -> loop 5min

Relayer Dashboard (apps/relayer-dashboard/)

Static Next.js 14 (output: "export"), Chakra UI v3, VeChain Kit, Recharts. GitHub Pages under /b3tr.

Data: Static report.json (hourly GH Action, temporary) + on-chain reads via useCallClause

Pages (state-based nav, not file routing):

  • Home: StatsCards (2x2), RoundsChart, RoundsList, info cards
  • My Relayer: ConnectedWallet view
  • Info: BecomeRelayer + AppsAsRelayers
  • Round detail: /round?roundId=X - 2-col layout, summary/actions/financials

Hooks:

  • contracts.ts - ABIs + addresses from @repo/config
  • useCurrentRoundId - XAllocationVoting.currentRoundId()
  • useTotalAutoVotingUsers - getTotalAutoVotingUsersAtTimepoint()
  • useRegisteredRelayers - getRegisteredRelayers()
  • useRoundRewardStatus - isRewardClaimable() + getTotalRewards()
  • useReportData - fetches /data/report.json
  • useB3trToVthoRate - oracle exchange rate

Commands: yarn relayer:dev:staging, yarn relayer:dev:mainnet, yarn relayer:build:staging, yarn relayer:build:mainnet

Gas Cost Analysis

ActionGasVTHOB3TR equiv
Vote (5-8 apps)~441K~4.41~0.075
Claim~208K~2.08~0.035
Total/user/round~6.49~0.11

Average user: ~10.8k-22.6k VOT3, earns ~90-190 B3TR/round. At 10% fee: ~9-19 B3TR per user into pool. Relayer cost: ~0.11 B3TR. Margin: ~8.9-18.9 B3TR/user.

External Resources

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Web3

grill-me

No summary provided by upstream source.

Repository SourceNeeds Review
Web3

smart-contract-development

No summary provided by upstream source.

Repository SourceNeeds Review
Web3

translate

No summary provided by upstream source.

Repository SourceNeeds Review
Web3

vechain-kit

No summary provided by upstream source.

Repository SourceNeeds Review