The setPoolScope function allows the pool owner to update the list of covered contracts before the scope is locked. The function correctly calls _observePoolState() to check and update the scopeLocked flag. However, the check if (scopeLocked) revert ScopePostLockImmutable() occurs after the call to _observePoolState().
A pool owner can call setPoolScope with an empty array []. This call will pass the initial scopeLocked check, but the subsequent internal call to _replaceScope will revert because an empty scope is disallowed. Crucially, the call to _observePoolState() will have already executed. If the underlying agreement became active in the meantime, this will set scopeLocked to true. From this point forward, any legitimate attempt to set the scope will be permanently blocked, bricking the pool's configuration.
Likelihood: Low
Reason 1
This scenario occurs when the pool owner calls setPoolScope with an empty array of accounts.
Reason 2
This action must be taken during the specific window where the scope is not yet locked, but the underlying agreement has transitioned to an active state.
Impact: High
Impact 1
The setPoolScope function becomes permanently unusable for the affected pool.
Impact 2
If the pool was created with an incorrect scope, the owner loses the ability to correct it, rendering the pool useless and potentially trapping any contributed bonus funds.
Move the if (scopeLocked) check to occur before calling _observePoolState(). This ensures that a call that is destined to fail cannot change the scopeLocked state.
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.