Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions assertions-book/assertions/ass20-erc20-drain.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ import ass20ERC20Drain from "/snippets/ass20-erc20-drain.a.mdx";

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.
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)`: Watches ERC20 outflow over a rolling window.
- `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 is responsible for tracking the window and invoking the assertion when the limit is exceeded.
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.
Expand Down
6 changes: 3 additions & 3 deletions assertions-book/assertions/ass22-erc20-inflow-breaker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ import ass22ERC20InflowBreaker from "/snippets/ass22-erc20-inflow-breaker.a.mdx"

Use this pattern when unexpected inflows can distort protocol accounting, prices, or risk controls. It applies to lending vault donations, AMM reserve stuffing, bridged-asset accounting, staking receipt-token systems, and other protocols where excessive token inflow over a short window is suspicious.

This is a V2 Reshiram circuit-breaker pattern. The rolling-window accounting is handled by the trigger/precompile machinery, not by assertion-authored storage.
This is a V2 Reshiram circuit-breaker pattern. The trigger/precompile machinery collects token inflow 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 inflow limit:

- `registerAssertionSpec(AssertionSpec.Reshiram)`: Registers the assertion as a Reshiram assertion.
- `watchCumulativeInflow(token, thresholdBps, windowDuration, assertFn)`: Watches ERC20 inflow over a rolling window.
- `watchCumulativeInflow(token, thresholdBps, windowDuration, assertFn)`: Collects ERC20 inflow into one bucket per block and watches the buckets over a rolling window.
- `ph.inflowContext()`: Reads the token context inside the triggered assertion.
- Reverts when cumulative inflow 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.
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.
Expand Down
4 changes: 2 additions & 2 deletions assertions-book/assertions/use-cases-index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ Use this page as a reference catalog when you already know the class of risk you

## Circuit Breakers

- [**ERC20 Cumulative Outflow Breaker**](./ass20-erc20-drain): Uses the Reshiram `watchCumulativeOutflow` trigger to limit ERC20 outflows over a rolling window.
- [**ERC20 Cumulative Outflow Breaker**](./ass20-erc20-drain): Uses the Reshiram `watchCumulativeOutflow` trigger to collect ERC20 outflow into one bucket per block and limit cumulative outflow over a rolling window.

- [**ERC20 Cumulative Inflow Breaker**](./ass22-erc20-inflow-breaker): Uses the Reshiram `watchCumulativeInflow` trigger to limit suspicious ERC20 inflows over a rolling window.
- [**ERC20 Cumulative Inflow Breaker**](./ass22-erc20-inflow-breaker): Uses the Reshiram `watchCumulativeInflow` trigger to collect ERC20 inflow into one bucket per block and limit suspicious cumulative inflow over a rolling window.

## Native Asset Protection

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Even if an attacker reaches an admin role or function, an outflow circuit breake
Useful checks include:

- maximum protocol asset outflow per transaction,
- maximum outflow per rolling window,
- maximum outflow across the rolling window's per-block buckets,
- tighter limits after admin-role changes,
- separate limits for treasury, vault, and user collateral assets.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The dangerous state is not only "a bridge was compromised." For a dependent prot

### Cross-Chain Inflow Circuit Breaker

An inflow circuit breaker can limit how much of a bridged or restaked asset enters a protected protocol over a rolling window.
An inflow circuit breaker can collect bridged or restaked asset inflow into one bucket per block and limit the cumulative inflow across those per-block buckets over a rolling window.

Useful checks include:

Expand Down Expand Up @@ -69,7 +69,7 @@ Useful checks include:

For an EVM protocol accepting an asset like rsETH as collateral or vault input, the assertions would not need to understand every LayerZero or KelpDAO internal detail. They would enforce local safety boundaries:

1. The protected market cannot accept more than a configured amount of the asset over a rolling window.
1. The protected market cannot accept more than a configured amount of the asset across the rolling window's per-block buckets.
2. The market cannot grow exposure if asset backing or message-security data is stale, disputed, or outside policy.
3. The protocol cannot silently continue with the same risk parameters after a critical upstream configuration changes.

Expand Down
4 changes: 2 additions & 2 deletions credible/cheatcodes-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Cheatcodes enable functionality that would be impossible or impractical with sta
- **Callstack introspection**: Inspect call traces and execution flow in ways not possible with standard EVM tools
- **State change tracking**: Monitor specific storage slots and track how they change during transaction execution
- **Triggering assertions**: Define precise conditions for when assertions should execute with `onFnCall` and `onTxEnd` triggers
- **Cumulative flow tracking**: Register circuit-breaker triggers for ERC20 inflows or outflows over rolling windows
- **Cumulative flow tracking**: Register circuit-breaker triggers that collect ERC20 inflows or outflows into one bucket per block and evaluate the buckets over rolling windows

## Why Cheatcodes Exist

Expand All @@ -37,7 +37,7 @@ Use cheatcodes when you need to:
- **Compare state changes**: Check if values changed correctly (e.g., "balance decreased by exactly the withdrawal amount")
- **Validate call patterns**: Ensure functions were called in the correct order or with expected parameters
- **Monitor storage**: Track changes to specific storage slots that represent critical protocol state
- **Limit cumulative flows**: Trigger checks after ERC20 inflows or outflows exceed configured rolling-window thresholds
- **Limit cumulative flows**: Collect ERC20 inflows or outflows into one bucket per block and trigger checks when cumulative flow across the buckets exceeds configured rolling-window thresholds
- **Optimize performance**: Use triggers to run assertions only when relevant state changes occur

<Note>
Expand Down
8 changes: 4 additions & 4 deletions credible/cheatcodes-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ function registerErc20ChangeTrigger(

#### `watchCumulativeOutflow`

Registers a circuit breaker trigger for cumulative ERC20 outflow from the assertion adopter.
Registers a circuit breaker trigger that collects ERC20 outflow from the assertion adopter into one bucket per block.

```solidity
function watchCumulativeOutflow(
Expand All @@ -780,11 +780,11 @@ function watchCumulativeOutflow(
) internal view;
```

`thresholdBps` is measured against the TVL snapshot taken at the start of the rolling window. `1000` is `10%`.
The trigger evaluates the per-block buckets over the configured rolling window. `thresholdBps` is measured against the TVL snapshot taken at the start of that window. `1000` is `10%`.

#### `watchCumulativeInflow`

Registers a circuit breaker trigger for cumulative ERC20 inflow into the assertion adopter.
Registers a circuit breaker trigger that collects ERC20 inflow into the assertion adopter into one bucket per block.

```solidity
function watchCumulativeInflow(
Expand All @@ -795,7 +795,7 @@ function watchCumulativeInflow(
) internal view;
```

`thresholdBps` is measured against the TVL snapshot taken at the start of the rolling window. `1000` is `10%`.
The trigger evaluates the per-block buckets over the configured rolling window. `thresholdBps` is measured against the TVL snapshot taken at the start of that window. `1000` is `10%`.

## Deprecated Cheatcodes

Expand Down
2 changes: 2 additions & 0 deletions credible/credible-std-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ function watchCumulativeInflow(
) internal view;
```

The cumulative flow helpers collect inflow or outflow into one bucket per block and evaluate those per-block buckets over the configured rolling window.

`registerFnCallTrigger` pairs with `ph.context()` so an assertion can inspect the matched call's selector and call range.

## Fork and Snapshot Helpers
Expand Down
2 changes: 1 addition & 1 deletion credible/glossary.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ The ability to run complex security rules outside the main blockchain execution,
Special transactions that may have protocol-level inclusion guarantees, such as L1->L2 deposits. Network integrations define the validation policy for these transaction paths.

### Circuit Breaker
An assertion pattern that limits how much value can flow into or out of a protected contract over a rolling window. Circuit breakers are useful when the goal is to reduce exploit velocity or contain blast radius rather than block one specific function call.
An assertion pattern that collects value flowing into or out of a protected contract into one bucket per block, then limits the cumulative flow across those per-block buckets over a rolling window. Circuit breakers are useful when the goal is to reduce exploit velocity or contain blast radius rather than block one specific function call.

### Verifiability
The ability to inspect the rules and registry state behind a protocol's Credible Layer posture. Assertion IDs and registry entries are on-chain, while assertion bytecode is stored in Assertion DA. Public views expose the protocol's visible assertion posture; private project data remains restricted to authorized project users.
Expand Down
2 changes: 1 addition & 1 deletion snippets/ass20-erc20-drain.a.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract ERC20CumulativeOutflowBreakerAssertion is Assertion {
}

/// @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.
/// @dev The Reshiram trigger collects one bucket per block across 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");
Expand Down
2 changes: 1 addition & 1 deletion snippets/ass22-erc20-inflow-breaker.a.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract ERC20CumulativeInflowBreakerAssertion is Assertion {
}

/// @notice Reverts when cumulative token inflow breaches the rolling-window limit.
/// @dev The Reshiram trigger tracks the window and calls this function only after breach.
/// @dev The Reshiram trigger collects one bucket per block across the window and calls this function only after breach.
function assertCumulativeInflow() external view {
PhEvm.InflowContext memory ctx = ph.inflowContext();
require(ctx.token == monitoredToken, "ERC20Inflow: wrong token context");
Expand Down
Loading