Skip to main content

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.

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.
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.
For more information about cheatcodes, see the Cheatcodes Documentation.

Assertion Pattern

// 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");
    }
}
Full examples and mock protocol code are available in credible-std.