freecoding.school100% FREE · NO SIGNUP
The EVM CoreISSUE #41 of 48

pausable · emergency stop · circuit breakers

SoliaVSThe Reentrancy Reaper
Solia saysA pausable contract gates every state-changing function on a `paused` flag, letting the team freeze the system mid-attack while honest withdrawals stay open.

Pausable is an emergency stop: a single boolean (paused) that, when true, causes every guarded function to revert. The pause power is locked to a PAUSER role. Done right, only state-mutating functions get the modifier — read functions stay live, and a special emergencyWithdraw often stays open even when paused.

Pausable is the simplest circuit breaker, and the right one for incident response. More sophisticated variants add automatic triggers (TVL drop > X% → auto-pause). The demo runs three transfers across paused/unpaused states.

Power-ups you unlock

The Reentrancy Reaper attacks — common mistakes

Boss battleBuild a transfer guarded by `whenNotPaused` and run three calls across paused/unpaused states.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
let paused = false;
const whenNotPaused = (fn) => (...a) => { if(paused) throw new Error('EnforcedPause'); return fn(...a); };
const transfer = whenNotPaused((amt) => 'transferred ' + amt);
const log = [];
log.push('paused=' + paused + ' transfer(10) → ' + transfer(10));
paused = true;
try { transfer(20); } catch(e){ log.push('paused=' + paused + ' transfer(20) → REVERT (' + e.message + ')'); }
paused = false;
log.push('paused=' + paused + ' transfer(30) → ' + transfer(30));
log.push('');
log.push('only mutators are guarded; read functions and emergencyWithdraw stay open');
document.getElementById('o').textContent = log.join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Access Control · Ownable · Roles · AccessmanagerCommit-Reveal · Hiding Intent ›