Skip to content

Users can't vote with staked coins #10

@gpevnev

Description

@gpevnev

Description

Users who received AZTEC tokens via Token Vaults (ATPs) and deposited them into Governance through their Staker contract have their voting power attributed to the Staker address, not their wallet. The aztec-gov dashboard currently queries powerNow(userWallet) which returns 0 for these users, so they see 0 voting power and cannot vote — despite having tokens locked in Governance.

This is a UI-only gap: the Staker contract already exposes voteInGovernance(proposalId, amount, support) that proxies votes to Governance using the staker's deposited balance.

Scope

  • Discover a user's stakers via the staking dashboard indexer (GET /api/atp/holdings?beneficiary={userAddress}) behind a NEXT_PUBLIC_STAKING_INDEXER_URL env var.
  • Query powerNow(stakerAddress) for each discovered staker and include it in the user's total voting power.
  • Route votes cast against staker-attributed power through Staker.voteInGovernance(...) instead of Governance.vote(...).
  • Surface a "Staked Positions" breakdown in the voting power UI.

Files touched

  • Modify: src/lib/contracts.ts, src/hooks/useVotingPower.ts, src/hooks/useVote.ts, src/components/governance/VotingPowerPanel.tsx, src/components/governance/ActionPanel.tsx
  • Add: src/hooks/useUserStakers.ts, src/lib/staker-abi.ts (governance-related Staker ABI extracted from staking-dashboard's ATPWithdrawableAndClaimableStaker.ts)

Benefit (The "Why")

ATP recipients who staked into Governance are currently locked out of voting in the aztec-gov dashboard, even though they hold eligible voting power on-chain. Closing this gap restores their ability to participate in governance, brings the dashboard to parity with the protocol's actual voting rules, and removes a silent source of disenfranchisement for a meaningful cohort of token holders.

Acceptance Criteria

  • Connecting a wallet with ATP-staked governance tokens displays a non-zero "Staked Positions" entry in the voting power panel, with a per-staker breakdown.
  • The total voting power shown in VotingPowerPanel and ActionPanel includes both direct-deposit power and the sum of powerNow(stakerAddress) across all discovered stakers.
  • Voting with staker-attributed power submits a transaction to the corresponding Staker contract's voteInGovernance(proposalId, amount, support) (not Governance.vote).
  • Existing direct-deposit voting flows continue to work unchanged (same tx target, same UX).
  • Staker discovery uses the staking dashboard indexer via NEXT_PUBLIC_STAKING_INDEXER_URL, defaulting to the production indexer URL when unset.
  • Users with no ATP/staker holdings see no "Staked Positions" section and experience no regression.
  • Indexer failures (network error, non-200) degrade gracefully: direct-deposit voting power still renders, and the UI surfaces a non-blocking error state for the staker section.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions