> ## 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 trigger/precompile machinery collects token outflow into one bucket per block and evaluates those per-block buckets over the rolling window. The assertion does not need its own storage for this accounting.

## 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)`: Collects ERC20 outflow into one bucket per block and watches the buckets 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 tracks the per-block buckets across the window and invokes the assertion when the limit is exceeded.

<Warning>
  The current Phylax app and Linea deployment support the V1 assertion specification. Treat this V2 Reshiram pattern as a local or development example until the target deployment supports V2.
</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)
