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.
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.