Security & Audits
Emergency Escape Hatch
The 30-day permissionless refund: when it opens, what it does, and what it cannot do.
emergencyRefund(poolId) is the protocol's dead-man switch. It exists because a prediction market that cannot be resolved is worse than one that is voided: void returns everyone's principal, whereas a frozen market returns nothing to anyone.
Preconditions
- The market status must be Open (a settled or already-cancelled market reverts)
- block.timestamp >= endTime + 30 days
- No privilege required — any address, including one with no position
What it does
function emergencyRefund(uint256 poolId) external {
Pool storage pool = _pools[poolId];
if (pool.status != PoolStatus.Open) revert PoolNotOpen(poolId);
uint256 eligibleAt = uint256(pool.endTime) + EMERGENCY_REFUND_DELAY;
if (block.timestamp < eligibleAt) revert EmergencyTooEarly(eligibleAt);
_cancel(poolId); // rake escrow zeroed, nothing released
emit EmergencyRefund(poolId, msg.sender, block.timestamp);
}After the void, each participant calls claimRefund and receives 100% of their gross stake, fee included. Nobody can claim twice; the refund flag is per wallet per market.
What it cannot do
- It cannot be used to steal: it pays every position back to its owner, never to the caller
- It cannot touch a settled market — the result stands
- It cannot release platform fees: a cancelled market releases zero rake
- It cannot be triggered early, even by the owner, without waiting the full 30 days
Economic side effect worth knowing
If the operator stays silent for 30 days, a position on the losing side can recover 100% of its stake. That removes the winner's profit for that market. Settling promptly is therefore part of the operator's obligation, not an optional courtesy.