Normally, on a good-faith CORRUPTED resolution the moderator names the whitehat that responsibly disclosed the breach, and the entire pool (snapshotTotalStaked + snapshotTotalBonus) becomes that named attacker's bounty (DESIGN.md §12); claimAttackerBounty then pays whoever equals the stored attacker.
flagOutcome only checks attacker_ for zero / non-zero consistency with the outcome type and then assigns attacker = attacker_ with no validation against any on-chain identity. Because the good-faith CORRUPTED path makes the whole pool the named attacker's bounty, a moderator can name itself as the attacker and withdraw the entire pool to its own address, leaving recoveryAddress and any legitimate whitehat with nothing. This cannot be closed by a simple check: the BattleChain registry exposes no attacker/whitehat identity to validate against (AgreementInfo carries only attackModerator, timers, and corrupted/promoted flags — never who breached the agreement), so the moderator's off-chain judgement is the sole source of truth for naming the attacker.
Likelihood:
Occurs only when the caller is the onlyModerator address (a privileged, trusted role), and only on a genuinely CORRUPTED registry — the CORRUPTED outcome requires state == CORRUPTED (a real breach the moderator cannot fabricate), a state where the pool was already destined to a whitehat.
DESIGN.md §11 places a malicious moderator explicitly outside the adversarial model; a compromised moderator can distort resolution more directly regardless, so this is a documented trust surface rather than an externally-triggerable defect.
Impact:
A self-dealing moderator can transfer the entire pool (snapshotTotalStaked + snapshotTotalBonus) to its own address via claimAttackerBounty, so the legitimate whitehat and recoveryAddress receive nothing and stakers have no on-chain recourse.
This is strictly stronger than the bad-faith path (which routes the pool to the sponsor-controlled recoveryAddress, not the moderator): good-faith self-naming is a direct self-enrichment path that needs no collusion, widening the effective trust assumption from "trusted to resolve correctly" to "may pay the entire pool to its own address."
No code fix is strictly required under the stated trust model (DESIGN.md §11 excludes a malicious moderator), but to shrink the self-dealing surface, consider one of the following. Note the developers already guard exactly this concern on the trustless path: claimExpired's auto-CORRUPTED branch sets claimsStarted = true specifically so the moderator cannot override mechanical bad-faith CORRUPTED with good-faith attacker-naming — the concern is acknowledged in code and only accepted on the trusted flagOutcome path
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.