A Confidence Pool is intended to let its sponsor replace the pool-local account scope only while the Agreement remains in NOT_DEPLOYED or NEW_DEPLOYMENT. The first pool interaction that observes any later registry state, including ATTACK_REQUESTED, must permanently lock that scope so existing stakers continue underwriting the account list they accepted.
The lock does not persist when ATTACK_REQUESTED is first observed through either public lock path. _observePoolState() sets scopeLocked = true, but setPoolScope() then reverts because the latch is true, while pokeRiskWindow() reverts because ATTACK_REQUESTED sets neither risk-window marker. EVM rollback restores scopeLocked to false in both cases.
The deployed AttackRegistry has a normal soft-rejection path that returns the Agreement from ATTACK_REQUESTED to NOT_DEPLOYED. A pool sponsor that retains the Agreement's ordinary attack-request role can pause stake and bonus inflows, request attack mode, let both observation paths roll back, receive a normal DAO soft rejection, and then replace a funded pool's account scope. The sponsor can re-request the same Agreement and expose the existing pool to a different account. In the fork PoC, corruption of that replacement account forfeits the entire 200-token pool even though the stakers originally accepted only the control account.
Likelihood:
A funded pool whose sponsor retains the Agreement attack-request role reaches ATTACK_REQUESTED, the DAO normally soft-rejects that request, and the sponsor replaces scope before requesting and receiving approval again. These are canonical deployed registry transitions rather than a mock registry rewind or a malicious registry repoint.
The sponsor controls both pause() and setPoolScope(), so pausing removes successful stake() and contributeBonus() calls that could otherwise persist the latch. Existing stakers retain a visible response window, but their only reliable path is full withdrawal, which abandons the pool and forfeits any bonus claim. These prerequisites and visibility support Medium likelihood rather than High.
Impact:
Existing stakers can lose the pool's entire principal and bonus to a good-faith whitehat or the configured recovery address because an account they never agreed to underwrite replaces the original pool-local commitment.
The fork differential moves a pool containing 150 tokens of principal and 50 tokens of bonus from a surviving account to a genuinely corrupted replacement account. The mutated pool pays all 200 tokens to the whitehat, while the unchanged control returns 133.333333333333333333 tokens to the sponsor and 66.666666666666666666 tokens to the honest staker.
Add this test as test/fork/CodexGpt5V6_20260712_LiveRejectedRequestScopeMutation.fork.t.sol in the supplied repository and run it against the documented BattleChain testnet RPC.
Run:
Observed output:
The most robust fix is to freeze scope when the first stake creates staker reliance, just as the same call already freezes expiry. This removes any dependency on a later registry observation and prevents a rejected request from reopening the meaning of an already-funded pool.
When retaining the current post-staging policy is required, provide a dedicated non-reverting scope-observation path. At minimum, pokeRiskWindow() must return successfully when _observePoolState() newly locks scope in ATTACK_REQUESTED, even though no risk-window marker was set. Add a regression covering funded pool -> ATTACK_REQUESTED -> soft rejection -> attempted scope replacement -> re-request.
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.