stake sets the one-way expiryLocked latch on its first call, permanently preventing the sponsor from calling setExpiry. Per docs/DESIGN.md §10 this protects staker reliance on expiry, which feeds the k=2 bonus formula as T on the EXPIRED path. contributeBonus accepts funds through the same _assertDepositsAllowed gate but does not set expiryLocked. As a result, while no stake has yet occurred, the sponsor can accept a bonus contribution and then freely extend or shorten expiry (down to the _MIN_EXPIRY_LEAD floor), changing how long the contributed funds are exposed and when the pool can resolve.
The latch's DESIGN rationale is framed entirely around the staker's T-weighting; contributors hold no T-position, so the protection was never extended to them. §10 does not state this asymmetry is intentional.
Likelihood: Low — requires a bonus-before-stake ordering and a sponsor motivated to reprice the timeline.
Impact: Low — no principal theft. The sponsor already holds strictly larger levers over bonus funds (pause on the deposit paths, bad-faith CORRUPTED sweep to their own recovery address). This is pure timeline manipulation of already-committed contributor funds.
An independent user contributes bonus first. The sponsor then changes the pool's expiry. This would not be possible if a staker had deposited first.
Mirror stake's latch, or document the asymmetry in DESIGN §10 the way §5/§9 close off other recurring false positives.
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.