FoundrySolidityLayer 2
7.25 ETH
Submission Details
Impact: high
Likelihood: high

Zero-Duration Risk Windows Allow Very Late Large Stake Sums to Capture Bonus Through Amount-Weighted Fallback

Author Revealed upon completion

ROOT CAUSE

if (globalScore == 0) {
if (snapshotTotalStaked == 0) return 0;
return Math.mulDiv(userEligible, snapshotTotalBonus, snapshotTotalStaked);
}

DESCRIPTION

The stake() function allows staking while registry is UNDER_ATTACK . The late stake gets timestamped at the current block and is then added into the eligible stake and global score sums and risk window start can be set in that same stake transaction. The pool is designed so bonus rewards compensate users for taking risk over time. In normal conditions, someone who stakes late during UNDER_ATTACK should receive little or no bonus because their at-risk duration is tiny.

If the risk window has zero duration, bonus then falls back to amount weighted distribution. But when the risk window has zero duration, the formula cannot time-weight anyone. So the contract falls back to amount-weighted distribution.

return Math.mulDiv(userEligible, snapshotTotalBonus, snapshotTotalStaked);

A late staker can use a very large stake (possibly a flash-loan) to convert the zero-duration fallback into an amount-weighted bonus distribution, capturing nearly all of snapshotTotalBonus while earlier stakers who bore the actual risk receive very little or no bonus.

SCENARIO

Alice stakes early: 100 tokens

Bob stakes early: 100 tokens

Bonus pool: 100 tokens

Expected fair outcome: Alice and Bob share the bonus

Then attacker enters very late:

Attacker flash/late stakes: 10,000 tokens

Risk window duration: very minimal

Outcome resolves: SURVIVED or EXPIRED

Now snapshotTotalStaked is: 100 + 100 + 10,000 = 10,200

The attacker’s bonus share becomes roughly: 10,000 / 10,200 * 100 = 98.03 bonus tokens

Alice and Bob together receive only about: 1.97 bonus tokens

The Attacker captures almost the entire bonus despite taking almost no meaningful risk.
Honest Stakers receive their principal back, but lose most or all of the bonus they expected.
The Attacker receives their principal back plus an unfair bonus share.

Recommended Mitigation

  1. Seperate pre-risk stake from post-risk stake and award higher percentage bonus to pre-risk stakers

  2. Or Consider blocking stake even during UNDER_ATTACK

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!