@@ -5,7 +5,7 @@ use alloy_primitives::{Address, Log};
5
5
use foundry_evm:: {
6
6
call_inspectors,
7
7
decode:: decode_console_logs,
8
- inspectors:: { LogCollector , TracingInspector } ,
8
+ inspectors:: { LogCollector , TracingInspector , TransferInspector } ,
9
9
revm:: {
10
10
interpreter:: {
11
11
CallInputs , CallOutcome , CreateInputs , CreateOutcome , EOFCreateInputs , Interpreter ,
@@ -25,6 +25,8 @@ pub struct Inspector {
25
25
pub tracer : Option < TracingInspector > ,
26
26
/// Collects all `console.sol` logs
27
27
pub log_collector : Option < LogCollector > ,
28
+ /// Collects all internal ETH transfers as ERC20 transfer events.
29
+ pub transfer : Option < TransferInspector > ,
28
30
}
29
31
30
32
impl Inspector {
@@ -80,6 +82,12 @@ impl Inspector {
80
82
self . tracer = Some ( TracingInspector :: new ( TracingInspectorConfig :: all ( ) . with_state_diffs ( ) ) ) ;
81
83
self
82
84
}
85
+
86
+ /// Configures the `Tracer` [`revm::Inspector`] with a transfer event collector
87
+ pub fn with_transfers ( mut self ) -> Self {
88
+ self . transfer = Some ( TransferInspector :: new ( false ) . with_logs ( true ) ) ;
89
+ self
90
+ }
83
91
}
84
92
85
93
/// Prints the traces for the inspector
@@ -132,7 +140,7 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
132
140
fn call ( & mut self , ecx : & mut EvmContext < DB > , inputs : & mut CallInputs ) -> Option < CallOutcome > {
133
141
call_inspectors ! (
134
142
#[ ret]
135
- [ & mut self . tracer, & mut self . log_collector] ,
143
+ [ & mut self . tracer, & mut self . log_collector, & mut self . transfer ] ,
136
144
|inspector| inspector. call( ecx, inputs) . map( Some ) ,
137
145
) ;
138
146
None
@@ -156,11 +164,11 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
156
164
ecx : & mut EvmContext < DB > ,
157
165
inputs : & mut CreateInputs ,
158
166
) -> Option < CreateOutcome > {
159
- if let Some ( tracer ) = & mut self . tracer {
160
- if let Some ( out ) = tracer . create ( ecx , inputs ) {
161
- return Some ( out ) ;
162
- }
163
- }
167
+ call_inspectors ! (
168
+ # [ ret ]
169
+ [ & mut self . tracer , & mut self . transfer ] ,
170
+ |inspector| { inspector . create ( ecx , inputs ) . map ( Some ) } ,
171
+ ) ;
164
172
None
165
173
}
166
174
@@ -183,11 +191,11 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
183
191
ecx : & mut EvmContext < DB > ,
184
192
inputs : & mut EOFCreateInputs ,
185
193
) -> Option < CreateOutcome > {
186
- if let Some ( tracer ) = & mut self . tracer {
187
- if let Some ( out ) = tracer . eofcreate ( ecx , inputs ) {
188
- return Some ( out ) ;
189
- }
190
- }
194
+ call_inspectors ! (
195
+ # [ ret ]
196
+ [ & mut self . tracer , & mut self . transfer ] ,
197
+ |inspector| { inspector . eofcreate ( ecx , inputs ) . map ( Some ) } ,
198
+ ) ;
191
199
None
192
200
}
193
201
@@ -207,9 +215,12 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
207
215
208
216
#[ inline]
209
217
fn selfdestruct ( & mut self , contract : Address , target : Address , value : U256 ) {
210
- if let Some ( tracer) = & mut self . tracer {
211
- revm:: Inspector :: < DB > :: selfdestruct ( tracer, contract, target, value) ;
212
- }
218
+ call_inspectors ! (
219
+ [ & mut self . tracer, & mut self . transfer] ,
220
+ |inspector| {
221
+ revm:: Inspector :: <DB >:: selfdestruct( inspector, contract, target, value) ;
222
+ } ,
223
+ ) ;
213
224
}
214
225
}
215
226
0 commit comments