Skip to content

bug: snapshot/revertTo causes tests to pass unexpectedly #3055

New issue

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

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

Already on GitHub? # to your account

Closed
2 tasks done
mds1 opened this issue Sep 1, 2022 · 12 comments · Fixed by #3087 or #4974
Closed
2 tasks done

bug: snapshot/revertTo causes tests to pass unexpectedly #3055

mds1 opened this issue Sep 1, 2022 · 12 comments · Fixed by #3087 or #4974
Assignees
Labels
A-cheatcodes Area: cheatcodes C-forge Command: forge Cmd-forge-test Command: forge test T-bug Type: bug

Comments

@mds1
Copy link
Collaborator

mds1 commented Sep 1, 2022

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 (48d5d79 2022-09-01T00:10:22.933552Z)

What command(s) is the bug in?

forge test

Operating System

No response

Describe the bug

If you run this test, it passes. If you comment out the vm.revertTo line it fails. Failure is expected in both cases since the assertion should fail. It seems like the cause is that reverting the state also reverts the failed flag: https://github.com/dapphub/ds-test/blob/9310e879db8ba3ea6d5c6489a579118fd264a3f5/src/test.sol#L47-L63

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "forge-std/Test.sol";

contract MyTest is Test {
  function test_snapshot() external {
    uint256 snapId = vm.snapshot();
    assertEq(uint256(0), uint256(1));
    vm.revertTo(snapId);
  }
}
@mds1 mds1 added the T-bug Type: bug label Sep 1, 2022
@gakonst gakonst added this to Foundry Sep 1, 2022
@gakonst gakonst moved this to Todo in Foundry Sep 1, 2022
@rkrasiuk rkrasiuk added Cmd-forge-test Command: forge test C-forge Command: forge labels Sep 1, 2022
@mattsse
Copy link
Member

mattsse commented Sep 1, 2022

It seems like the cause is that reverting the state also reverts the failed flag:

that sounds right, need to make a check for failed() here

@mattsse
Copy link
Member

mattsse commented Sep 5, 2022

with #3087 this now results in

~/git/rust/foundry/target/debug/forge test                                                                                                           ! master 
[⠢] Compiling...
No files changed, compilation skipped

Running 1 test for test/Counter.t.sol:MyTest
[FAIL. Reason: Assertion failed.] test_snapshot() (gas: 15534)
Test result: FAILED. 0 passed; 1 failed; finished in 2.71ms

Failing tests:
Encountered 1 failing test in test/Counter.t.sol:MyTest
[FAIL. Reason: Assertion failed.] test_snapshot() (gas: 15534)

Encountered a total of 1 failing tests, 0 tests succeeded

Repository owner moved this from Todo to Done in Foundry Sep 5, 2022
@graykode
Copy link

This still doesn't work. But after modifying a few lines in forge-std, it works. foundry-rs/forge-std#241 @mattsse

@mds1
Copy link
Collaborator Author

mds1 commented Nov 28, 2022

@mattsse I was able to reproduce the issue from @graykode, any idea on the cause?

The forge-std fix in foundry-rs/forge-std#241 does resolve the issue, but I'm not sure why. Regardless though, seems this should be fixed upstream here in foundry instead?

@mattsse
Copy link
Member

mattsse commented Nov 28, 2022

looks strange, I have to take a closer look

@ZeroEkkusu
Copy link
Contributor

ZeroEkkusu commented Nov 29, 2022

@mattsse, see foundry-rs/forge-std#241 (review). The underlying issue needs to be identified.

@xenoliss
Copy link

xenoliss commented Dec 1, 2022

Hey ! I'm still facing this issue on forge std c7d30303fc34b7b2a680c86ddc1cd186bec23614. Here is a PoC code:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import "forge-std/Test.sol";

contract TestMe is Test {
    function testMe() public {
        uint256 snapshot = vm.snapshot();
        assertTrue(false);

        vm.revertTo(snapshot);
        assertTrue(true);
    }
}

This outputs the following:

$ forge test --match-test testMe -vv
[⠒] Compiling...
No files changed, compilation skipped

Running 1 test for test/TestMe.t.sol:TestMe
[PASS] testMe() (gas: 11436)
Logs:
  Error: Assertion Failed

The only was to view the failing test is using a more verbose mode like -vv, else this is totally invisible.
Also when nesting snapshots, the logs are simply vanished and -vv does not log the errors.

@OliverNChalk
Copy link
Contributor

For those facing this issue, you may wish to use the following as a temp workaround:

    function _revertTo(uint256 aSnapshot) private {
        require(!failed(), "Fail flag triggered, aborting revert");

        vm.revertTo(aSnapshot);
    }

@mattsse
Copy link
Member

mattsse commented Mar 31, 2023

hmm, I'm not quite sure what the issue is here, because both examples fail.

or is the problem that the first assertion doesn't stop execution?

this behavior has ds-test legacy reasons but I'm skeptical that this is any good...

@OliverNChalk
Copy link
Contributor

Interesting, I can get logged test failures without the test failing:
image

I am on a fork while using vm.revertTo. My forge version is forge 0.2.0 (0f1dea4 2023-03-31T00:07:29.356304995Z). Let me try get you a repro a bit later

@OliverNChalk
Copy link
Contributor

@mattsse It appears that fuzz testing breaks whatever code was introduced to persist the failure state. That said, I vaguely remember seeing this fail prior to fuzzing. However, perhaps they share the same root cause.

This minimal repro should make it easier to track down:
https://github.com/OliverNChalk/revert-to-repro

@mattsse
Copy link
Member

mattsse commented Apr 2, 2023

thanks, will check!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-cheatcodes Area: cheatcodes C-forge Command: forge Cmd-forge-test Command: forge test T-bug Type: bug
Projects
Archived in project
7 participants