_assertDepositsAllowed deliberately allows deposits during UNDER_ATTACK while blocking them during PROMOTION_REQUESTED, PRODUCTION, and CORRUPTED. The rationale is that UNDER_ATTACK deposits are voluntary risk capital where the k=2 weighting crushes bonus to ~zero, making late-join unattractive without needing to block it.
However, three mechanics combine to create a trap:
Withdrawals are permanently disabled once riskWindowStart != 0 (set when UNDER_ATTACK is first observed). A staker depositing during UNDER_ATTACK can never exit only resolution returns their funds.
The k=2 bonus is ~zero because the staker's effective entry time is max(block.timestamp, riskWindowStart) ≈ now, so ( (T - \text{entry})^2 \approx 0 ) for any near-term resolution.
Full principal loss on CORRUPTED: if the agreement is breached and the moderator flags CORRUPTED, the staker's entire deposit sweeps to recoveryAddress (bad-faith) or the named attacker (good-faith).
The staker bears full downside risk with negligible upside. The contract provides no warning event or other mechanism for frontends to surface this risk to users before they stake.
Likelihood: Low
UNDER_ATTACK is a normal operating mode that typically lasts for extended periods; rapid transitions to terminal states are unlikely
Stakers can read riskWindowStart (public getter) and the live registry state on-chain before calling stake()
The behavior is documented in DESIGN.md §3 as an intentional design decision
Only affects stakers who do not check on-chain state before depositing
Impact:
Immediate CORRUPTED after deposit → staker loses 100% of principal
Immediate SURVIVED after deposit → staker recovers principal but earns ~zero bonus (capital was locked for no upside)
Principal lock duration is unbounded while registry remains in UNDER_ATTACK
The PoC demonstrates the worst-case scenario: a staker deposits during UNDER_ATTACK, the registry immediately transitions to CORRUPTED, and the staker's entire principal is swept to recoveryAddress with no bonus.
A companion test in test/poc/PoC_UnderAttackDepositTrap.t.sol also verifies that with multiple stakers, the late UNDER_ATTACK entrant's bonus is crushed by the k=2 formula compared to an early staker who bore more at-risk time.
Full runnable PoC at test/poc/PoC_UnderAttackDepositTrap.t.sol — 4 tests, all pass.
Emit a warning event when a stake occurs during UNDER_ATTACK, giving frontends and indexers a standard mechanism to surface the elevated risk:
This preserves the intentional design (UNDER_ATTACK deposits remain possible), adds negligible gas overhead, and enables frontends to display a clear warning: "This pool is in an active-risk state. Your deposit will be locked until resolution, earns negligible bonus, and may be forfeited if the agreement is breached."
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.