Withdrawals become permanently unavailable once the agreement reaches UNDER_ATTACK; at that same point, existing stakers should begin earning the risk premium. Ordinary pool interactions are intended to lazily persist riskWindowStart when they observe this state.
withdraw() first calls _observePoolState(), which sets riskWindowStart, but then necessarily reverts with WithdrawsDisabled() because that marker is now nonzero. The revert rolls the marker back. When the registry reaches PRODUCTION before another successful observer call, resolution records no observed risk, _bonusShare() returns zero, and the entire bonus can be swept to recoveryAddress. Consequently, the same interaction that denies a staker their exit also fails to begin their risk-premium accounting.
Likelihood:
Occurs when a staker's rejected withdrawal is the first pool transaction to observe UNDER_ATTACK or PROMOTION_REQUESTED.
Produces loss when the upstream registry becomes terminal before another successful call to pokeRiskWindow(), stake(), or contributeBonus() persists the active-risk observation.
Impact:
Stakers lose their complete share of the sponsor-funded bonus despite being denied withdrawal and bearing the active-risk interval.
The unallocated bonus is transferred to the sponsor-controlled recoveryAddress, creating an incentive not to correct the missing marker before terminal resolution.
The blocked withdrawal path must complete successfully so the one-way observation can persist. Emit an event for the rejected request rather than reverting after state mutation.
Impact - Low The staker keeps their principal, so what is lost is the premium they were accruing while locked, and it ends up at the sponsor's recoveryAddress. DESIGN.md #9 justifies the whole no-observed-risk rule by pairing two events, saying a staker forfeits the exit exactly when the premium starts. One call does the first and undoes the second. Likelihood - Low Any staker can cure this for free with pokeRiskWindow, which succeeds in the same state the withdrawal failed in. A permanent loss therefore needs the whole cohort to miss that step, and the trap is that the obvious move is the one that fails. A short active-risk interval can also close before anyone gets a block in which to poke. DESIGN.md #6 explains an unsealed window as nobody having interacted with the pool, which is exactly what did not happen here.
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.