Reproduced Exploit

Virtuals — public impact recalculation redirects reward allocation

Impact values determine the allocation used to mint rewards. updateImpact is public, and it persists a recalculated allocation using the current datasetImpactWeight. After governance changes that weight, any account can invoke the function and force an already-recorded impact to be rewritten before…

Apr 2025Otheraccess-control3 min read

Chain

Other

Category

access-control

Date

Apr 2025

Source

AuditVault

EVM Playground

Source-level debugger — step opcodes and Solidity in sync

evm-hack-analyzer

The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.

Loading fork state…

Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 61824-h-03-public-servicenftupdateimpact-call-leads-to-cascading-i. Standalone Foundry PoC and full write-up: 61824-h-03-public-servicenftupdateimpact-call-leads-to-cascading-i_exp in the evm-hack-registry mirror.


Vulnerability classes: vuln/access-control/missing-auth · vuln/logic/reward-calculation · vuln/logic/incorrect-state-transition

Reproduction: self-contained Foundry PoC with no fork, RPC, or cheatcodes. Full trace: output.txt. Driver: test/61824-h-03-public-servicenftupdateimpact-call-leads-to-cascading-i_exp.sol.

AuditVault taxonomy: blockchain/evm · blockchain/evm/base · lang/solidity · sector/dex · sector/governance · sector/nft · platform/code4rena · has/github · has/poc · severity/high · impact/loss-of-funds/direct-drain · genome: single-function · direct-drain · reward-accounting

Key info#

ImpactHIGH — an untrusted caller can turn a governed weight update into a 90-unit reward claim rather than the original 20 units.
ProtocolVirtuals
Vulnerable codeServiceNft.updateImpact
FindingCode4rena Virtuals, 2025-04 · #61824 (H-03) · reporter TheDonH
StatusAudit finding; local reduction models the reward-bearing impact rewrite.
Compiler^0.8.24 (local reduction)

TL;DR#

Impact values determine the allocation used to mint rewards. updateImpact is public, and it persists a recalculated allocation using the current datasetImpactWeight. After governance changes that weight, any account can invoke the function and force an already-recorded impact to be rewritten before claiming.

The PoC records an initial 20 percent allocation, changes the governed weight to 90 percent, lets a public helper recalculate it, and claims 90 reward units.

The vulnerable code#

SOLIDITY
_impacts[datasetId] = (rawImpact * datasetImpactWeight) / 10_000; // @> VULN
_impacts[proposalId] = rawImpact - _impacts[datasetId];

These reward-bearing assignments are reachable through a public function rather than a controlled accounting update.

Root cause#

A mutable governance parameter is combined with a permissionless state-changing recalculation. The design does not distinguish reading a new configuration from authorized migration of historic accounting records.

Preconditions#

  • An impact has already been recorded and can later be claimed for rewards.
  • datasetImpactWeight changes through its intended governance path.
  • Any external account can call updateImpact before settlement.

Attack walkthrough#

  1. A dataset impact is created with a 20 percent weight.
  2. Governance changes the global weight to 90 percent.
  3. An attacker calls the public recalculation entry point.
  4. The persisted impact becomes 90, and the attacker claims 90 reward units.

Diagrams#

flowchart TD A[Impact recorded at 20 percent] --> B[Governance changes weight to 90 percent] B --> C[Untrusted caller invokes updateImpact] C --> D[Stored allocation overwritten] D --> E[Attacker claims 90 reward units]

Remediation#

Make impact mutation internal or restrict it to the protocol component that owns the accounting transition. If a governance migration is needed, use a bounded, explicitly authorized batch operation and snapshot the weight used for each settled record.

How to reproduce#

BASH
cd /workspaces/RustroverProjects/audits/evm-hack-registry/61824-h-03-public-servicenftupdateimpact-call-leads-to-cascading-i_exp
forge test -vvv

Sources#

Reference: Code4rena Virtuals finding H-03, curated by AuditVault.


Sources & further analysis#

Reproductions & code

Alerts & third-party analyses

  • Web3Sec X hacked database: search.
  • Rekt leaderboard: search.
  • Solodit incident search: search.

These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.