contributeBonus is permissionless and there is no refund path. The bonus is only ever paid to stakers via the k=2 split or swept to recoveryAddress. If a pool draws no stakers and simply expires (organic lack of interest), the entire bonus routes to the sponsor-controlled recoveryAddress, never back to an independent contributor.
Concretely, with riskWindowStart == 0 (no risk ever observed) the sweepUnclaimedBonus reserve logic reserves nothing for the bonus (totalEligibleStake == 0, and the riskWindowStart != 0 branch is skipped), so 100% of the bonus is sweepable to recoveryAddress. Because the sponsor both seeds the bonus and controls recoveryAddress, the sponsor is made whole while an unrelated contributor is not.
Likelihood: Low — pools with a bonus but no staking interest are plausible but not the common case, and the acute harm requires a bonus contributor who is not the sponsor.
Impact: Low — bounded to the contributor's own funds. docs/DESIGN.md (Actors) states contributors gain "no rights," but does not document that a staker-less expiry redirects their principal to the sponsor rather than stranding or refunding it.
An independent user contributes bonus. No one stakes. After expiry the pool resolves and the bonus is swept to the sponsor’s recoveryAddress. The contributor loses the full amount.
Document explicitly in DESIGN §10 that bonus contributions are unconditionally forfeit to recoveryAddress if the pool resolves with no eligible stakers, so contributors price it in. If unintended, gate a refund on snapshotTotalStaked == 0 at resolution:
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.