Skip to content

Conversation

yash-atreya
Copy link
Member

@yash-atreya yash-atreya commented Jul 25, 2025

Motivation

Supersedes #8686
Closes #592
Closes #8506

Solution

  • Improves the revert message for expectEmits when there is a mismatch in params.
  • log != expected log has been replaced with the named event variant: ComplexEvent != expected SimpleEvent if decoding is successful
  • In the improved error message the parameter index is specified along with the expected and got (actual) data. For example, consider the following test:
// in src/
contract EventEmitter {
    event SimpleEvent(uint256 indexed a, uint256 indexed b, uint256 c);
    function emitSimple(uint256 a, uint256 b, uint256 c) public {
        emit SimpleEvent(a, b, c);
    }
}

// in test/
contract EmitterTest is Test {
    event SimpleEvent(uint256 indexed a, uint256 indexed b, uint256 c);

    function testParamMismatch() public {
        EventEmitter eventEmitter = new EventEmitter();
        vm.expectEmit(true, true, true, true);
        emit SimpleEvent(100, 200, 300);
        eventEmitter.emitSimple(100, 999, 300); // param (b) mismatch
    }
}

This test will fail with:

[FAIL: SimpleEvent param mismatch at b: expected=200, got=999] testParamMismatch()
  • We're checking both the indexed params of an event i.e log.topics and also the non-indexed params which are part of the log.data.
  • Param index starts from 0.
  • If there is an emitter mismatch: the log emitter mismatch: expected=0x..., got=0x... error is thrown
  • To decode the events and their params, the SignaturesIdentifier has now been added to the Cheatcodes struct -Decoding only works over local selectors cache.
  • Note: Decoding does not work for anonymous events.

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

@yash-atreya yash-atreya changed the title feat(cheatcodes): show mismatched params in events feat(cheatcodes): show mismatched params in events Jul 25, 2025
@yash-atreya yash-atreya marked this pull request as ready for review July 25, 2025 12:43
Copy link
Collaborator

@grandizzy grandizzy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's awesome, is there any way we could decode and show mismatched values?

@yash-atreya
Copy link
Member Author

that's awesome, is there any way we could decode and show mismatched values?

I think we should be able to do it with SignatureIdentifier in offline mode ?

@yash-atreya yash-atreya self-assigned this Jul 25, 2025
@yash-atreya yash-atreya marked this pull request as draft July 25, 2025 13:51
@yash-atreya yash-atreya added T-feature Type: feature C-forge Command: forge labels Jul 28, 2025
@yash-atreya yash-atreya marked this pull request as ready for review July 28, 2025 08:17
@yash-atreya yash-atreya changed the title feat(cheatcodes): show mismatched params in events feat(cheatcodes): show mismatched params on expectEmit Jul 28, 2025
@yash-atreya yash-atreya removed their assignment Jul 28, 2025
zerosnacks
zerosnacks previously approved these changes Jul 28, 2025
Copy link
Member

@zerosnacks zerosnacks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better! 👍

Copy link
Collaborator

@grandizzy grandizzy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you, left some initial nits / questions

let event = foundry_common::block_on(identifier.identify_event(t0))?;

// Check if event already has correct indexed flags
let indexed_count = event.inputs.iter().filter(|p| p.indexed).count();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this logic already covered in get_indexed_event fn so we could just do here

  let event = foundry_common::block_on(identifier.identify_event(t0))?;
  let indexed_event = get_indexed_event(event, log);

  // Try to decode the event
  if let Ok(decoded) = indexed_event.decode_log(log) {
...

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because get_indexed_event is using a heuristic which gives preference to an address while categorizing whether a param is indexed or not.

It incorrectly guesses the number of indexed parameters for:

event MixedEventNumbering(
        uint256 indexed param0,
        address indexed param1,
        uint256 param2,
        uint256 param3,
        address param4 // Marks this as `indexed` leading to decoding failure.
    );

This is due to this if condition:

if num_inputs == indexed_params
                || (num_address_params == indexed_params && param.ty == "address") // 2nd condition is true for above event 
            {
                param.indexed = true;
            }

So, TL;DR don't use get_indexed_event if we already know the indexed params

@yash-atreya yash-atreya changed the title feat(cheatcodes): show mismatched params on expectEmit feat(cheatcodes): decode and show mismatched params on expectEmit Jul 28, 2025
@yash-atreya yash-atreya enabled auto-merge (squash) July 28, 2025 14:08
@yash-atreya yash-atreya disabled auto-merge July 28, 2025 14:08
grandizzy
grandizzy previously approved these changes Jul 28, 2025
Copy link
Collaborator

@grandizzy grandizzy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thank you, left one more optional nit

@yash-atreya yash-atreya enabled auto-merge (squash) July 29, 2025 05:37
@grandizzy grandizzy self-requested a review July 29, 2025 05:39
@yash-atreya yash-atreya merged commit 8030cbc into master Jul 29, 2025
22 checks passed
@yash-atreya yash-atreya deleted the yash/highl-mismatched-events branch July 29, 2025 05:52
@github-project-automation github-project-automation bot moved this to Done in Foundry Jul 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-forge Command: forge T-feature Type: feature
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

feat(tracing): log failed expectEmit events as error traces feat(cheatcodes): specify mis-matched fields on expectEmit failure
3 participants