Once a pool observes its Agreement outside pre-attack staging, scopeLocked is intended to make the pool-local account list the binding coverage commitment. docs/DESIGN.md §8 explicitly states that after the sponsor narrows an Agreement, "the pool's own commitment to stakers remains the binding source of truth"; protocol-readme.md likewise states that narrowing scope does not alter what the pool covers. Consequently, a real corruption involving an account that remains in the locked pool scope must remain classifiable as CORRUPTED, so the pool can pay the named whitehat instead of returning the funds to stakers.
ConfidencePool stores the locked account list separately from the Agreement address, but every outcome gate reads only the Agreement address fixed during initialization. The canonical upstream contracts allow an Agreement owner to remove an account after its commitment period, which clears the account's registry binding, and then register the account under another Agreement. The pool retains the removed account in its locked scope, but it never follows that account's current Agreement binding.
The sponsor can therefore move the insured account to a replacement Agreement, put both Agreements through their normal DAO-approved lifecycle, and report a genuine corruption on the replacement Agreement immediately before the old Agreement completes promotion. The pool moderator cannot flag CORRUPTED because the old Agreement is only PROMOTION_REQUESTED; one second later the old Agreement becomes terminal PRODUCTION, after which even the registry moderator's instantCorrupt(oldAgreement) call reverts. At pool expiry, claimExpired() reads that stale PRODUCTION state and irreversibly resolves the pool as SURVIVED despite the locked-scope account having been corrupted during the covered risk period.
Likelihood:
Medium. The canonical flow becomes reachable after the original Agreement's commitment period: the sponsor adds a companion account, removes the insured account, registers it under a replacement Agreement, and receives the registry DAO's normal approval for attack mode. The fork PoC executes every transition against deployed BattleChain testnet contracts without direct state writes.
Exploitation requires the sponsor, which is also the canonical Agreement owner and attack moderator, to schedule the replacement Agreement's corruption in the final pre-production block of the old Agreement's three-day promotion delay. The sponsor controls both promotion and corruption reporting and has a direct incentive to recover its otherwise-forfeited stake, but the narrow timing and DAO-approval prerequisites keep likelihood below High.
Impact:
High. A genuine corruption of a locked-scope account is irreversibly misclassified as SURVIVED, defeating the pool's core slashing and whitehat-bounty mechanism for the entire pool balance. Pool size is not capped by this logic.
In the PoC, the intended CORRUPTED settlement pays the whitehat all 200 tokens. The vulnerable path instead pays the sponsor 133.333333333333333333 tokens, including recovery of its 100-token principal and 33.333333333333333333 bonus, pays the other staker 66.666666666666666666 tokens, and pays the whitehat zero.
Add the following test as test/fork/CodexGpt5V5_20260712_SubmissionAgreementRebinding.fork.t.sol. It pins the public BattleChain testnet at block 16,000, uses a deployed active Agreement and its real owner/moderator roles, and deploys only the in-scope pool plus a mock stake token locally.
Run it with the RPC documented by the project:
Observed output:
Outcome authorization must follow the current registry bindings of the accounts in the locked pool scope, rather than treating the initialization-time Agreement as the only possible source of corruption. The moderator may use that signal to make the existing off-chain in-scope judgement. Permissionless expiry resolution should defer instead of auto-resolving SURVIVED while any current Agreement bound to a locked-scope account is CORRUPTED.
One possible implementation is:
Add a regression test covering locked scope -> Agreement removal -> replacement binding -> replacement CORRUPTED -> old Agreement PRODUCTION -> expiry resolution. A stronger upstream defense is to prevent removal or rebinding of an account while a live pool still commits to it, but the in-scope pool must remain safe even when the documented Agreement-narrowing flow occurs.
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.