Skip to Content
Quorum contracts are live on Base Sepolia. Mainnet ships after external audit. Do not send real funds.
SecurityEmergency Pause

Emergency pause and incident response

Quorum contracts do not currently implement Pausable (per audit M-04). Mainnet remediation will add a PausableUpgradeable mixin or equivalent guard. Until then, incident response relies on owner-gated parameter changes and off-chain coordination.

Current incident response surface

Pre-mainnet, the owner (Sepolia: single EOA, mainnet: Safe + Timelock) can:

ActionContractFunctionEffect
Stop new bounty creationForumExecutor(no surface — see planned remediation)n/a
Stop new chamber commitsChamberRegistrysetDealer(address(0))dealer-locked, no new commits
Stop new idea deploysIdeaFactorysetDeployer(address(0))factory-locked, no new deploys
Redirect treasuryBondingEscrow.setProtocolTreasurynew addressnext flush goes elsewhere
Change slash rateBondingEscrow.setProtocolSlashBpsnew value (0..3000)applies to next settlement
Re-point ForumExecutorBondingEscrow.setForumExecutornew contractsettle calls re-route

These are owner-gated and (on mainnet) timelock-delayed by 24h. A 24h delay is fine for operational changes but insufficient for active exploits — by design, that’s the incident-response window for the multisig to call cancel on a compromised proposal.

Planned mainnet emergency surface

Pre-mainnet remediation adds:

  • Pausable on BondingEscrow, ForumExecutor, FeeRouter, IdeaFactory.
  • A GUARDIAN_ROLE separate from owner that can pause without timelock delay.
  • A 7-day max pause duration (auto-unpause to prevent indefinite freeze).
  • A “soft pause” mode that blocks only state-mutating entry points, leaves view functions live.
// Planned addition to BondingEscrow (post-remediation): function pause() external onlyGuardian { _pause(); _pausedAt = block.timestamp; } function unpause() external onlyOwner { _unpause(); } modifier whenNotPausedOrExpired() { if (paused() && block.timestamp <= _pausedAt + MAX_PAUSE_DURATION) revert ContractPaused(); _; }

The Guardian role would be held by a hot-wallet rotation pool (3 independent operators) so a single compromised operator cannot brick the protocol indefinitely.

Incident classes

Class A — direct loss of funds (critical)

Examples:

  • Reentrancy enabling withdrawal of escrowed bounty.
  • Token-shape exploit (e.g. fee-on-transfer token bricking BondingEscrow.claim so a winner can drain via reverting their own claim — H-02 variant).
  • Owner key compromise with active draining.

Response:

  1. Guardian calls pause() on affected contracts (when available).
  2. Operator team convenes on Telegram / Discord war room within 1h.
  3. Postmortem draft within 24h.
  4. Fix deployed within 72h or pause extended (max 7 days).
  5. Public disclosure within 14 days.

Class B — sustained DoS

Examples:

  • H-03 1-wei AGAINST short-circuit (a finalize-front-runs everyone variant).
  • H-01 voters locked out of dispute rounds.
  • M-06 FeeRouter recipient blocking flush forever.

Response:

  1. Investigate and confirm the DoS pattern.
  2. If user funds are locked (not lost), notify users and plan migration.
  3. Deploy fix on Sepolia first, run E2E, then mainnet.
  4. Public postmortem within 14 days.

No emergency pause required for Class B issues — they degrade functionality but do not steal.

Class C — protocol parameter mis-use

Examples:

  • Owner key compromise without active draining (visible attempt to redirect treasury).
  • Mis-configured BPS on a new idea (sum != 10000 — actually caught by BpsMismatch revert).

Response:

  1. Multisig cancels the malicious timelock proposal within the 24h window.
  2. Rotate owner keys.
  3. Postmortem within 7 days.

Class D — operational degradation

Examples:

  • forum-API outage (fly.io machine down).
  • Relayer EOA out of ETH.
  • RPC provider degradation.

Response:

  1. Status page banner.
  2. Operator on-call resolves within SLA (4h business, 12h off-hours).
  3. Postmortem only for outages > 4h.

Not a protocol-level incident — does not affect on-chain state, only off-chain coordination.

Status page

A live status page will publish at https://status.quorum.sh (pending domain registration). It will show:

  • forum-API health (latency, error rate)
  • RPC provider health
  • Relayer wallet balance
  • Pending timelock proposals
  • Multisig signer activity in the last 24h
  • Open incidents

For now, the deployments  page in the repo is the canonical state.

Postmortem policy

Every Class A / B incident produces a public postmortem with:

  • Timeline (UTC).
  • Root cause (technical + organizational).
  • Impact: users affected, funds affected, downtime.
  • Resolution: what was fixed, when, how.
  • Prevention: changes to process, code, monitoring.
  • Acknowledgements: researchers credited, team members responsible.

Postmortems live in docs/postmortems/ in the repo. No private postmortems.

Last updated on