recoveryAddress is the destination for all CORRUPTED sweeps and unclaimed bonuses. It is set at pool initialization and can be updated by the pool owner (sponsor) at any time via setRecoveryAddress(). All three sweep functions claimCorrupted(), sweepUnclaimedCorrupted(), and sweepUnclaimedBonus() read recoveryAddress live at execution time rather than from a snapshot taken at outcome resolution.
setRecoveryAddress() has no guard on outcome or claimsStarted, meaning the sponsor can change the sweep destination after the moderator has flagged the outcome and before any sweep executes:
Likelihood:
A sponsor who disagrees with a bad-faith CORRUPTED determination has a direct financial incentive to act. The transaction costs only a single setRecoveryAddress call before anyone sweeps.
The window is permissionlessly triggerable; any party can call claimCorrupted(), so the sponsor must front-run. On chains with a public mempool, this is straightforward.
Impact:
In the bad-faith CORRUPTED path, the sponsor can silently redirect the entire pool balance (all staker principal + bonus) to an arbitrary address after the moderator's decision, since stakers have no claim rights in this path and cannot prevent the sweep.
Post-resolution sweepUnclaimedBonus() in SURVIVED/EXPIRED paths is also re-routable, allowing the sponsor to redirect excess bonus that would otherwise go to the intended protocol recovery wallet.
The scenario assumes the sponsor disagrees with a bad-faith CORRUPTED outcome and wants the pool balance sent elsewhere. Because setRecoveryAddress() has no outcome check, the sponsor can update it at any time after flagOutcome() and before anyone triggers the sweep. On a chain with a public mempool the sponsor can watch for the OutcomeFlagged event and submit setRecoveryAddress() in the same or next block before any sweep transaction lands.
Lock recoveryAddress once the outcome has been set by adding an outcome state guard:
An alternative is to snapshot recoveryAddress into a storage variable at flagOutcome() time (analogous to snapshotTotalStaked) and have all sweep functions reference the snapshot rather than the live value.
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.