ConfidencePoolFactory.createPool only validates the lower bound on expiry (must be at least 30 days from now) but does not validate the upper bound (expiry <= type(uint32).max). The pool's initialize function DOES check both bounds. This validation asymmetry creates a reachable input that passes the factory but fails initialize, directly triggering the orphaned-clone DoS described in Finding 1.
Likelihood:
Any agreement owner can pass expiry = type(uint32).max + 1 (or any value above 4294967295). The factory's only check (expiry >= now + 30 days) trivially passes for such large values.
This is a single-parameter input validation gap that directly compounds into Finding 1's permanent DoS.
Impact:
Enables the permanent bricking of pool creation for an agreement (see Finding 1).
Since expiry is a uint256 parameter, there is a large input space (any value from type(uint32).max + 1 to type(uint256).max) that triggers this path.
Run: forge test --match-contract Finding4_MissingExpiryUpperBound -vvv
Terminal Output:
To address the missing upper-bound expiry validation, we introduce an explicit type(uint32).max check within ConfidencePoolFactory.createPool. This ensures the factory enforces the same upper limit as the pool's initialize function, preventing oversized inputs from passing the factory logic only to revert and trigger clone orphaning.
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.