Reproduced Exploit
Buck Labs: A late inflow disqualifies account A but leaves its 100-token balance in currentEligibleSu
Chain
Other
Category
untagged
Date
Jan 1970
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: 64665-eligible-supply-is-not-reduced-on-late-entry-spearbit-none-b. The historical source/toolchain is unavailable; this entry is documentation only and claims no executable Forge PoC.
Vulnerability classes: vuln/locked-funds · vuln/reward-accounting
Reproduction: a faithful minimal reproduction of the vulnerable finding — the vulnerable function is reproduced verbatim (marked
@>) with faithful minimal doubles; local deploy, no fork.
Root cause#
A late inflow disqualifies account A but leaves its 100-token balance in currentEligibleSupply, inflating globalEligibleUnits (the distribution denominator); eligible account C is under-paid by 550,000 reward tokens and 600,000 reward tokens are permanently locked (undistributed) in the RewardsEngine.
// ─── verbatim vulnerable block (RewardsEngine.sol#L1257-L1274) ───
bool isLateEntry = (checkpointStart > 0 && now_ >= checkpointStart && now_ < epochEnd);
if (isLateEntry) {
s.eligible = false; // @> late entry marks the account ineligible but its prior eligible balance is NEVER subtracted from currentEligibleSupply
s.lastAccrualTime = now_;
} else {
Why it's exploitable here#
A late inflow disqualifies account A but leaves its 100-token balance in currentEligibleSupply, inflating globalEligibleUnits (the distribution denominator); eligible account C is under-paid by 550,000 reward tokens and 600,000 reward tokens are permanently locked (undistributed) in the RewardsEngine.
Attack path#
Marked-line walkthrough (Playground)#
The EVM Playground pins each step to the exact executed source line in 0xce01759b82…:
- L90 — Wire reward token: Setup: constructor stores the reward token the engine later distributes.
- L106 — Accrual checkpoint entry point: Permissionless checkpoint that updates per-account accrual and eligibility before distribution.
- L124 — Compute account elapsed time: Measures time since the account's last accrual to credit its pending reward units.
- L135 — Disqualify account, keep its supply: Root-cause bug: a late inflow flips the account ineligible but never subtracts its balance from
currentEligibleSupply, inflating the reward denominator. - L138 — Branch for non-excluded accounts: Only non-excluded accounts feed eligible supply — yet the balance just disqualified above is still being counted.
- L156 — Distribute over eligible units: Splits the reward across
globalEligibleUnits; the inflated denominator underpays honest accounts and strands the rest. - L171 — Update last accrual timestamp: Records the account's accrual time so the next checkpoint measures elapsed time from here.
PoC#
Registry (Foundry, local deploy — verbatim vulnerable source + harm-asserting test + negative control):
cd 64665-eligible-supply-is-not-reduced-on-late-entry-spearbit-none-b_exp
forge test -vvv
The browser Playground replays the same synthetic opcode-for-opcode and measures the harm: A late inflow disqualifies account A but leaves its 100-token balance in currentEligibleSupply, inflating globalEligibleUnits (the distribut. Both gates are green (registry forge test PASS + Playground _verify-poc VERDICT: PASS).
Sources & further analysis#
Reproductions & code
- No executable Forge reproduction is claimed; the historical source/toolchain was unavailable for this finding.
- AuditVault finding: 64665-eligible-supply-is-not-reduced-on-late-entry-spearbit-none-b.
- Upstream DeFiHackLabs PoC directory: src/test.
Alerts & third-party analyses
- DeFiHackLabs incident explorer: search "Buck Labs: A late inflow disqualifies account A but leaves its 100-token balance in currentEligibleSu".
- 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.