Skip to content

Fixing checking assert failure #753

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

Merged
merged 10 commits into from
Jul 16, 2025
Merged

Fixing checking assert failure #753

merged 10 commits into from
Jul 16, 2025

Conversation

msooseth
Copy link
Collaborator

@msooseth msooseth commented May 20, 2025

Description

As per discussion on the public matrix channel and the issue #751 we have a problem with revert()/revert("message")/assertintest` mode. Fixes:

  • require(a==b, "str") is no longer considered a FAIL
  • revert(string) is no longer considered a FAIL

As before, all assert-s are considered a FAIL. Also, as before, revert() is not considered a fail.

The badVault code seems to PASS now. It used to fail on the require(stuff, "string") which should not have been a cause for FAIL. It may actually be a good vault, and so maybe the PASS is correct.

We now also print a yellow WARNING in case it's FAIL because of Cex or Warnings -- but ALSO everything reverted. So at least we indicate that there's more than just the issue with the FAIL.

Checklist

  • tested locally
  • added automated tests
  • updated the docs
  • updated the changelog

@msooseth msooseth force-pushed the fixing-forge-assert-check branch from 5b3a960 to 31a10d8 Compare May 20, 2025 14:56
@msooseth msooseth marked this pull request as ready for review May 20, 2025 15:04
@msooseth msooseth force-pushed the fixing-forge-assert-check branch 4 times, most recently from e0a2c13 to bfcd1b0 Compare May 21, 2025 13:15
@msooseth msooseth requested a review from blishko May 21, 2025 13:16
@msooseth
Copy link
Collaborator Author

OK, I think this is finally ready for review :) I added a number of test cases, and removed badVault. We can come back to badVault later.

@msooseth msooseth force-pushed the fixing-forge-assert-check branch 3 times, most recently from 99c8f7a to 1a6a476 Compare May 22, 2025 10:18
-- We need to drop the selector (4B), the offset value (aligned to 32B), and the length of the string (aligned to 32B)
-- NOTE: assertTrue/assertFalse does not have the double colon after "assertion failed"
let assertFail = selector "Error(string)" `BS.isPrefixOf` b && "assertion failed" `BS.isPrefixOf` (BS.drop (4+32+32) b)
in if assertFail || b == panicMsg 0x01 then PBool False
else PBool True
b -> b ./= ConcreteBuf (panicMsg 0x01)
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should run the prefix check in the symbolic case too

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done now :)

@msooseth
Copy link
Collaborator Author

msooseth commented May 22, 2025

The commit be2a5eb now also handles the symbolic case when the prefix is a concrete "assertion failed" of the symbolic string.

We currently don't handle when the string returned doesn't have a concrete prefix matching "assertion failed"

@msooseth msooseth force-pushed the fixing-forge-assert-check branch from c16aca9 to be2a5eb Compare May 26, 2025 12:49
symbolicFail e =
let text = V.fromList $ map (fromIntegral . ord) "assertion failed"
panic = e == ConcreteBuf (panicMsg 0x01)
assertFail = V.take (length text) (Expr.concretePrefix e) == text
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this is sound? What if we have a symbolic prefix that could still be "assertion failed"?

Copy link
Collaborator Author

@msooseth msooseth Jun 16, 2025

Choose a reason for hiding this comment

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

Yeah, that would give us a false positive. But we provide the CEX, so it can be checked. I think it's not a likely problem to come up. But I'm OK with removing it, of course -- I just don't know what to put in its place. Should we just ignore this kind of symbolic fail and simply have

      symbolicFail e =
        let panic = e == ConcreteBuf (panicMsg 0x01)
        in PBool (not panic)

What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think that's probably fine? I would prefer to be sound as a default, I'm also fine to keep the existing concrete prefix extraction as a special case optimization and have this fully symbolic case as a fallback?

Copy link
Collaborator

Choose a reason for hiding this comment

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

and unless I'm misunderstanding, right now a symbolic prefix that could still be "assertion failed" would not be considered as an assertion (since concretePrefix wouldn't find it), and we would be missing potentially failing branches?

Copy link
Collaborator

Choose a reason for hiding this comment

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

are we even able to test this case? we probably need to use assembly actually and like pass some symbolic memory region into revert directly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I had a go at this :) Can you please check if it's what you were thinking of?

The test case I will write later, good catch!

@msooseth msooseth force-pushed the fixing-forge-assert-check branch 3 times, most recently from 7fe1166 to 6d3b75c Compare June 18, 2025 11:26
@msooseth msooseth force-pushed the fixing-forge-assert-check branch from 20e5dd2 to da3dd14 Compare July 2, 2025 14:16
@msooseth
Copy link
Collaborator Author

msooseth commented Jul 2, 2025

TODO: add tests cases -- especially for symbolic return values.

@msooseth msooseth force-pushed the fixing-forge-assert-check branch from 4d4b984 to b10e62e Compare July 14, 2025 16:12
Copy link
Collaborator

@blishko blishko left a comment

Choose a reason for hiding this comment

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

I unfortunately don't understand this part of the program :(
I trust that the changes are correct :)

msooseth added 3 commits July 15, 2025 14:45
require(bool,string) was also considered a FAIL, and revert(string)
also, etc. Also added a number of tests for all of these.
Adding a note about checkAssertions

Ooops
@msooseth msooseth force-pushed the fixing-forge-assert-check branch from b10e62e to a266a8b Compare July 15, 2025 12:49
@msooseth msooseth force-pushed the fixing-forge-assert-check branch from a266a8b to cd2bf74 Compare July 15, 2025 12:52
@msooseth msooseth force-pushed the fixing-forge-assert-check branch from cd2bf74 to c6c5927 Compare July 15, 2025 14:39
@msooseth msooseth merged commit 8dcd682 into main Jul 16, 2025
22 of 25 checks passed
@msooseth msooseth deleted the fixing-forge-assert-check branch July 16, 2025 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants