The initialize function of the cloned ConfidencePool does not verify whether the provided agreement_ belongs to or is consistent with the specified safeHarborRegistry_. An attacker can initialize a pool with a malicious, custom-deployed registry that returns arbitrary state to hijack pool outcomes.
The factory contract deploys non-upgradeable clones of ConfidencePool and calls their initialize function. This function takes agreement_ and safeHarborRegistry_ as separate arguments.
The issue is that while initialize checks whether the agreement is registered as valid under the registry via isAgreementValid(agreement_), it does not enforce any strict architectural binding between them. An attacker can deploy a fake registry contract that returns true for isAgreementValid but provides an attacker-controlled mock AttackRegistry. Because the pool reads live state via safeHarborRegistry.getAttackRegistry(), initializing a clone with an inconsistent/mock registry allows the attacker to completely control state transitions (such as fabricating a false CORRUPTED state to sweep honest stakers' principal).
Likelihood:
Occurs when a pool is created, either via direct interaction with the implementation proxy or if the factory owner incorrectly configures the registry parameters.
Allows deployment of deceptive "honeypot" pools that mirror legitimate agreements but are backed by a malicious state machine.
Impact:
Direct loss of principal for honest depositors who stake in the mismatched pool.
Arbitrary outcome manipulation (unauthorized sweeps of both principal and bonus).
Validate the registry relationship or retrieve the canonical registry directly from a trusted factory or global contract mapping rather than allowing arbitrary addresses to be set during clone initialization.
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.