Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,9 +1031,9 @@ impl<DB: DatabaseExt> Inspector<DB> for Cheatcodes {
}
}

fn log(&mut self, _interpreter: &mut Interpreter, _ecx: &mut EvmContext<DB>, log: &Log) {
fn log(&mut self, interpreter: &mut Interpreter, _ecx: &mut EvmContext<DB>, log: &Log) {
if !self.expected_emits.is_empty() {
expect::handle_expect_emit(self, log);
expect::handle_expect_emit(self, log, interpreter);
}

// `recordLogs`
Expand Down
24 changes: 19 additions & 5 deletions crates/cheatcodes/src/test/expect.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{Cheatcode, Cheatcodes, CheatsCtxt, DatabaseExt, Result, Vm::*};
use crate::{Cheatcode, Cheatcodes, CheatsCtxt, DatabaseExt, Error, Result, Vm::*};
use alloy_primitives::{address, hex, Address, Bytes, LogData as RawLog, U256};
use alloy_sol_types::{SolError, SolValue};
use revm::interpreter::{return_ok, InstructionResult};
use revm::interpreter::{
return_ok, InstructionResult, Interpreter, InterpreterAction, InterpreterResult,
};
use spec::Vm;
use std::collections::{hash_map::Entry, HashMap};

Expand Down Expand Up @@ -444,7 +446,11 @@ fn expect_emit(
Ok(Default::default())
}

pub(crate) fn handle_expect_emit(state: &mut Cheatcodes, log: &alloy_primitives::Log) {
pub(crate) fn handle_expect_emit(
state: &mut Cheatcodes,
log: &alloy_primitives::Log,
interpreter: &mut Interpreter,
) {
// Fill or check the expected emits.
// We expect for emit checks to be filled as they're declared (from oldest to newest),
// so we fill them and push them to the back of the queue.
Expand Down Expand Up @@ -473,11 +479,19 @@ pub(crate) fn handle_expect_emit(state: &mut Cheatcodes, log: &alloy_primitives:
let Some(expected) = &event_to_fill_or_check.log else {
// Unless the caller is trying to match an anonymous event, the first topic must be
// filled.
// TODO: failing this check should probably cause a warning
if event_to_fill_or_check.anonymous || log.topics().first().is_some() {
event_to_fill_or_check.log = Some(log.data.clone());
state.expected_emits.push_back(event_to_fill_or_check);
} else {
interpreter.instruction_result = InstructionResult::Revert;
interpreter.next_action = InterpreterAction::Return {
result: InterpreterResult {
output: Error::encode("use vm.expectEmitAnonymous to match anonymous events"),
gas: interpreter.gas,
result: InstructionResult::Revert,
},
};
}
state.expected_emits.push_back(event_to_fill_or_check);
return
};

Expand Down
4 changes: 2 additions & 2 deletions testdata/default/repros/Issue7457.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ contract Issue7457Test is DSTest, ITarget {
target.emitAnonymousEventEmpty();
}

function testFailEmitEventNonIndexed() public {
function testEmitEventNonIndexedReverts() public {
vm.expectEmit(false, false, false, true);
vm.expectRevert("use vm.expectEmitAnonymous to match anonymous events");
emit AnonymousEventNonIndexed(1);
target.emitAnonymousEventNonIndexed(1);
}

function testEmitEventNonIndexed() public {
Expand Down