DESIGN §9 justifies the "no observed risk → no bonus" rule as fair by coupling two events: "a staker only forfeits the exit option once risk has actually materialized, which is exactly when they begin earning the risk premium." Under that promise a locked-in staker is, by construction, already earning the premium.
The code decouples them. Exit dies on LIVE registry state — withdraw() reverts WithdrawsDisabled the instant the registry is UNDER_ATTACK, even while riskWindowStart == 0 (:293-300). But the premium is earned only via a SEPARATE one-way latch — _bonusShare pays zero while riskWindowStart == 0 (:699), and that latch is sealed only by a state-mutating observation (pokeRiskWindow/stake/contributeBonus) landing during the active-risk interval. So a staker can be locked (exit dead) yet earning nothing, the exact state §9 says cannot exist. The trap is that the intuitive defense fails twice: a staker who sees UNDER_ATTACK and calls withdraw() (a) reverts, and (b) the _observePoolState() seal inside withdraw is rolled back with the revert — so it neither exits nor seals. Only the non-obvious pokeRiskWindow() seals it, and the beneficiary of the un-sealed window is the conflicted sponsor (recoveryAddress), economically incentivized not to poke.
Likelihood:
The agreement enters an active-risk state (UNDER_ATTACK / PROMOTION_REQUESTED) and later resolves SURVIVED — normal operation.
No party calls pokeRiskWindow/stake/contributeBonus during that interval, so riskWindowStart stays 0 — plausible on a thin pool, a fast transition, or when the only sophisticated actor is the conflicted sponsor who benefits from the window staying unsealed.
Impact:
The honest staker was locked (bore real, involuntary at-risk time) yet receives 0 bonus — 100% of the reward they earned is redirected to the sponsor's recoveryAddress. Loss = the full contributed bonus pool.
A locked staker can self-heal by calling pokeRiskWindow() themselves during the active-risk interval, so the permanent loss requires that free permissionless step to be missed by everyone. This is why the finding is filed as Low (contested Medium): the loss is self-preventable, but (a) §9's stated coupling is factually false, (b) the intuitive defense (withdraw) both fails and fails-to-seal, and (c) the beneficiary is the conflicted sponsor — so "just poke" is neither obvious nor incentive-aligned.
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.