Deposits are allowed in UNDER_ATTACK:
UNDER_ATTACK is intentionally not blocked. But if the risk window starts and ends with the same timestamp, _bonusShare() uses amount-weighted fallback:
A user can stake during UNDER_ATTACK in the same block/timestamp where the pool later observes terminal resolution. Instead of receiving near-zero bonus, they receive an amount-weighted share.
This contradicts the comment saying UNDER_ATTACK deposits “earn ~zero k=2 bonus.” They earn ~zero only if there is positive elapsed time between riskWindowStart and riskWindowEnd. If both are the same timestamp, the fallback gives them a full amount-weighted bonus share.
Unfair bonus distribution; dilution of honest stakers’ rewards; contradicts stated design guarantee.
A late staker can capture a full proportional share of the bonus pool, diluting the rewards of earlier stakers and contradicting the design intention that UNDER_ATTACK deposits earn ~zero bonus.
When a user stakes during UNDER_ATTACK in the same block as the registry transitions to a terminal state, both riskWindowStart and riskWindowEnd receive identical timestamps. This causes globalScore to equal 0, triggering the amount‑weighted fallback instead of the intended near‑zero k=2 bonus.
Because riskWindowStart is recorded lazily on pool interaction, not necessarily at the actual registry transition time, a late staker can be the first interaction that observes UNDER_ATTACK.
Registry may have been UNDER_ATTACK before,
but the pool only records riskWindowStart when someone interacts.The pool measures risk duration from the first pool observation of UNDER_ATTACK, not from the registry’s actual UNDER_ATTACK transition. If the first observation occurs in the same timestamp as resolution, the time-weighted score collapses to zero and the fallback distributes the bonus by amount.
This test demonstrates that a staker who deposits during UNDER_ATTACK in the same block where the risk window ends receives a full proportional share of the bonus pool, contradicting the intended “~zero bonus” design.
Registry is UNDER_ATTACK.
Attacker stakes a large amount.
This first pool interaction sets riskWindowStart = block.timestamp.
Registry reaches terminal state in the same block/timestamp, or moderator flags outcome in same timestamp after terminal state.
_markRiskWindowEnd() sets riskWindowEnd = same timestamp.
globalScore == 0.
Bonus distribution falls back to amount-weighted.
Late staker captures bonus despite taking no meaningful time risk.
Best fix: disallow staking once UNDER_ATTACK begins.
Alternative: when globalScore == 0, distribute only to stake that existed before riskWindowStart, or return zero bonus instead of amount-weighted fallback.
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.