setRecoveryAddress Has No outcome == UNRESOLVED Guard — Owner Can Atomically Redirect CORRUPTED Full-Pool SweepSeverity: Low
In ConfidencePool.sol:setRecoveryAddress, the function is onlyOwner with no outcome check, no timelock, and no two-step change:
All post-resolution sweep functions read recoveryAddress live at transfer time — ConfidencePool.sol:claimCorrupted, ConfidencePool.sol:sweepUnclaimedCorrupted, ConfidencePool.sol:sweepUnclaimedBonus. recoveryAddress is not frozen at resolution. The owner can change recoveryAddress at any moment, including after a CORRUPTED outcome is flagged but before the sweep is called, atomically bundling setRecoveryAddress(newDest) → claimCorrupted() in one transaction to redirect the full-pool sweep before any staker or observer reacts.
Per DESIGN.md, recoveryAddress is the sponsor-controlled CORRUPTED sweep destination, and the sponsor is the economic beneficiary of excess/sweep value — so this is not an unprivileged-attacker extraction. It is a trust-boundary issue: a staker verifying pool parameters at deposit time (DESIGN: "All staker-relevant state is on-chain; stakers should verify pool parameters before depositing") can rely on recoveryAddress only up to the resolution instant, not beyond it.
Contract: ConfidencePool.sol
Function: setRecoveryAddress()
No third-party loss beyond the sponsor's own value. Stakers lose the ability to predict, at stake time, where residual/sweep value will land if the pool goes CORRUPTED — the binding audit-trail destination is mutable post-deposit and post-flag. Principle of least surprise is violated. The named good-faith attacker (whose bounty destination recoveryAddress only matters when the bounty is unclaimed) is likewise affected when the sponsor changes recoveryAddress mid-claim-window.
Likelihood: Low. Requires the sponsor (a single trusted actor) to act adversarially against their own pool — outside the strict adversarial model (DESIGN) but within the sponsor trust surface (DESIGN) — or to be a compromised key.
Freeze recoveryAddress at first resolution by snapshotting it:
and read resolutionRecoveryAddress in all post-resolution sweep paths. Alternatively, gate the setter:
A two-step address change with a 48-hour accept window adds further defense-in-depth and gives stakers a final verification opportunity.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
View preliminary resultsAppeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.