CredibleTestWithBacktesting
Inherits: CredibleTest, Test
Title: CredibleTestWithBacktesting
Author: Phylax Systems
Extended CredibleTest with historical transaction backtesting capabilities
Inherit from this contract to test assertions against historical blockchain transactions. Supports two modes:
- Block range mode: Test all transactions in a block range via
executeBacktest(config) - Single transaction mode: Test a specific transaction via
executeBacktestForTransaction(txHash, ...)Example:
contract MyBacktest is CredibleTestWithBacktesting {
function testHistorical() public {
executeBacktest(BacktestingTypes.BacktestingConfig({
targetContract: 0x...,
endBlock: 1000000,
blockRange: 100,
assertionCreationCode: type(MyAssertion).creationCode,
assertionSelector: MyAssertion.check.selector,
rpcUrl: "https://eth.llamarpc.com",
detailedBlocks: false,
forkByTxHash: true
}));
}
}
State Variables
_cachedScriptPath
Cached script path to avoid repeated filesystem lookups
string private _cachedScriptPath
Functions
_requireFfi
Skip the calling test unless the profile grants FFI.
Backtesting shells out to transaction_fetcher.sh through vm.ffi, so it only runs
under a profile that sets ffi = true, FOUNDRY_PROFILE=backtesting here. Without it
every vm.ffi reverts, and the script lookup below would report the script as missing
when it is sitting right where it belongs. Skipping names the real requirement and
keeps a full-suite run under another profile green.
function _requireFfi() internal;
executeBacktestForTransaction
Execute backtesting for a single transaction by hash (overload for single tx mode)
function executeBacktestForTransaction(
bytes32 txHash,
address targetContract,
bytes memory assertionCreationCode,
bytes4 assertionSelector,
string memory rpcUrl
) public returns (BacktestingTypes.BacktestingResults memory results);
Parameters
| Name | Type | Description |
|---|---|---|
txHash | bytes32 | The transaction hash to backtest |
targetContract | address | The target contract address |
assertionCreationCode | bytes | The assertion contract creation code |
assertionSelector | bytes4 | The assertion function selector |
rpcUrl | string | The RPC URL to use |
Returns
| Name | Type | Description |
|---|---|---|
results | BacktestingTypes.BacktestingResults | The backtesting results |
executeBacktest
Execute backtesting with config struct (block range mode)
function executeBacktest(BacktestingTypes.BacktestingConfig memory config)
public
returns (BacktestingTypes.BacktestingResults memory results);
_getScriptSearchPaths
Get the standard search paths for transaction_fetcher.sh
Override this in your test contract to add custom search paths
function _getScriptSearchPaths() internal view virtual returns (string[] memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | string[] | Array of paths to check, in order of preference |
_findScriptPath
Find the transaction_fetcher.sh script path
Checks environment variable first, then searches common locations,
and finally uses find to auto-detect the script location.
Override _getScriptSearchPaths() to customize search locations
function _findScriptPath() internal virtual returns (string memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The path to transaction_fetcher.sh |
_autoDetectScriptPath
Auto-detect the script path using find command
Searches the project directory for transaction_fetcher.sh
function _autoDetectScriptPath() internal virtual returns (string memory);
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | The detected path, or empty string if not found |
_fetchTransactions
Fetch transactions using FFI
Automatically detects internal calls using trace APIs with fallback: trace_filter -> debug_traceBlockByNumber -> debug_traceTransaction -> direct calls only
function _fetchTransactions(address targetContract, uint256 startBlock, uint256 endBlock, string memory rpcUrl)
private
returns (BacktestingTypes.TransactionData[] memory transactions);
_executeBacktestForSingleTransaction
Execute backtesting for a single transaction specified by hash
function _executeBacktestForSingleTransaction(
bytes32 txHash,
address targetContract,
bytes memory assertionCreationCode,
bytes4 assertionSelector,
string memory rpcUrl
) private returns (BacktestingTypes.BacktestingResults memory results);
_fetchTransactionByHash
Fetch a single transaction by hash using FFI
function _fetchTransactionByHash(bytes32 txHash, string memory rpcUrl)
private
returns (BacktestingTypes.TransactionData memory txData);
_parseTransactionFromTsv
Parse transaction data from tab-separated output
function _parseTransactionFromTsv(string memory tsvLine)
private
pure
returns (BacktestingTypes.TransactionData memory txData);
_validateTransaction
Validate a single transaction with detailed error categorization
function _validateTransaction(
address targetContract,
bytes memory assertionCreationCode,
bytes4 assertionSelector,
string memory rpcUrl,
BacktestingTypes.TransactionData memory txData,
bool forkByTxHash
) private returns (BacktestingTypes.ValidationDetails memory validation);
_replayTransactionForTrace
Replay a failed transaction to show the full execution trace
Forks to state before the tx and makes a raw call so Foundry prints the full trace
function _replayTransactionForTrace(
address, // targetContract - unused, kept for interface compatibility
bytes memory, // assertionCreationCode - unused
bytes4, // assertionSelector - unused
string memory rpcUrl,
BacktestingTypes.TransactionData memory txData
) private;
_categorizeAndLogError
Categorize and log error details
function _categorizeAndLogError(BacktestingTypes.ValidationDetails memory validation) private pure;
_printDetailedResults
Print detailed results with error categorization
function _printDetailedResults(
uint256 startBlock,
uint256 endBlock,
BacktestingTypes.BacktestingResults memory results
) private pure;