|
1 | | -use crate::executors::{Executor, RawCallResult}; |
| 1 | +use crate::executors::{Executor, FuzzTestTimer, RawCallResult}; |
2 | 2 | use alloy_dyn_abi::JsonAbiExt; |
3 | 3 | use alloy_json_abi::Function; |
4 | 4 | use alloy_primitives::{map::HashMap, Address, Bytes, Log, U256}; |
5 | 5 | use eyre::Result; |
6 | 6 | use foundry_common::evm::Breakpoints; |
7 | 7 | use foundry_config::FuzzConfig; |
8 | 8 | use foundry_evm_core::{ |
9 | | - constants::MAGIC_ASSUME, |
| 9 | + constants::{MAGIC_ASSUME, TEST_TIMEOUT}, |
10 | 10 | decode::{RevertDecoder, SkipReason}, |
11 | 11 | }; |
12 | 12 | use foundry_evm_coverage::HitMaps; |
@@ -98,7 +98,15 @@ impl FuzzedExecutor { |
98 | 98 | let max_traces_to_collect = std::cmp::max(1, self.config.gas_report_samples) as usize; |
99 | 99 | let show_logs = self.config.show_logs; |
100 | 100 |
|
| 101 | + // Start timer for this fuzz test. |
| 102 | + let timer = FuzzTestTimer::new(self.config.timeout); |
| 103 | + |
101 | 104 | let run_result = self.runner.clone().run(&strategy, |calldata| { |
| 105 | + // Check if the timeout has been reached. |
| 106 | + if timer.is_timed_out() { |
| 107 | + return Err(TestCaseError::fail(TEST_TIMEOUT)); |
| 108 | + } |
| 109 | + |
102 | 110 | let fuzz_res = self.single_fuzz(address, should_fail, calldata)?; |
103 | 111 |
|
104 | 112 | // If running with progress then increment current run. |
@@ -193,17 +201,21 @@ impl FuzzedExecutor { |
193 | 201 | } |
194 | 202 | Err(TestError::Fail(reason, _)) => { |
195 | 203 | let reason = reason.to_string(); |
196 | | - result.reason = (!reason.is_empty()).then_some(reason); |
197 | | - |
198 | | - let args = if let Some(data) = calldata.get(4..) { |
199 | | - func.abi_decode_input(data, false).unwrap_or_default() |
| 204 | + if reason == TEST_TIMEOUT { |
| 205 | + // If the reason is a timeout, we consider the fuzz test successful. |
| 206 | + result.success = true; |
200 | 207 | } else { |
201 | | - vec![] |
202 | | - }; |
| 208 | + result.reason = (!reason.is_empty()).then_some(reason); |
| 209 | + let args = if let Some(data) = calldata.get(4..) { |
| 210 | + func.abi_decode_input(data, false).unwrap_or_default() |
| 211 | + } else { |
| 212 | + vec![] |
| 213 | + }; |
203 | 214 |
|
204 | | - result.counterexample = Some(CounterExample::Single( |
205 | | - BaseCounterExample::from_fuzz_call(calldata, args, call.traces), |
206 | | - )); |
| 215 | + result.counterexample = Some(CounterExample::Single( |
| 216 | + BaseCounterExample::from_fuzz_call(calldata, args, call.traces), |
| 217 | + )); |
| 218 | + } |
207 | 219 | } |
208 | 220 | } |
209 | 221 |
|
|
0 commit comments