Skip to content

Commit

Permalink
fix(invariant): support assertions on handlers (foundry-rs#5445)
Browse files Browse the repository at this point in the history
  • Loading branch information
Evalir authored Jul 24, 2023
1 parent 4e3c9e7 commit 0fb92d8
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions evm/src/fuzz/invariant/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use super::{
};
use crate::{
executor::{
inspector::Fuzzer, Executor, RawCallResult, CHEATCODE_ADDRESS, HARDHAT_CONSOLE_ADDRESS,
inspector::Fuzzer, Executor, RawCallResult, StateChangeset, CHEATCODE_ADDRESS,
HARDHAT_CONSOLE_ADDRESS,
},
fuzz::{
strategies::{
Expand Down Expand Up @@ -171,7 +172,7 @@ impl<'a> InvariantExecutor<'a> {
}

// Commit changes to the database.
executor.backend_mut().commit(state_changeset);
executor.backend_mut().commit(state_changeset.clone());

fuzz_runs.push(FuzzCase {
calldata: calldata.clone(),
Expand All @@ -185,6 +186,8 @@ impl<'a> InvariantExecutor<'a> {
&executor,
&inputs,
&mut failures.borrow_mut(),
&targeted_contracts,
state_changeset,
self.config.fail_on_revert,
self.config.shrink_sequence,
);
Expand Down Expand Up @@ -551,17 +554,28 @@ fn collect_data(

/// Verifies that the invariant run execution can continue.
/// Returns the mapping of (Invariant Function Name -> Call Result) if invariants were asserted.
#[allow(clippy::too_many_arguments)]
fn can_continue(
invariant_contract: &InvariantContract,
call_result: RawCallResult,
executor: &Executor,
calldata: &[BasicTxDetails],
failures: &mut InvariantFailures,
targeted_contracts: &FuzzRunIdentifiedContracts,
state_changeset: StateChangeset,
fail_on_revert: bool,
shrink_sequence: bool,
) -> (bool, Option<BTreeMap<String, RawCallResult>>) {
let mut call_results = None;
if !call_result.reverted {

// Detect handler assertion failures first.
let handlers_failed = targeted_contracts
.lock()
.iter()
.any(|contract| !executor.is_success(*contract.0, false, state_changeset.clone(), false));

// Assert invariants IFF the call did not revert and the handlers did not fail.
if !call_result.reverted && !handlers_failed {
call_results = assert_invariants(invariant_contract, executor, calldata, failures).ok();
if call_results.is_none() {
return (false, None)
Expand Down

0 comments on commit 0fb92d8

Please sign in to comment.