Reproduced Exploit
Base/reward token alias inflates `burnForBase` — reward-accounting theft
burnForBase pro-rates the entire base-token balance. If rewards use the same token as base, reward funding is counted as principal and a burner receives 150 for 100 strategy tokens.
Loss
Burners receive reward funding as if it were base principal
Chain
Ethereum
Category
logic
Date
Jun 2021
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
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.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 16984-strategy-contracts-balance-tracking-system-could-facilitate. Standalone Foundry PoC and full write-up: 16984-strategy-contracts-balance-tracking-system-could-facilitate_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/logic/reward-calculation · vuln/logic/missing-validation
Reproduction: self-contained synthetic Foundry reduction; see output.txt.
Key info#
| Field | Value |
|---|---|
| Loss | Burners receive reward funding as if it were base principal |
| Vulnerable contract | Strategy.burnForBase / setRewardsToken |
| Attacker EOA | 0x1111111111111111111111111111111111111111 |
| Attack contract | RewardToken and Strategy via Exploit |
| Attack tx | Exploit.run() |
| Chain / block / date | Ethereum model · block 0 · 2021-06 |
| Compiler | solc 0.8.24 (synthetic) |
| Bug class | Reward token may equal base token |
TL;DR#
burnForBase pro-rates the entire base-token balance. If rewards use the same token as base, reward funding is counted as principal and a burner receives 150 for 100 strategy tokens.
Background#
Yield V2's ERC20Rewards inheritance assumes the reward token is distinct from base, liquidity, fyToken, and strategy tokens. The reviewed setter lacked that identity check.
The vulnerable code#
withdrawal = base.balanceOf(address(this)) * burnt / totalSupply; // @> includes rewards
Root cause#
Configuration permits the reward token to alias base, so balance-based withdrawal cannot distinguish principal from reward reserves.
Preconditions#
- An administrator sets
rewardsToken == base. - Reward tokens are funded before strategy tokens are burned.
Attack walkthrough#
Exploitconfigures the same token as base and rewards.- The strategy holds 100 principal plus 50 reward tokens.
- Burning 100 strategy tokens pays 150; the
Proofevent is at output.txt:393.
Diagrams#
Remediation#
Reject reward-token aliases at configuration time and track principal/reserve balances separately before calculating redemptions.
How to reproduce#
cd evm-hack-registry/16984-strategy-contracts-balance-tracking-system-could-facilitate_exp
forge test -vvvvv
Sources#
Reference: https://github.com/trailofbits/publications/blob/master/reviews/YieldV2.pdf
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 16984-strategy-contracts-balance-tracking-system-could-facilitate_exp (evm-hack-registry mirror).
- AuditVault finding: 16984-strategy-contracts-balance-tracking-system-could-facilitate.
Alerts & third-party analyses
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.