import { SourceLocationTracker } from '../source/sourceLocationTracker'; import { SymbolicStackManager, SymbolicStackSlot } from './symbolicStack'; import type { SolidityProxy } from './solidityProxy'; /** * Represents detailed information about a single step in the VM execution trace. */ export type StepDetail = { /** Call depth in the execution stack (0 for top-level, increases with each call) */ depth: number; /** Remaining gas at this step (can be number or string representation) */ gas: number | string; /** Gas consumed by this specific operation */ gasCost: number; /** Memory state as an array of bytes */ memory: number[]; /** EVM opcode name (e.g., 'PUSH1', 'ADD', 'CALL') */ op: string; /** Program counter - position in the bytecode */ pc: number; /** EVM stack state as an array of values */ stack: number[]; }; /** * Represents a local variable or parameter with its metadata. */ export interface LocalVariable { /** Variable name */ name: string; /** Parsed type information */ type: any; /** Stack position where the variable is stored */ stackIndex: number; /** Source location where the variable is declared */ sourceLocation: any; /** VM trace step where the variable is declared */ declarationStep: number; /** VM trace step where it's safe to decode this variable */ safeToDecodeAtStep: number; /** AST node ID of the variable */ id: number; /** ABI information (for parameters) */ abi?: any; /** Whether this is a function parameter */ isParameter?: boolean; /** Whether this is a return parameter */ isReturnParameter?: boolean; } export type ScopeFilterMode = 'all' | 'call' | 'nojump'; export interface NestedScope extends Scope { scopeId: string; children: NestedScope[]; } /** * Represents a scope in the call tree with execution details. */ export interface Scope { /** First VM trace step index where this scope starts */ firstStep: number; /** Last VM trace step index where this scope ends (optional) */ lastStep?: number; /** Last safe VM trace step index where this scope ends (optional) */ lastSafeStep?: number; /** Map of local variables in this scope by name */ locals: { [name: string]: LocalVariable; }; /** Whether this scope represents contract creation */ isCreation: boolean; /** Total gas cost for this scope */ gasCost: number; /** Source line where execution starts (optional) */ startExecutionLine?: number; /** Source line where execution ends (optional) */ endExecutionLine?: number; /** Function definition AST node if this scope represents a function */ functionDefinition?: FunctionDefinition; /** Information about revert if scope was reverted */ reverted?: { step: StepDetail; line?: number; }; /** Opcode */ opcodeInfo: StepDetail; /** Opcode */ lastOpcodeInfo?: StepDetail; /** Address */ address?: string; /** Stack */ stackBeforeJumping?: Array; /** Only low level jump **/ lowLevelScope: boolean; /** ASt Nodes **/ astNodes?: Array; } /** * Represents an AST function definition node from Solidity compiler. */ export interface FunctionDefinition { /** Unique identifier for the function in the AST */ id: number; /** Function name */ name: string; /** Function kind (function, constructor, fallback, receive, etc.) */ kind: string; /** Source location string (start:length:file) */ src: string; /** Input parameters */ parameters?: { parameters: any[]; }; /** Return parameters */ returnParameters?: { parameters: any[]; }; /** Function visibility (public, private, internal, external) */ visibility?: string; /** State mutability (pure, view, payable, nonpayable) */ stateMutability?: string; /** Whether function is virtual */ virtual?: boolean; /** Function modifiers */ modifiers?: any[]; /** Function body (block statement) */ body?: any; } /** * Represents a function definition with its inputs for a specific scope. */ export interface FunctionDefinitionWithInputs { /** AST function definition node */ functionDefinition: FunctionDefinition; /** Array of input parameter names */ inputs: string[]; } /** * Return type for the getScopes method containing all scope-related data. */ export interface ScopesData { /** Map of scopeIds to their scope details */ scopes: { [scopeId: string]: Scope; }; /** Map of VM trace indices to scopeIds representing scope starts */ scopeStarts: { [stepIndex: number]: string; }; /** Map of scopeIds to function definitions with their inputs */ functionDefinitionsByScope: { [scopeId: string]: FunctionDefinitionWithInputs; }; /** Stack of VM trace step indices where function calls occur */ functionCallStack: number[]; } /** * Tree representing internal jump into function. * Triggers `callTreeReady` event when tree is ready * Triggers `callTreeBuildFailed` event when tree fails to build */ export declare class InternalCallTree { /** Flag to indicate whether to include local variables in the call tree analysis */ includeLocalVariables: any; /** Flag to enable debugging with compiler-generated sources (e.g., Yul intermediate representation) */ debugWithGeneratedSources: any; /** Event manager for emitting call tree lifecycle events */ event: any; /** Proxy for interacting with Solidity compilation results and AST */ solidityProxy: SolidityProxy; /** Manager for accessing and navigating the execution trace */ traceManager: any; /** Tracker for mapping VM trace indices to source code locations */ sourceLocationTracker: SourceLocationTracker; /** Map of scopes defined by range in the VM trace. Keys are scopeIds, values contain firstStep, lastStep, locals, isCreation, gasCost */ scopes: { [scopeId: string]: Scope; }; /** Map of low level scope that has been merged to their parent */ mergedScope: { [scopeId: string]: string; }; /** Map of VM trace indices to scopeIds, representing the start of each scope */ scopeStarts: { [stepIndex: number]: string; }; /** Stack of VM trace step indices where function calls occur */ functionCallStack: number[]; /** Map of scopeIds to function definitions with their inputs */ functionDefinitionsByScope: { [scopeId: string]: FunctionDefinitionWithInputs; }; /** Cache of variable declarations indexed by file and source location */ variableDeclarationByFile: any; /** Cache of function definitions indexed by file and source location */ functionDefinitionByFile: any; /** AST walker for traversing Abstract Syntax Trees */ astWalker: any; /** Optimized trace containing only steps with new source locations */ reducedTrace: any; /** Map of VM trace indices to their corresponding source location, step details, line/column position, and contract address */ locationAndOpcodePerVMTraceIndex: { [Key: number]: any; }; /** Map of gas costs aggregated by file and line number */ gasCostPerLine: any; /** Converter for transforming source offsets to line/column positions */ offsetToLineColumnConverter: any; /** Map of variable IDs to their metadata (name, type, stackIndex, sourceLocation, declarationStep, safeToDecodeAtStep) */ variables: { [Key: number]: any; }; handledPendingConstructorExecution: { [Key: number]: any; }; /** Symbolic stack manager for tracking variable bindings and stack state throughout execution */ symbolicStackManager: SymbolicStackManager; /** Debug mode */ debug: boolean; /** get from cache */ getCache: (key: string) => Promise; /** fn entry location */ fnJumpDest: { [Key: string]: number; }; /** keep track of ctor params position */ ctorLayout: { [id: number]: number; }; /** last valid BlocksDefinition */ lastValidBlocksDefinition: any; /** * constructor * * @param {Object} debuggerEvent - event declared by the debugger (EthDebugger) * @param {Object} traceManager - trace manager * @param {Object} solidityProxy - solidity proxy * @param {Object} codeManager - code manager * @param {Object} opts - { includeLocalVariables, debugWithGeneratedSources } */ constructor(debuggerEvent: any, traceManager: any, solidityProxy: any, codeManager: any, opts: any, offsetToLineColumnConverter?: any); /** * Resets the call tree to its initial state, clearing all caches and data structures. * Initializes empty maps for scopes, scope starts, variable/function declarations, and other tracking data. */ reset(): void; /** * Retrieves all scope-related data structures. * * @returns {ScopesData} Object containing scopes, scopeStarts, functionDefinitionsByScope, and functionCallStack */ getScopes(): ScopesData; /** * Finds the scope that contains the given VM trace index. * If the scope's lastStep is before the given index, traverses up to parent scopes. * * @param {number} vmtraceIndex - Index in the VM trace * @returns {Object|null} Scope object containing firstStep, lastStep, locals, isCreation, and gasCost, or null if not found */ findScope(vmtraceIndex: any): Scope; /** * Returns the parent scope ID by removing the last sub-scope level. * For example, "1.2.3" becomes "1.2", and "1" becomes "". * * @param {string} scopeId - Scope identifier in dotted notation (e.g., "1.2.3") * @returns {string} Parent scope ID, or empty string if no parent exists */ parentScope(scopeId: any): any; /** * Finds the scope ID that is active at the given VM trace index. * Uses binary search to find the nearest scope start that is <= vmtraceIndex. * * @param {number} vmtraceIndex - Index in the VM trace * @returns {string|null} Scope ID string, or null if no scopes exist */ findScopeId(vmtraceIndex: any): string; /** * Retrieves the stack of function definitions from the root scope to the scope containing the given VM trace index. * Each function entry includes the function definition merged with scope details (firstStep, lastStep, locals, etc.). * * @param {number} vmtraceIndex - Index in the VM trace * @returns {Array} Array of function objects, ordered from innermost to outermost scope * @throws {Error} If recursion depth exceeds 1000 levels */ retrieveFunctionsStack(vmtraceIndex: any): any[]; /** * Extracts the source location corresponding to a specific VM trace step. * Retrieves the contract address and compilation result, then maps the step to source code position. * * @param {number} step - VM trace step index * @param {string} [address] - Contract address (optional, defaults to address at current step) * @returns {Promise} Source location object with start, length, file, and jump properties * @throws {Error} If source location cannot be retrieved */ extractSourceLocation(step: number, address?: string): Promise<{}>; /** * Extracts a valid source location for a specific VM trace step, handling invalid or out-of-range locations. * Falls back to previous valid location if current location is invalid. * * @param {number} step - VM trace step index * @param {string} [address] - Contract address (optional, defaults to address at current step) * @returns {Promise} Valid source location object * @throws {Error} If valid source location cannot be retrieved */ extractValidSourceLocation(step: number, address?: string): Promise>; /** * Retrieves a source location from the cache using VM trace index. * Uses the locationAndOpcodePerVMTraceIndex cache to avoid redundant lookups. * * @param {string} address - Contract address * @param {number} step - VM trace step index * @param {any} contracts - Contracts object from compilation result * @returns {Promise} Valid source location from cache */ getSourceLocationFromVMTraceIndexFromCache(step: number): Promise; /** * Retrieves a valid source location from the cache using VM trace index. * Uses the locationAndOpcodePerVMTraceIndex cache to avoid redundant lookups. * * @param {string} address - Contract address * @param {number} step - VM trace step index * @param {any} contracts - Contracts object from compilation result * @returns {Promise} Valid source location from cache */ getValidSourceLocationFromVMTraceIndexFromCache(address: string, step: number, contracts: any): Promise; /** * Retrieves the aggregated gas cost for a specific file and line number. * * @param {number} file - File index * @param {number} line - Line number * @returns {Promise} Object containing gasCost (total gas) and indexes (array of VM trace steps) * @throws {Error} If gas cost data is not available for the specified file and line */ getGasCostPerLine(file: number, line: number, scopeId: string): Promise; /** * Retrieves a local variable's metadata by its AST node ID. * * @param {number} id - AST node ID of the variable * @returns {Object|undefined} Variable metadata object with name, type, stackIndex, and sourceLocation, or undefined if not found */ getLocalVariableById(id: number): any; /** * Retrieves the symbolic stack state at a specific VM trace step. * The symbolic stack tracks what each stack position represents (variables, parameters, intermediate values). * * @param {number} step - VM trace step index * @returns {Array} Array of symbolic stack slots representing the stack state at that step */ getSymbolicStackAtStep(step: number): SymbolicStackSlot[]; /** * Gets all variables currently on the symbolic stack at a given step. * * @param {number} step - VM trace step index * @returns {Array} Array of variables with their stack positions */ getVariablesOnStackAtStep(step: number): { slot: SymbolicStackSlot; position: number; }[]; /** * Converts the flat scopes structure to a nested JSON structure. * Transforms scopeIds like "1", "1.1", "1.2", "1.1.1" into a hierarchical tree. * * @param {ScopeFilterMode} filterMode - Filtering mode: 'all' (no filtering), 'call' (only keep CALLs), 'nojump' (merge low-level scopes) * @param {string} rootScopeId - Optional scope ID to use as root. If specified, builds tree from this scope instead of actual roots * @returns {NestedScope[]} Array of nested scopes with children as arrays */ getScopesAsNestedJSON(filterMode?: ScopeFilterMode, rootScopeId?: string): NestedScope[]; }