When the pool owner calls setPoolScope to update the BattleChain accounts the pool monitors, _replaceScope first iterates the entire existing scope array to clear isAccountInScope for every old account, then applies the new scope. This is a valid wholesale-replacement pattern — the owner controls the input scope and is trusted to keep it reasonably sized.
The loop that clears the old scope iterates over _scopeAccounts with no upper bound on its length. Each iteration executes an SSTORE (isAccountInScope[old[i]] = false). If a prior scope contained thousands of accounts, the cumulative gas cost of the clearing loop alone can exceed the block gas limit or become economically prohibitive, permanently preventing any subsequent scope update.
Likelihood:
Owner sets a scope with thousands of accounts in an earlier setPoolScope or initialize call, and any subsequent scope update must clear every one of those entries before applying the new scope
The clearing loop gas cost scales linearly with the old scope size with no protocol-enforced cap, so at sufficient size the call exceeds block gas or becomes economically prohibitive.
Impact:
Owner cannot update the pool's BattleChain account scope, setPoolScope permanently reverts on any attempt
No fund movement is affected (scope is informational only), but a documented owner capability is permanently disabled
The test below walks through the full lifecycle: the owner first sets a 3,000-account scope, then later attempts a small scope update. The gas cost of the second setPoolScope call is dominated by the L755-757 clearing loop, which must SSTORE-clear isAccountInScope for all 3,000 old accounts before it can write the 10 new ones. Gas scales linearly with old scope size; at 30,000 accounts the clearing alone exceeds a 30M block gas limit.
Remove the old-scope clearing loop. Stale isAccountInScope entries are harmless — the second loop already sets the new scope's accounts to true, and scope is never read by any fund-moving logic. The _scopeAccounts array is already overwritten by delete + push.
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.