The pool's pause flag gates only stake() and contributeBonus(). Withdrawals, outcome flagging, risk-window observation, claims, recovery sweeps, and owner configuration remain callable while paused() == true.
This is an intentional inflow-only policy according to the repository's existing unit tests, which state that pause must not let the owner trap stakers. The name pause(), however, does not communicate that narrow scope, and the contract has no separate emergency mode capable of stopping resolution or treasury-directed egress. During a registry or recipient incident, operators can pause new deposits but cannot prevent the post-grace, permissionless auto-CORRUPTED path from finalizing and sending the entire pool to recoveryAddress.
The custom pause modifiers are wired only to the two inbound token functions:
The sharpest path occurs when the registry is CORRUPTED and an active risk window was observed. Once expiry + MODERATOR_CORRUPTED_GRACE is reached, any address can call claimExpired() while the pool remains paused:
Because bad-faith claimCorrupted() is also ungated, the next caller can transfer the entire pool balance to the current recovery recipient. Pausing therefore offers no response window for investigating a corrupted registry report, a compromised recovery address, or an accounting incident that affects outbound transfers.
The same asymmetry applies more broadly: flagOutcome(), claimSurvived(), claimAttackerBounty(), sweepUnclaimedCorrupted(), sweepUnclaimedBonus(), pokeRiskWindow(), setRecoveryAddress(), setExpiry(), and setPoolScope() do not inspect pause state. Some of these exemptions are defensible individually, especially allowing users to withdraw before risk begins, but together they mean the control is not a general emergency brake.
Likelihood:
The behavior requires no exploit or unusual token. It occurs deterministically whenever the pool is paused and one of the ungated functions is called.
The highest-impact scenario requires an incident during or after a CORRUPTED lifecycle and the 180-day moderator grace period to have elapsed.
Existing tests explicitly encode the inflow-only design, reducing the chance that maintainers misunderstand it, but external operators and integrators can still reasonably interpret a generic paused() flag more broadly.
Impact:
Pause cannot stop terminal resolution, claims, or recovery sweeps, so it cannot contain an incident affecting the registry, moderator decision, recovery destination, or outbound accounting.
The PoC shows the full staked principal plus bonus leaving the contract while paused() stays true.
Blindly extending the existing pause to withdrawals would introduce a different risk: the owner could trap stakers before the risk window begins. The mitigation must preserve an explicit exit policy.
Create test/audit/CP033DepositOnlyPoolPause.t.sol with the following contents:
Run the PoC from the repository root:
Execute forge test --offline --match-path test/audit/CP033DepositOnlyPoolPause.t.sol -vv.
Confirm that the test passes. Both deposit-side calls revert with PoolPaused, but after the moderator grace period claimExpired() resolves the paused pool as CORRUPTED and claimCorrupted() transfers all 125 tokens to recovery without unpausing.
Make the existing policy explicit and add a distinct, narrowly governed emergency-resolution mode. Keep ordinary inflow pause from blocking pre-risk user exits, but let a guardian temporarily stop new resolution and pool-wide egress during a verified incident. The emergency mode should be time-bounded or controlled by a multisig/timelock so it cannot become a permanent seizure mechanism.
Apply the same emergency modifier to other pool-wide resolution and recovery sweeps according to a documented matrix. Decide separately whether already-finalized individual claims should remain available; continuing user claims may be safer than freezing them. Rename or document the current pause() as pauseInflows() at the interface and event level so monitoring systems do not mistake paused() == true for a full contract freeze.
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.