FoundrySolidityLayer 2
7.25 ETH
Submission Details
Impact: medium
Likelihood: low

Moderator can revoke good-faith bounty via CORRUPTED re-flag

Author Revealed upon completion

Description

Before any claim, the moderator can re-flag the outcome freely. flagOutcome() allows re-flag when outcome != UNRESOLVED && claimsStarted == false (Pool:327). The moderator can initially flag CORRUPTED, goodFaith=true, attacker=whitehat — setting bountyEntitlement = snapshotTotalStaked + snapshotTotalBonus — then re-flag to CORRUPTED, goodFaith=false before the whitehat can claim. bountyEntitlement is zeroed (Pool:362), and claimAttackerBounty reverts at Pool:435 with InvalidGoodFaithParams.

The _firstGoodFaithCorruptedAt guard (Pool:364) only prevents deadline extension, not outcome re-flagging.

Pool:327 if (outcome != UNRESOLVED && claimsStarted) revert OutcomeAlreadySet();
// passes: outcome=CORRUPTED, claimsStarted=false → re-flag allowed
Pool:362 bountyEntitlement = willBeGoodFaithCorrupted ? snapshotTotalStaked + snapshotTotalBonus : 0;
// second flag: willBeGoodFaithCorrupted=false → bountyEntitlement=0
Pool:435 if (!goodFaith) revert InvalidGoodFaithParams();
// whitehat's claimAttackerBounty blocked

Risk

Likelihood: Low. Requires the moderator (DAO-trusted role) to act maliciously. The moderator can already cause far greater damage (e.g., flagging SURVIVED on a genuine breach).

Impact: Medium for whitehat trust. A promised bounty can be revoked with no on-chain recourse. This undermines the whitehat incentive model — the entire purpose of the good-faith CORRUPTED path is to reward security researchers.

Mitigation

Once a good-faith CORRUPTED flag is set with a named attacker, prevent re-flagging to a different CORRUPTED variant. Allow only SURVIVED as a re-flag target (or none at all). A simpler fix: set claimsStarted = true on any good-faith CORRUPTED flag, closing the re-flag window immediately.

Support

FAQs

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

Give us feedback!