Withdrawal Rate Limiter: Containing a Hack in Real Time
A global circuit breaker that caps how quickly funds leave the protocol. Choose a scenario, press Play, and watch the rate limiter work — or fail.
Scenario
Speed
2×
Choose a scenario and press ▶ Play to start the simulation.
Protocol Vault
$10.00M
Total Value Locked
Hourly limit$1.00M
Burst (first 15 min)$250k
Per-block rate$117/blk
Limit rate100‰ = 10% TVL
Approved total$0
Blocked attempts0
Rate Limiter — Live State
Idle
Current allowance
$0 / $0
—
Cycle: —
Block: 0
Period ends: —
Event Log
Press ▶ Play to run scenario
⚙ Override Controls — active in any scenario
Bypass Address
Owner designates addresses that skip the rate limiter entirely — used for protocol vaults, market makers, and emergency response during high-withdrawal periods.
Bypass OFF — rate limit applies
setWithdrawBypass(addr, true/false)
Owner Force Reset
After freezing an attacker's accounts, the owner calls force reset. This zeros the current cycle and immediately restores burst allowance for legitimate users.
Zeroes allowance, perBlock, expiry, and lastBlock. Next withdrawal starts a fresh burst cycle from current TVL.
Withdrawal Availability Curve
Available allowance over one 60-minute rate-limit cycle
Theoretical
Actual
Approved
Attacker ✓
Blocked
Bypass
Deposit
Burst Window — First ~15 min
~25% of the hourly limit is available immediately at the start of each cycle. Covers normal user withdrawals without delay while still limiting attacker throughput.
burst ≈ hourlyLimit × 2143 / 8571
≈ 25% of hourly limit
≈ 25% of hourly limit
Linear Refill — 15–60 min
After the burst, capacity unlocks block-by-block at
collateralPerBlock. An attacker who drains the burst must wait for the drip to refill before withdrawing more.perBlock = hourlyLimit / 8,571 blocks
hourly = max(TVL × 10%, $1M floor)
hourly = max(TVL × 10%, $1M floor)
Cycle Reset & Scaling
At ~60 min, the next withdrawal triggers a new cycle recomputed from current TVL. As TVL shrinks during an exploit, so does the absolute limit — the attack self-throttles.
New period: _wrlsExpiryBlock = block + 8571
Limit scales with each cycle's TVL snapshot
Limit scales with each cycle's TVL snapshot