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

PhEvm

Git Source

Title: PhEvm

Author: Phylax Systems

Precompile interface for accessing transaction state within assertions

This interface provides access to the Credible Layer’s execution environment, allowing assertions to inspect transaction state, logs, call inputs, and storage changes. The precompile is available at a deterministic address during assertion execution.

Functions

forkPreTx

Fork to the state before the assertion-triggering transaction

DEPRECATED: Use staticcallAt / loadStateAt with ForkId instead.

function forkPreTx() external;

forkPostTx

Fork to the state after the assertion-triggering transaction

DEPRECATED: Use staticcallAt / loadStateAt with ForkId instead.

function forkPostTx() external;

forkPreCall

Fork to the state before a specific call execution

DEPRECATED: Use staticcallAt / loadStateAt with ForkId instead.

function forkPreCall(uint256 id) external;

forkPostCall

Fork to the state after a specific call execution

DEPRECATED: Use staticcallAt / loadStateAt with ForkId instead.

function forkPostCall(uint256 id) external;

load

Load a storage slot value from any address

DEPRECATED: Use loadStateAt with ForkId instead.

function load(address target, bytes32 slot) external view returns (bytes32 data);

loadStateAt

Read a storage slot from the current assertion adopter at a snapshot.

function loadStateAt(bytes32 slot, ForkId calldata fork) external view returns (bytes32 value);

Parameters

NameTypeDescription
slotbytes32The storage slot to read.
forkForkIdThe snapshot fork to read from.

Returns

NameTypeDescription
valuebytes32The raw 32-byte value at the slot.

loadStateAt

Read a storage slot from any account at a snapshot.

function loadStateAt(address target, bytes32 slot, ForkId calldata fork) external view returns (bytes32 value);

Parameters

NameTypeDescription
targetaddressThe address to read storage from.
slotbytes32The storage slot to read.
forkForkIdThe snapshot fork to read from.

Returns

NameTypeDescription
valuebytes32The raw 32-byte value at the slot.

staticcallAt

Execute a static call against a snapshot fork.

function staticcallAt(address target, bytes calldata data, uint64 gas_limit, ForkId calldata fork)
    external
    view
    returns (StaticCallResult memory result);

Parameters

NameTypeDescription
targetaddressThe contract to call.
databytesThe ABI-encoded function call.
gas_limituint64The gas budget forwarded to the nested static call.
forkForkIdThe snapshot fork to execute against.

Returns

NameTypeDescription
resultStaticCallResultSuccess flag and return or revert bytes from the nested call.

getLogsQuery

Get logs matching a query from a snapshot fork

function getLogsQuery(LogQuery calldata query, ForkId calldata fork) external view returns (Log[] memory logs);

Parameters

NameTypeDescription
queryLogQueryThe emitter and signature filters to apply
forkForkIdThe snapshot fork to read logs from

Returns

NameTypeDescription
logsLog[]Array of logs matching the query inside the selected snapshot window

getErc20Transfers

Returns all ERC20 transfers for a single token in the specified fork.

function getErc20Transfers(address token, ForkId calldata fork)
    external
    view
    returns (Erc20TransferData[] memory transfers);

Parameters

NameTypeDescription
tokenaddressThe ERC20 token address.
forkForkIdThe fork to query.

Returns

NameTypeDescription
transfersErc20TransferData[]Array of decoded transfer records.

getErc20TransfersForTokens

Returns all ERC20 transfers for multiple tokens in the specified fork.

function getErc20TransfersForTokens(address[] calldata tokens, ForkId calldata fork)
    external
    view
    returns (Erc20TransferData[] memory transfers);

Parameters

NameTypeDescription
tokensaddress[]Array of ERC20 token addresses.
forkForkIdThe fork to query.

Returns

NameTypeDescription
transfersErc20TransferData[]Combined array of decoded transfer records across all tokens.

changedErc20BalanceDeltas

Returns all transfers involving the given token for the specified fork.

Semantic alias of getErc20Transfers for balance-delta workflows.

function changedErc20BalanceDeltas(address token, ForkId calldata fork)
    external
    view
    returns (Erc20TransferData[] memory deltas);

Parameters

NameTypeDescription
tokenaddressThe ERC20 token address.
forkForkIdThe fork to query.

reduceErc20BalanceDeltas

Reduces transfers into net balance deltas per unique (from, to) pair.

function reduceErc20BalanceDeltas(address token, ForkId calldata fork)
    external
    view
    returns (Erc20TransferData[] memory deltas);

Parameters

NameTypeDescription
tokenaddressThe ERC20 token address.
forkForkIdThe fork to query.

Returns

NameTypeDescription
deltasErc20TransferData[]Aggregated transfer records in first-seen pair order.

getLogs

Get all logs emitted during the transaction

Returns logs in emission order

function getLogs() external returns (Log[] memory logs);

Returns

NameTypeDescription
logsLog[]Array of Log structs containing all emitted events

getAllCallInputs

Get all call inputs for a target and selector (all call types)

Includes CALL, STATICCALL, DELEGATECALL, and CALLCODE

function getAllCallInputs(address target, bytes4 selector) external view returns (CallInputs[] memory calls);

Parameters

NameTypeDescription
targetaddressThe target contract address
selectorbytes4The function selector to filter by

Returns

NameTypeDescription
callsCallInputs[]Array of CallInputs matching the criteria

getCallInputs

Get call inputs for regular CALL opcode only

function getCallInputs(address target, bytes4 selector) external view returns (CallInputs[] memory calls);

Parameters

NameTypeDescription
targetaddressThe target contract address
selectorbytes4The function selector to filter by

Returns

NameTypeDescription
callsCallInputs[]Array of CallInputs from CALL opcodes

getStaticCallInputs

Get call inputs for STATICCALL opcode only

function getStaticCallInputs(address target, bytes4 selector) external view returns (CallInputs[] memory calls);

Parameters

NameTypeDescription
targetaddressThe target contract address
selectorbytes4The function selector to filter by

Returns

NameTypeDescription
callsCallInputs[]Array of CallInputs from STATICCALL opcodes

getDelegateCallInputs

Get call inputs for DELEGATECALL opcode only

function getDelegateCallInputs(address target, bytes4 selector) external view returns (CallInputs[] memory calls);

Parameters

NameTypeDescription
targetaddressThe target/proxy contract address
selectorbytes4The function selector to filter by

Returns

NameTypeDescription
callsCallInputs[]Array of CallInputs from DELEGATECALL opcodes

getCallCodeInputs

Get call inputs for CALLCODE opcode only

function getCallCodeInputs(address target, bytes4 selector) external view returns (CallInputs[] memory calls);

Parameters

NameTypeDescription
targetaddressThe target contract address
selectorbytes4The function selector to filter by

Returns

NameTypeDescription
callsCallInputs[]Array of CallInputs from CALLCODE opcodes

callOutputAt

Returns the raw return or revert bytes for a traced call.

function callOutputAt(uint256 callId) external view returns (bytes memory output);

Parameters

NameTypeDescription
callIduint256The call identifier from CallInputs.id.

Returns

NameTypeDescription
outputbytesThe raw ABI-encoded return bytes or revert bytes.

callinputAt

Returns the calldata of a specific call.

function callinputAt(uint256 callId) external view returns (bytes memory input);

Parameters

NameTypeDescription
callIduint256The call ID to read input from.

Returns

NameTypeDescription
inputbytesThe raw calldata bytes (selector + ABI-encoded arguments).

getStateChanges

Get all state changes for a specific storage slot

Returns the sequence of values the slot held during transaction execution

function getStateChanges(address contractAddress, bytes32 slot)
    external
    view
    returns (bytes32[] memory stateChanges);

Parameters

NameTypeDescription
contractAddressaddressThe contract whose storage to inspect
slotbytes32The storage slot to get changes for

Returns

NameTypeDescription
stateChangesbytes32[]Array of values the slot held (in order of changes)

forbidChangeForSlot

Checks that a single storage slot on the assertion adopter was not modified.

function forbidChangeForSlot(bytes32 slot) external returns (bool ok);

Parameters

NameTypeDescription
slotbytes32The slot to protect.

Returns

NameTypeDescription
okboolTrue when the slot was not written during the transaction.

forbidChangeForSlots

Checks that none of the given storage slots on the assertion adopter were modified.

function forbidChangeForSlots(bytes32[] calldata slots) external returns (bool ok);

Parameters

NameTypeDescription
slotsbytes32[]The slots to protect.

Returns

NameTypeDescription
okboolTrue when none of the slots were written during the transaction.

getAssertionAdopter

Get the assertion adopter address for the current transaction

The adopter is the contract that registered the assertion

function getAssertionAdopter() external view returns (address);

Returns

NameTypeDescription
<none>addressThe address of the assertion adopter contract

getTxObject

Get the original transaction object that triggered the assertion

Returns the transaction envelope data for the assertion-triggering tx

function getTxObject() external view returns (TxObject memory txObject);

Returns

NameTypeDescription
txObjectTxObjectThe transaction data struct

context

Returns the context for the current onFnCall trigger invocation.

Only valid inside an assertion function triggered by registerFnCallTrigger. Reverts if called outside of an onFnCall-triggered assertion.

function context() external view returns (TriggerContext memory);

matchingCalls

Returns calls matching the given target, selector, and filter criteria.

function matchingCalls(address target, bytes4 selector, CallFilter calldata filter, uint256 limit)
    external
    view
    returns (TriggerCall[] memory calls);

Parameters

NameTypeDescription
targetaddressThe target contract address.
selectorbytes4The function selector to filter by.
filterCallFilterFiltering criteria (call type, depth, success).
limituint256Maximum number of results to return.

Returns

NameTypeDescription
callsTriggerCall[]Array of matching call records.

getLogsForCall

Returns logs emitted during a specific call frame.

function getLogsForCall(LogQuery calldata query, uint256 callId) external view returns (Log[] memory logs);

Parameters

NameTypeDescription
queryLogQueryThe emitter and signature filters to apply.
callIduint256The call ID to scope the log query to.

Returns

NameTypeDescription
logsLog[]Array of logs emitted during the call.

store

Write a bytes32 value to persistent assertion storage.

function store(bytes32 key, bytes32 value) external;

Parameters

NameTypeDescription
keybytes32The storage key.
valuebytes32The value to store.

load

Read a bytes32 value from persistent assertion storage.

function load(bytes32 key) external view returns (bytes32 value);

Parameters

NameTypeDescription
keybytes32The storage key.

Returns

NameTypeDescription
valuebytes32The stored value.

exists

Check if a key exists in persistent assertion storage.

function exists(bytes32 key) external view returns (bool doesExist);

Parameters

NameTypeDescription
keybytes32The storage key.

Returns

NameTypeDescription
doesExistboolTrue if the key has been written to.

values_left

Returns remaining storage slots available to this assertion.

function values_left() external view returns (uint256 remaining);

changedMappingKeys

Returns canonical Solidity key encodings h(key) for keys whose mapping entry at baseSlot was written during the tx.

Best-effort heuristic: traces KECCAK256 -> SSTORE provenance in the execution trace. Custom inline assembly or precomputed hashed slots can bypass the visible keccak chain and produce false negatives.

function changedMappingKeys(address target, bytes32 baseSlot) external view returns (bytes[] memory keys);

Parameters

NameTypeDescription
targetaddressThe contract whose storage was modified.
baseSlotbytes32The Solidity mapping’s base storage slot.

Returns

NameTypeDescription
keysbytes[]Array of encoded keys (each is the h(key) preimage).

mappingValueDiff

Returns the pre/post values for a specific mapping entry.

Computes slot = keccak256(key ++ baseSlot) + fieldOffset, then reads pre from the PreTx fork and post from the PostTx fork.

function mappingValueDiff(address target, bytes32 baseSlot, bytes calldata key, uint256 fieldOffset)
    external
    view
    returns (bytes32 pre, bytes32 post, bool changed);

Parameters

NameTypeDescription
targetaddressThe contract address.
baseSlotbytes32The mapping’s base slot.
keybytesThe canonical encoding h(key) of the mapping key.
fieldOffsetuint256Struct field offset (0 for the first slot of the value).

Returns

NameTypeDescription
prebytes32The PreTx value.
postbytes32The PostTx value.
changedboolTrue if pre != post.

assetsMatchSharePrice

Checks ERC4626 share price consistency across all fork points.

function assetsMatchSharePrice(address vault, uint256 toleranceBps) external returns (bool);

Parameters

NameTypeDescription
vaultaddressThe ERC4626 vault address.
toleranceBpsuint256Maximum allowed deviation in basis points.

Returns

NameTypeDescription
<none>boolTrue if share price stays within tolerance at all forks.

assetsMatchSharePriceAt

Checks ERC4626 share price consistency between two specific forks.

function assetsMatchSharePriceAt(address vault, uint256 toleranceBps, ForkId calldata fork0, ForkId calldata fork1)
    external
    returns (bool);

Parameters

NameTypeDescription
vaultaddressThe ERC4626 vault address.
toleranceBpsuint256Maximum allowed deviation in basis points.
fork0ForkIdThe baseline fork.
fork1ForkIdThe comparison fork.

Returns

NameTypeDescription
<none>boolTrue if share price stays within tolerance.

conserveBalance

Checks that an account’s ERC20 balance is unchanged between two forks.

function conserveBalance(ForkId calldata fork0, ForkId calldata fork1, address token, address account)
    external
    returns (bool);

Parameters

NameTypeDescription
fork0ForkIdThe baseline fork.
fork1ForkIdThe comparison fork.
tokenaddressThe ERC20 token address.
accountaddressThe account whose balance should remain unchanged.

Returns

NameTypeDescription
<none>boolTrue if balanceOf(account) is identical at both forks.

outflowContext

Returns context about the outflow that triggered this assertion.

Only valid inside an assertion function triggered by watchCumulativeOutflow. Returns a zeroed struct if called from a non-outflow trigger context.

function outflowContext() external view returns (OutflowContext memory ctx);

Returns

NameTypeDescription
ctxOutflowContextThe outflow context for the current trigger invocation.

inflowContext

Returns context about the inflow that triggered this assertion.

Only valid inside an assertion function triggered by watchCumulativeInflow. Returns a zeroed struct if called from a non-inflow trigger context.

function inflowContext() external view returns (InflowContext memory ctx);

Returns

NameTypeDescription
ctxInflowContextThe inflow context for the current trigger invocation.

oracleSanity

Checks oracle price consistency across all fork points.

function oracleSanity(address target, bytes calldata data, uint256 bpsDeviation) external returns (bool);

Parameters

NameTypeDescription
targetaddressThe oracle contract address.
databytesThe ABI-encoded oracle query.
bpsDeviationuint256Maximum allowed deviation in basis points.

Returns

NameTypeDescription
<none>boolTrue if oracle price stays within tolerance.

oracleSanityAt

Checks oracle price consistency between two specific forks.

function oracleSanityAt(
    address target,
    bytes calldata data,
    uint256 bpsDeviation,
    ForkId calldata initialFork,
    ForkId calldata currentFork
) external returns (bool);

Parameters

NameTypeDescription
targetaddressThe oracle contract address.
databytesThe ABI-encoded oracle query.
bpsDeviationuint256Maximum allowed deviation in basis points.
initialForkForkIdThe baseline fork.
currentForkForkIdThe comparison fork.

Returns

NameTypeDescription
<none>boolTrue if oracle price stays within tolerance.

mulDivDown

Computes (x * y) / denominator, rounded down. Uses 512-bit intermediates.

function mulDivDown(uint256 x, uint256 y, uint256 denominator) external pure returns (uint256 result);

mulDivUp

Computes (x * y) / denominator, rounded up. Uses 512-bit intermediates.

function mulDivUp(uint256 x, uint256 y, uint256 denominator) external pure returns (uint256 result);

normalizeDecimals

Scales an amount from one decimal base to another.

function normalizeDecimals(uint256 amount, uint8 fromDecimals, uint8 toDecimals)
    external
    pure
    returns (uint256 result);

ratioGe

Compares two ratios with tolerance: num1/den1 >= num2/den2 * (1 - toleranceBps/10000).

Uses cross-multiplication with wide intermediates to avoid division and overflow.

function ratioGe(uint256 num1, uint256 den1, uint256 num2, uint256 den2, uint256 toleranceBps)
    external
    pure
    returns (bool);

Structs

Log

Represents an Ethereum log emitted during transaction execution

Used by getLogs() to return transaction logs for inspection

struct Log {
    /// @notice The topics of the log, including the event signature if any
    bytes32[] topics;
    /// @notice The raw ABI-encoded data of the log
    bytes data;
    /// @notice The address of the contract that emitted the log
    address emitter;
}

LogQuery

Query used to filter transaction logs by emitter and/or signature

struct LogQuery {
    /// @notice address(0) matches any emitter
    address emitter;
    /// @notice bytes32(0) matches any topic0 signature
    bytes32 signature;
}

CallInputs

Represents the inputs to a call made during transaction execution

Used by getCallInputs() and related functions to inspect call details

struct CallInputs {
    /// @notice The calldata of the call
    bytes input;
    /// @notice The gas limit of the call
    uint64 gas_limit;
    /// @notice The address of the bytecode being executed (code address)
    address bytecode_address;
    /// @notice The target address whose storage may be modified
    address target_address;
    /// @notice The address that initiated this call
    address caller;
    /// @notice The ETH value sent with the call
    uint256 value;
    /// @notice Unique identifier for this call, used with forkPreCall/forkPostCall
    uint256 id;
}

TxObject

Contains data about the original assertion-triggering transaction

Provides access to transaction envelope data for inspection in assertions

struct TxObject {
    /// @notice The address that initiated the transaction (tx.origin equivalent)
    address from;
    /// @notice The transaction recipient, or address(0) for contract creation
    address to;
    /// @notice The ETH value sent with the transaction
    uint256 value;
    /// @notice The chain ID, or 0 if not present
    uint64 chain_id;
    /// @notice The gas limit for the transaction
    uint64 gas_limit;
    /// @notice The gas price or max_fee_per_gas for EIP-1559 transactions
    uint128 gas_price;
    /// @notice The transaction calldata
    bytes input;
}

StaticCallResult

Result of a nested static call executed against a snapshot.

struct StaticCallResult {
    /// @notice Whether the nested call completed successfully
    bool ok;
    /// @notice Raw return data or revert data from the nested call
    bytes data;
}

Erc20TransferData

Decoded ERC20 Transfer event data from a snapshot fork.

struct Erc20TransferData {
    /// @notice The token contract that emitted the Transfer event
    address token_addr;
    /// @notice The sender indexed in topic1
    address from;
    /// @notice The receiver indexed in topic2
    address to;
    /// @notice The transferred amount decoded from log data
    uint256 value;
}

ForkId

Identifies a read-only transaction snapshot.

forkType: 0 = PreTx, 1 = PostTx, 2 = PreCall, 3 = PostCall callIndex is used only for call-scoped snapshots.

struct ForkId {
    uint8 forkType;
    uint256 callIndex;
}

TriggerContext

Context for an onFnCall-triggered assertion invocation.

Only valid inside an assertion function triggered by registerFnCallTrigger.

struct TriggerContext {
    /// @notice The function selector that was called on the adopter
    bytes4 selector;
    /// @notice Call index for constructing PreCall ForkId
    uint256 callStart;
    /// @notice Call index for constructing PostCall ForkId
    uint256 callEnd;
}

CallFilter

Filter criteria for matchingCalls queries.

struct CallFilter {
    /// @notice Call type: 0 = any, 1 = CALL, 2 = STATICCALL, 3 = DELEGATECALL, 4 = CALLCODE
    uint8 callType;
    /// @notice Minimum call depth to include
    uint32 minDepth;
    /// @notice Maximum call depth to include
    uint32 maxDepth;
    /// @notice If true, only return top-level calls (depth == 1)
    bool topLevelOnly;
    /// @notice If true, only return calls that succeeded
    bool successOnly;
}

TriggerCall

Detailed record of a call in the transaction trace.

struct TriggerCall {
    uint256 callId;
    uint256 parentCallId;
    address caller;
    address target;
    address codeAddress;
    bytes4 selector;
    uint32 depth;
    uint8 callType;
    bool success;
    uint256 value;
    bytes input;
}

OutflowContext

Context about the outflow that triggered an assertion via watchCumulativeOutflow.

Only valid inside an assertion function triggered by watchCumulativeOutflow. Returns a zeroed struct if called from a non-outflow trigger context.

struct OutflowContext {
    /// @notice The ERC20 token that breached the threshold
    address token;
    /// @notice Net outflow within the window (token units)
    uint256 cumulativeOutflow;
    /// @notice Total absolute outflow within the window (token units, ignoring deposits)
    uint256 absoluteOutflow;
    /// @notice Current outflow as basis points of TVL snapshot
    uint256 currentBps;
    /// @notice Adopter's token balance at window start
    uint256 tvlSnapshot;
    /// @notice Timestamp when the current window began
    uint256 windowStart;
    /// @notice Timestamp when the current window expires
    uint256 windowEnd;
}

InflowContext

Context about the inflow that triggered an assertion via watchCumulativeInflow.

Only valid inside an assertion function triggered by watchCumulativeInflow. Returns a zeroed struct if called from a non-inflow trigger context.

struct InflowContext {
    /// @notice The ERC20 token that breached the threshold
    address token;
    /// @notice Net inflow within the window (token units)
    uint256 cumulativeInflow;
    /// @notice Total absolute inflow within the window (token units, ignoring withdrawals)
    uint256 absoluteInflow;
    /// @notice Current inflow as basis points of TVL snapshot
    uint256 currentBps;
    /// @notice Adopter's token balance at window start
    uint256 tvlSnapshot;
    /// @notice Timestamp when the current window began
    uint256 windowStart;
    /// @notice Timestamp when the current window expires
    uint256 windowEnd;
}