@@ -5,7 +5,10 @@ use alloy_primitives::{Address, Bytes, Log, U256};
55use eyre:: Result ;
66use foundry_common:: evm:: Breakpoints ;
77use foundry_config:: FuzzConfig ;
8- use foundry_evm_core:: { constants:: MAGIC_ASSUME , decode:: RevertDecoder } ;
8+ use foundry_evm_core:: {
9+ constants:: MAGIC_ASSUME ,
10+ decode:: { RevertDecoder , SkipReason } ,
11+ } ;
912use foundry_evm_coverage:: HitMaps ;
1013use foundry_evm_fuzz:: {
1114 strategies:: { fuzz_calldata, fuzz_calldata_from_state, EvmFuzzState } ,
@@ -131,9 +134,8 @@ impl FuzzedExecutor {
131134 } ) => {
132135 // We cannot use the calldata returned by the test runner in `TestError::Fail`,
133136 // since that input represents the last run case, which may not correspond with
134- // our failure - when a fuzz case fails, proptest will try
135- // to run at least one more case to find a minimal failure
136- // case.
137+ // our failure - when a fuzz case fails, proptest will try to run at least one
138+ // more case to find a minimal failure case.
137139 let reason = rd. maybe_decode ( & outcome. 1 . result , Some ( status) ) ;
138140 execution_data. borrow_mut ( ) . logs . extend ( outcome. 1 . logs . clone ( ) ) ;
139141 execution_data. borrow_mut ( ) . counterexample = outcome;
@@ -157,6 +159,7 @@ impl FuzzedExecutor {
157159 first_case : fuzz_result. first_case . unwrap_or_default ( ) ,
158160 gas_by_case : fuzz_result. gas_by_case ,
159161 success : run_result. is_ok ( ) ,
162+ skipped : false ,
160163 reason : None ,
161164 counterexample : None ,
162165 logs : fuzz_result. logs ,
@@ -168,20 +171,22 @@ impl FuzzedExecutor {
168171 } ;
169172
170173 match run_result {
171- // Currently the only operation that can trigger proptest global rejects is the
172- // `vm.assume` cheatcode, thus we surface this info to the user when the fuzz test
173- // aborts due to too many global rejects, making the error message more actionable.
174- Err ( TestError :: Abort ( reason) ) if reason. message ( ) == "Too many global rejects" => {
175- result. reason = Some (
176- FuzzError :: TooManyRejects ( self . runner . config ( ) . max_global_rejects ) . to_string ( ) ,
177- ) ;
178- }
174+ Ok ( ( ) ) => { }
179175 Err ( TestError :: Abort ( reason) ) => {
180- result. reason = Some ( reason. to_string ( ) ) ;
176+ let msg = reason. message ( ) ;
177+ // Currently the only operation that can trigger proptest global rejects is the
178+ // `vm.assume` cheatcode, thus we surface this info to the user when the fuzz test
179+ // aborts due to too many global rejects, making the error message more actionable.
180+ result. reason = if msg == "Too many global rejects" {
181+ let error = FuzzError :: TooManyRejects ( self . runner . config ( ) . max_global_rejects ) ;
182+ Some ( error. to_string ( ) )
183+ } else {
184+ Some ( msg. to_string ( ) )
185+ } ;
181186 }
182187 Err ( TestError :: Fail ( reason, _) ) => {
183188 let reason = reason. to_string ( ) ;
184- result. reason = if reason. is_empty ( ) { None } else { Some ( reason) } ;
189+ result. reason = ( ! reason. is_empty ( ) ) . then_some ( reason) ;
185190
186191 let args = if let Some ( data) = calldata. get ( 4 ..) {
187192 func. abi_decode_input ( data, false ) . unwrap_or_default ( )
@@ -193,7 +198,13 @@ impl FuzzedExecutor {
193198 BaseCounterExample :: from_fuzz_call ( calldata, args, call. traces ) ,
194199 ) ) ;
195200 }
196- _ => { }
201+ }
202+
203+ if let Some ( reason) = & result. reason {
204+ if let Some ( reason) = SkipReason :: decode_self ( reason) {
205+ result. skipped = true ;
206+ result. reason = reason. 0 ;
207+ }
197208 }
198209
199210 state. log_stats ( ) ;
@@ -212,9 +223,9 @@ impl FuzzedExecutor {
212223 let mut call = self
213224 . executor
214225 . call_raw ( self . sender , address, calldata. clone ( ) , U256 :: ZERO )
215- . map_err ( |_ | TestCaseError :: fail ( FuzzError :: FailedContractCall ) ) ?;
226+ . map_err ( |e | TestCaseError :: fail ( e . to_string ( ) ) ) ?;
216227
217- // When the ` assume` cheatcode is called it returns a special string
228+ // Handle `vm. assume`.
218229 if call. result . as_ref ( ) == MAGIC_ASSUME {
219230 return Err ( TestCaseError :: reject ( FuzzError :: AssumeReject ) )
220231 }
0 commit comments