Expected behavior: the first pool interaction that observes a registry state outside NOT_DEPLOYED / NEW_DEPLOYMENT should persistently lock the pool scope. pokeRiskWindow is the permissionless observation hook for pool-local registry markers.
Issue: in ATTACK_REQUESTED, _observePoolState sets scopeLocked = true, but pokeRiskWindow then reverts with RiskWindowNotReached because no active-risk or terminal marker was sealed. The revert rolls back the scope lock, so a later registry rewind to NOT_DEPLOYED lets the owner replace the funded scope.
This is not direct fund loss. It is an incorrect one-way state transition: the permissionless hook observes ATTACK_REQUESTED but cannot persist the scope lock it creates.
Likelihood:
Medium. ATTACK_REQUESTED is a normal registry state, and attack requests can be rejected back to NOT_DEPLOYED.
Any caller can reach the failed observation through pokeRiskWindow.
Impact:
Low. Funds are not directly lost, but the pool remains scope-mutable after an attempted ATTACK_REQUESTED observation. A funded pool can later have its covered scope replaced if no other successful pool call persisted the lock.
The native Foundry PoC stakes into the default scope, observes ATTACK_REQUESTED, then rewinds the registry and replaces scope:
Test location:
Targeted command:
Observed output:
Make pokeRiskWindow succeed when _observePoolState persists any one-way observation, including scopeLocked.
One implementation is to have _observePoolState return whether it locked scope, opened the risk window, or sealed the terminal timestamp.
Impact - Low Nothing moves when the scope is swapped, and the state afterward is pre-attack, so any staker who notices can withdraw in full. _replaceScope emits ScopeUpdated, which puts the change on-chain where it can be seen. Real loss needs a restarted attack cycle that breaches one of the substituted accounts with the original staker still in the pool, at which point their principal funds a CORRUPTED payout for coverage they never chose. Likelihood - Medium The step the sponsor cannot force is the moderator rejecting the attack request, though rejections are an ordinary registry operation. The rest they can arrange. Neither observation path can seal the lock in this state, and pausing the pool shuts the deposit routes, leaving only a full-exit withdraw to do it. So reaching the mutable-scope condition is not hard; what holds the severity down is how much has to go wrong afterward for anyone to actually lose money.
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.