Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm.expectEmit fails #5506

Closed
2 tasks done
Craigson opened this issue Jul 30, 2023 · 15 comments
Closed
2 tasks done

vm.expectEmit fails #5506

Craigson opened this issue Jul 30, 2023 · 15 comments
Assignees
Labels
A-cheatcodes Area: cheatcodes C-forge Command: forge Cmd-forge-test Command: forge test T-bug Type: bug
Milestone

Comments

@Craigson
Copy link

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (d93312b 2023-07-30T00:26:55.660686000Z)

What command(s) is the bug in?

forge test

Operating System

macOS (Apple Silicon)

Describe the bug

After running foundryup for the first time in a while, all of my tests containing vm.expectEmit are suddenly failing. I cannot create a new test to reproduce the issue, as the behavior in the new test is as expected. I have read through #5117 and other similar issues, but none seem to apply to my use case. Here is my test:

    // should fail performing an admin action while still pending
    function testCallingAdminFunctionAsPendingAdminFails(uint256 eoaUint) public {
        address eoa = _generateRandomEoa(eoaUint);

        _deployDummyIntegration();
        address newAdmin = makeAddr("newAdmin");
        vm.startPrank(integrationDeployer);
        vm.expectEmit(true, true, false, true);
        emit SecurityAdminTransferStarted(integrationDeployer,newAdmin);
        dummyIntegration.transferSecurityAdministration(newAdmin);
        vm.stopPrank();

        assertEq(newAdmin, dummyIntegration.pendingSecurityAdmin(), "SA02: not pending admin");

        vm.startPrank(newAdmin);
        vm.expectRevert(bytes("SA01: security admin only"));
        dummyIntegration.transferSecurityAdministration(eoa);
        vm.stopPrank();
    }

I have confirmed that both events, defined in my contract, and my test file, are identical.

    event SecurityAdminTransferStarted(address indexed oldAdmin, address indexed pendingAdmin);

I tried moving the event definition into the test file, and still no dice. From the console output, we can see that the event is fired inside the first call being made, and the args match exactly.

    ├─ [0] VM::addr(<pk>) [staticcall]
    │   └─ ← newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585]
    ├─ [0] VM::label(newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585], newAdmin)
    │   └─ ← ()
    ├─ [0] VM::startPrank(0xA4B9D41Efb6b3d2C684f3909bdA5356f4F58a899)
    │   └─ ← ()
    ├─ [0] VM::expectEmit(true, true, false, true)
    │   └─ ← ()
    ├─ emit SecurityAdminTransferStarted(oldAdmin: 0xA4B9D41Efb6b3d2C684f3909bdA5356f4F58a899, pendingAdmin: newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    ├─ [22386] DummyIntegration::transferSecurityAdministration(newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    │   ├─ emit SecurityAdminTransferStarted(oldAdmin: 0xA4B9D41Efb6b3d2C684f3909bdA5356f4F58a899, pendingAdmin: newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    │   └─ ← ()
    └─ ← "Log != expected log"

Test result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 109.19ms
Ran 1 test suites: 0 tests passed, 1 failed, 0 skipped (1 total tests)

Failing tests:
Encountered 1 failing test in test/foundry/MyTest.t.sol:MyTestTest
[FAIL. Reason: Expected an emit, but the call reverted instead. Ensure you're testing the happy path when using the `expectEmit` cheatcode. Counterexample: calldata=0x5710534d0000000000000000000000000000000000000000000000000000000000000000, args=[0]] testCallingAdminFunctionAsPendingAdminFails(uint256) (runs: 0, μ: 0, ~: 0)

The reason seems to indicate that the issue has to do with the call reverting, but that is expected behaviour with the expectRevert included. As a sanity check, the test still fails when the expectRevert portion of the test is commented out.

Attempting to reproduce the error was unsuccessful, as the behavior is as expected and the test passes:

pragma solidity 0.8.19;

import "forge-std/Test.sol";

contract EmitContract {
     event TestEvent(address indexed sender, uint256 indexed value);

     function shouldEmit(uint256 val) public {
       emit TestEvent(msg.sender, val);
     }
}

interface IEvents {
     event TestEvent(address indexed sender, uint256 indexed value);
}

contract EmitTest is Test, IEvents {


    EmitContract emitContract;

    function setUp() public {
      emitContract = new EmitContract();
    }
    function testEvent(uint256 val) public {

       address eoa = makeAddr("eoa");
       vm.startPrank(eoa);
       vm.expectEmit(true, true, false, true);
       emit TestEvent(eoa, val);
       emitContract.shouldEmit(val);
       vm.stopPrank();
    }
}

I have tried expecting the emission with all values set to false, and without any args, and the result is the same.

@Craigson Craigson added the T-bug Type: bug label Jul 30, 2023
@Evalir
Copy link
Member

Evalir commented Jul 31, 2023

thanks for reporting this!

I know reproing was unsuccessful, but could we at least get a few instructions on how to repro with your repo? It's much harder to track this down otherwise

@Craigson
Copy link
Author

The contracts are part of a larger protocol that's in a private repo, so I can't share any of the code, but I'll try modify the example to better resemble the conditions.

@jmanywhere
Copy link

jmanywhere commented Aug 5, 2023

This is happening as well on my end. Things in common:

@Evalir
Copy link
Member

Evalir commented Aug 15, 2023

Hey @jmanywhere i can't reproduce—I downloaded your repo, and using the latest foundry version I uncommented the offending part and it passed. Also tried moving the prank after the expect emit and subsequent event emission (which should be the correct usage too) and can't reproduce as well. everything works fine. Also working on an M1 Mac here.

Inclined to close if this can't be accurately reproduced, because if it was a more widespread issue we'd see more reports.

@jmanywhere
Copy link

Thanks @Evalir will run foundryup again and reach back.

@bd21
Copy link

bd21 commented Aug 23, 2023

Running into this issue on a M1 Mac as well. Tests pass with the expectEmit(...) commented out and I can see the events correctly emitted in the trace logs.

solidity: 0.7.6
forge: 0.2.0 (06a17bf 2023-08-19T00:24:01.238378000Z)

Update: no bug, I was just being stupid

@LogiqueClergyman
Copy link

Same issue, but on Windows 10 here. Commenting out expectEmit(...) works with the events emitting correctly in the logs. I am following along a YouTube tutorial, and it works fine in his code and I am following along exactly the same way but the error persists. timestamp: https://youtu.be/sas02qSFZ74?si=kLOd8xjAs6iHCUep&t=18742

@gregkbarnes
Copy link

Hey all - was running into similar issue. Figured out I needed to redefine the events in my test contract (they're not inherited, as they are NOT types like enums/structs/etc.).

Hope this saves someone some time.

@Craigson
Copy link
Author

Craigson commented Sep 5, 2023

Sadly I'm still experiencing this issue. I have tried all of the above solutions mentioned in the comments and nothing works for me.

    ├─ [0] VM::expectEmit(true, true, false, true)
    │   └─ ← ()
    ├─ emit SecurityAdminTransferStarted(oldAdmin: 0xA4B9D41Efb6b3d2C684f3909bdA5356f4F58a899, newAdmin: newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    ├─ [22565] DummyIntegration::transferSecurityAdministration(newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    │   ├─ emit SecurityAdminTransferStarted(oldAdmin: 0xA4B9D41Efb6b3d2C684f3909bdA5356f4F58a899, newAdmin: newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    │   └─ ← ()
    └─ ← "Log != expected log"

I make use of vm.expectEmit 56 times in my codebase. Every time, it's used the same way, using the same events defined in my base test contract that is inherited by all my other tests. Only 5 instances of the expectEmit fail across various files. I cannot reproduce it in a separate project and I can't find any discernible difference between the invocations.

@Craigson
Copy link
Author

Craigson commented Sep 5, 2023

Hey all - was running into similar issue. Figured out I needed to redefine the events in my test contract (they're not inherited, as they are NOT types like enums/structs/etc.).

Hope this saves someone some time.

I have a common file that all my tests inherit from which includes the event definitions. As a sanity check, I commented out the offending event and moved it into the test file. No dice.

@Craigson
Copy link
Author

Craigson commented Sep 5, 2023

Running into this issue on a M1 Mac as well. Tests pass with the expectEmit(...) commented out and I can see the events correctly emitted in the trace logs.

solidity: 0.7.6
forge: 0.2.0 (06a17bf 2023-08-19T00:24:01.238378000Z)

Update: no bug, I was just being stupid

Sharing your issue/solution might be helpful here.

@alfheimrShiven
Copy link

Even I'm facing a similar issue. I've defined it here👇🏾
Discussion Page

Awaiting for help on this. Thanks!

@alfheimrShiven
Copy link

Even I'm facing a similar issue. I've defined it here👇🏾 Discussion Page

Awaiting for help on this. Thanks!

This was fixed! The issue was that I had not followed the sequence of calls for a successful vm.expectEmit(...) to catch the emitted event. You will be able to view the answer on the Discussion page itself.

@zerosnacks zerosnacks added A-cheatcodes Area: cheatcodes C-forge Command: forge Cmd-forge-test Command: forge test labels Jul 3, 2024
@zerosnacks zerosnacks changed the title expectEmit fails vm.expectEmit fails Jul 3, 2024
@zerosnacks
Copy link
Member

Sadly I'm still experiencing this issue. I have tried all of the above solutions mentioned in the comments and nothing works for me.

    ├─ [0] VM::expectEmit(true, true, false, true)
    │   └─ ← ()
    ├─ emit SecurityAdminTransferStarted(oldAdmin: 0xA4B9D41Efb6b3d2C684f3909bdA5356f4F58a899, newAdmin: newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    ├─ [22565] DummyIntegration::transferSecurityAdministration(newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    │   ├─ emit SecurityAdminTransferStarted(oldAdmin: 0xA4B9D41Efb6b3d2C684f3909bdA5356f4F58a899, newAdmin: newAdmin: [0x67ED0Ac45b537A79406E01656d90659325455585])
    │   └─ ← ()
    └─ ← "Log != expected log"

I make use of vm.expectEmit 56 times in my codebase. Every time, it's used the same way, using the same events defined in my base test contract that is inherited by all my other tests. Only 5 instances of the expectEmit fail across various files. I cannot reproduce it in a separate project and I can't find any discernible difference between the invocations.

Hi @Craigson are you still facing issues around this?

@zerosnacks zerosnacks changed the title vm.expectEmit fails vm.expectEmit fails Jul 3, 2024
@zerosnacks zerosnacks self-assigned this Jul 3, 2024
@zerosnacks zerosnacks added this to the v1.0.0 milestone Jul 26, 2024
@zerosnacks
Copy link
Member

Optimistically marking as resolved, feel free to re-open or leave a comment if you are still experiencing issues with this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cheatcodes Area: cheatcodes C-forge Command: forge Cmd-forge-test Command: forge test T-bug Type: bug
Projects
Status: Completed
Development

No branches or pull requests

8 participants