> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phylax.systems/llms.txt
> Use this file to discover all available pages before exploring further.

# ERC20 Cumulative Outflow Breaker

> Limit cumulative ERC20 outflows with a Reshiram circuit-breaker trigger

## When to Use This Pattern

Monitors and limits cumulative token outflows to prevent catastrophic asset loss during exploits, creating a response window for protocol operators. Use it for lending reserves, vault custody, bridge escrows, treasuries, liquidity pools, and other contracts where rapid ERC20 withdrawals are a critical risk.

This is a V2 Reshiram circuit-breaker pattern. The rolling-window accounting is handled by the trigger/precompile machinery, not by assertion-authored storage.

## What This Pattern Checks

Registers a percentage-based cumulative outflow limit:

* `registerAssertionSpec(AssertionSpec.Reshiram)`: Registers the assertion as a Reshiram assertion.
* `watchCumulativeOutflow(token, thresholdBps, windowDuration, assertFn)`: Watches ERC20 outflow over a rolling window.
* `ph.outflowContext()`: Reads the token context inside the triggered assertion.
* Reverts when cumulative outflow breaches the configured threshold.

The assertion does not manually store balances or rolling counters. The Reshiram circuit-breaker trigger is responsible for tracking the window and invoking the assertion when the limit is exceeded.

<Warning>
  As of May 6, 2026, the v2 Reshiram spec is not live on Linea mainnet. Treat this pattern as a local, development, or forward-looking example until Linea mainnet supports the spec.
</Warning>

For more information about cheatcodes, see the [Cheatcodes Documentation](/credible/cheatcodes-reference).

## Assertion Pattern

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {Assertion} from "credible-std/Assertion.sol";
import {AssertionSpec} from "credible-std/SpecRecorder.sol";
import {PhEvm} from "credible-std/PhEvm.sol";

contract ERC20CumulativeOutflowBreakerAssertion is Assertion {
    address public immutable monitoredToken;
    uint256 public immutable outflowThresholdBps;
    uint256 public immutable outflowWindowDuration;

    constructor(address monitoredToken_, uint256 outflowThresholdBps_, uint256 outflowWindowDuration_) {
        registerAssertionSpec(AssertionSpec.Reshiram);

        monitoredToken = monitoredToken_;
        outflowThresholdBps = outflowThresholdBps_;
        outflowWindowDuration = outflowWindowDuration_;
    }

    function triggers() external view override {
        watchCumulativeOutflow(
            monitoredToken,
            outflowThresholdBps,
            outflowWindowDuration,
            this.assertCumulativeOutflow.selector
        );
    }

    /// @notice Reverts when cumulative token outflow breaches the rolling-window limit.
    /// @dev The Reshiram trigger tracks the window and calls this function only after breach.
    function assertCumulativeOutflow() external view {
        PhEvm.OutflowContext memory ctx = ph.outflowContext();
        require(ctx.token == monitoredToken, "ERC20Outflow: wrong token context");

        revert("ERC20Outflow: cumulative outflow breaker tripped");
    }
}
```

<Note>Full examples and mock protocol code are available in [credible-std](https://github.com/phylaxsystems/credible-std/tree/master/examples/assertions-book).</Note>

## Related Patterns

* [ERC20 Cumulative Inflow Breaker](/assertions-book/assertions/ass22-erc20-inflow-breaker)
* [Ether Drain](/assertions-book/assertions/ass21-ether-drain)
* [Ownership Change](/assertions-book/assertions/ass05-ownership-change)
* [Implementation Address Change](/assertions-book/assertions/ass01-impl-addr-change)
