# Anybody can control a user’s delegate by calling AgentVeToken.stake() with 1 wei

AgentVeToken.stake() delegates the receiver's voting power to an attacker-chosen delegatee, letting anyone stake 1 wei to hijack a whale's votes and pass malicious DAO proposals.

- Payout: Contest reward
- Severity: high
- Program: Virtuals Protocol
- Credited: BowTiedOriole
- Disclosed: 2025-08-04
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2025-04-virtuals-protocol#h-02
- Library page: https://bugbountylibrary.com/r/c4%3A2025-04-virtuals-protocol%3AH-02
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:governance

**Target:** AgentVeToken staking contract (ERC4626-style veToken)
**Root cause:** stake() unconditionally calls _delegate(receiver, delegatee) with an attacker-supplied delegatee, so staking any amount for a victim overwrites the victim's delegate regardless of who the sender is.
**Steps:**
1. Acquire 1 wei of the agent LP token (assetToken).
2. Approve AgentVeToken to spend it.
3. Call `stake(1, victimWithHighVeBalance, attackerAddress)`.
4. Observe `delegates(victim)` now returns attackerAddress, granting attacker the victim's voting power in AgentDAO.
5. Repeat across many large holders to accumulate majority voting power, then submit a malicious proposal.
**How found:** Code review of stake(): noticed _delegate(receiver, delegatee) is called with attacker-controlled delegatee and no check that sender==receiver, making delegation hijackable for 1 wei.
**Exploitation:** Attacker stakes 1 wei per victim with receiver=victim and delegatee=attacker, silently reassigning voting power of all large veToken holders to themselves, then uses aggregated votes to pass a malicious governance proposal.
**Escalation:** Donate 1 wei to multiple high-balance holders to aggregate majority voting power in AgentDAO.
**Insight:** In veToken/ERC4626-style staking, any function that delegates on behalf of the receiver must gate the delegatee on msg.sender==receiver; otherwise a dust stake lets you capture arbitrary holders' voting power.
