_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.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.