MockConfidencePoolModerator.flag has no access control and as a result, any address can flag any wired pool's outcome and name itself the good-faith attacker, redirecting the entire pool balance to itselfflag (and its wrappers flagSurvived, flagCorruptedGoodFaith, flagCorruptedBadFaith) have no caller restriction whatsoever — msg.sender is only used for the event, never checked. Any address, including an attacker who has actually broken the agreement, can call flagCorruptedGoodFaith(pool, attacker) naming themselves (or an accomplice) as attacker, provided the underlying registry is already CORRUPTED (the only real gate is inside ConfidencePool.flagOutcome, which just checks registry state, not caller legitimacy).
The docstring correctly warns this is testnet-only and must not be deployed to mainnet, and ConfidencePool itself still enforces that only outcomeModerator may call flagOutcome — so the vulnerability only manifests if this mock is ever wired up as a pool's (or the factory's defaultOutcomeModerator's) actual moderator address in a real deployment. That is exactly the kind of mistake that happens via a stale deployment script, copy-pasted config, or a staging/production address mix-up, and the consequence if it does happen is total: whoever calls it first after CORRUPTED is observed drains the entire pool (corruptedReserve = snapshotTotalStaked + snapshotTotalBonus) via claimAttackerBounty, ahead of the legitimate whitehat.
A comment is not an enforcement mechanism — nothing in the code itself prevents this contract's address from ending up in outcomeModerator on a live network
Likelihood:
Low as a spontaneous on-chain event (requires a deployment/config error to wire this contract in as a real moderator) but non-trivial in practice — config mistakes involving mock/testnet artifacts leaking into production are a common real-world failure mode, and the blast radius here is total pool drain, not degraded functionality.
Impact:
ICritical if the precondition occurs. 100% of a pool's staked funds + bonus are diverted to an attacker-chosen address instead of the legitimate whitehat/attacker.
This POC shows the vulnerabilty
Since this contract is explicitly testnet-only, add an on-chain guard so a mainnet deployment fails hard instead of relying on a comment:
Extend the chainid check to cover any other chain IDs the protocol treats as production. Additionally, consider keeping this contract out of any deployment script / address-book path that could feed defaultOutcomeModerator or a pool's outcomeModerator, and add a factory-side or deployment-CI check that rejects known mock addresses in that role.
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.