Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

AnomalyCompositeAssertion

Git Source

Inherits: AnomalyGatedBaseAssertion

Title: AnomalyCompositeAssertion

Author: Phylax Systems

One anomaly-gated assertion that combines several damage heuristics under a single operator, AND or OR, in one function. Invariant covered:

  • Gated composite damage: an anomalous transaction may not corroborate the enabled damage set under the chosen operator. Under OR any one heuristic blocks; under AND every enabled heuristic must corroborate.

A fleet of single-heuristic assertions can only OR: each is its own contract and any revert invalidates the transaction, so several AnomalyGated* contracts compute a AND (h1 OR h2 OR ...). A fleet cannot express two things:

  1. Operator::And across heuristics, a AND (h1 AND h2). Reverting is disjunctive across contracts, so a conjunction has to live in one function. The offline sweep searches AND configs; deploying an AND selection as separate contracts would ship a different predicate than the one whose friction and detection were measured.
  2. The exclusive-set fall-through a AND NOT(h1) AND NOT(h2) ..., a conjunction of negations. It must be a non-revert outcome of the same evaluation that would otherwise block, or the alert cell is not derivable. The disposition (see AnomalyGatedBaseAssertion): block = a AND H reverts and alert = a AND NOT H falls through without reverting. pass = NOT a costs nothing here at all: the trigger carries the sensitivity level, so a transaction that clears no level never dispatches this function and the corroboration reads are never reached. The corroboration reads use the base primitives, the same ones the individual mixins call. Deploy one composite per protocol, parameters as the only difference. Override _extra to fold a protocol-specific leg into the operator.

Constants

requireAll

bool internal immutable requireAll

useDrain

bool internal immutable useDrain

outflowTarget

address internal immutable outflowTarget

outflowToken

address internal immutable outflowToken

outflowFracBps

uint256 internal immutable outflowFracBps

useUpgrade

bool internal immutable useUpgrade

upgradeTarget

address internal immutable upgradeTarget

ownerSlot

bytes32 internal immutable ownerSlot

useAccounting

bool internal immutable useAccounting

accountingVault

address internal immutable accountingVault

shareToleranceBps

uint256 internal immutable shareToleranceBps

useOracle

bool internal immutable useOracle

oracle

address internal immutable oracle

oracleToleranceBps

uint256 internal immutable oracleToleranceBps

State Variables

oracleQuery

Stored, not immutable: bytes cannot be immutable. Read only when useOracle.

bytes internal oracleQuery

Functions

constructor

constructor(Config memory c) AnomalyGatedBaseAssertion(c.target, c.sensitivity);

triggers

function triggers() external view virtual override;

assertComposite

The composite block predicate. Non-view because the oracle leg executes a read.

Folds each enabled heuristic into the operator, skipping the remaining reads once the fold hits the operator’s absorbing value: a silent leg under AND, a corroborating leg under OR. The alert cell (a AND NOT H) is the deliberate fall-through with no revert.

function assertComposite() external;

_fold

The operator’s fold over one leg: AND or OR of the accumulator and the leg.

function _fold(bool acc, bool leg) internal view returns (bool);

_decided

Whether the fold has hit the operator’s absorbing value (false under AND, true under OR). Past it the remaining legs cannot change the outcome, so their reads are skipped.

function _decided(bool acc) internal view returns (bool);

_extra

A protocol-specific corroboration leg folded into the operator alongside the generic heuristics. Override in a subclass to add a protocol invariant the generic set cannot express.

The constructor guard cannot see a subclass leg, so a subclass whose only leg is _extra must set bareGateBaseline to deploy; the bare-gate fall-back then fires only when the leg reports itself disabled.

function _extra() internal virtual returns (bool enabled, bool corroborates);

Returns

NameTypeDescription
enabledboolWhether the leg participates in the operator.
corroboratesboolWhether the leg corroborates damage on this transaction.

Errors

AnomalousDamage

Reverts when the enabled damage set corroborates under the operator (block = a AND H).

error AnomalousDamage();

AnomalousBareGate

Reverts on an anomalous transaction when no heuristic is enabled: the bare-gate baseline, block on the score alone. Reachable only when bareGateBaseline allowed the heuristic-free deploy; deployed only to measure the baseline.

error AnomalousBareGate();

NoHeuristicEnabled

Constructor guard: a Config with no heuristic enabled would block on the model score alone, which must be the explicit bareGateBaseline choice rather than a default-initialized struct.

error NoHeuristicEnabled();

Structs

Config

The enabled heuristics and their parameters. Each field becomes an immutable in the constructor, except oracleQuery (a bytes, which cannot be immutable) held in storage, and bareGateBaseline, which only gates the constructor.

struct Config {
    address target;
    uint8 sensitivity; // a level from `Sensitivity`, 1..=10
    bool requireAll; // true: block on AND of the enabled heuristics; false: OR
    bool bareGateBaseline; // explicit opt-in: with no heuristic enabled, block on the score alone
    bool useDrain;
    address outflowTarget;
    address outflowToken;
    uint256 outflowFracBps;
    bool useUpgrade;
    address upgradeTarget; // address(0): watch `target`
    bytes32 ownerSlot;
    bool useAccounting;
    address accountingVault;
    uint256 shareToleranceBps;
    bool useOracle;
    address oracle;
    bytes oracleQuery;
    uint256 oracleToleranceBps;
}