stake() and contributeBonus() check that the pool is unresolved before making the external token call, but they do not re-check the outcome after safeTransferFrom returns. A callback-capable token can resolve the pool during the transfer. The function then resumes and writes stake or bonus accounting after the terminal snapshot has already been taken.
This breaks the link between the terminal snapshot and the accounts/funds that can later claim against it.
contributeBonus() can exclude a pre-resolution bonus from the terminal snapshot:
If the token callback resolves the pool before totalBonus += received, the terminal snapshot does not include the contribution. The contribution is still recorded in totalBonus after resolution and can later be swept as excess instead of paid to stakers.
stake() has the same timing issue:
If the callback resolves the pool during the transfer, the snapshot includes only incumbent stake. The attacker's stake is then written after the snapshot and can claim against a denominator that excluded it.
A victim bonus contribution made before resolution can be excluded from snapshotTotalBonus and swept to recoveryAddress instead of distributed.
An attacker can create post-snapshot stake and use it to drain incumbent staker principal and bonus. In the strongest case, the attacker claims against a stale denominator and empties the pool, leaving honest claims to revert.
The stale snapshot can also push claimedBonus above snapshotTotalBonus. Later sweepUnclaimedBonus() can then underflow at snapshotTotalBonus - claimedBonus, trapping residual funds.
If a stale bonus is swept before a moderator reflags to good-faith CORRUPTED, the corrected bounty can be underpaid because the reflagged bounty snapshot excludes the swept in-flight bonus.
In-flight bonus contribution excluded from the terminal snapshot:
In-flight stake finalized outside the snapshot:
Stale snapshot overclaim can brick the later sweep:
Good-faith reflag underpays the corrected bounty:
Re-check the terminal state after every external token transfer and before writing post-transfer accounting.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.