According to DESIGN.md
The sponsor can update scope freely while the registry is in
NOT_DEPLOYED/NEW_DEPLOYMENT
(pre-attack staging). Scope locks permanently on the first interaction observing any other state.
This claim is not entirely true. Not all pool functions that observe a different registry state can lock the scope permanently. Consider the following situation:
The registry transitioned from NOT_DEPLOYED to ATTACK_REQUESTED, but if pokeRiskWindow is called as the first interaction that observes pool state, it observes the changed state and locks the scope, but then reverts because no risk window was observed. Ultimately keeping the scope mutable. So later if the DAO rejects the attack proposal (via AttackRegistry.rejectAttackRequest) and changes the registry back to NOT_DEPLOYED the pool scope can still be changed by the owner.
Now comparing this to all other functions that observe the pool state downstream, always lock the scope. So in other cases even after the DAO rejects the attack proposal the scope cannot be altered. Such as stake(), withdraw() , setPoolScope() persist the same observation and therefore leave scopeLocked set even after the registry returns to a pre-attack state. It contradicts the documented invariant that scope locks permanently on the first interaction observing any state outside pre-attack staging.
There is a clear discrepancy, the same situation achieves different final outcomes in the above case.
The sponsor will retain the ability to alter a pool's coverage even after the pool has observed an ATTACK_REQUESTED state, contrary to the design commitment presented to stakers. Whether that first pool observation becomes durable depends on which permissionless or user-facing function is called first, producing inconsistent scope-finality breaking the intended "first non pre-attack observe interaction == permanent lock" design.
High because the state is reachable via permissionless flows.
pokeRiskWindow() performs the scope-locking observation in the same transaction as a validation that intentionally reverts for ATTACK_REQUESTED. The revert also undoes the scopeLocked write, so the one-way scope-lock invariant is not preserved.
Remove the revert logic in pokeRiskWindow. Instead use an emit to signify that Risk Window has not reached.
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.