-
Notifications
You must be signed in to change notification settings - Fork 62
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
base: main
Are you sure you want to change the base?
Conversation
5b3a960
to
31a10d8
Compare
e0a2c13
to
bfcd1b0
Compare
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. |
578fe0a
to
99c8f7a
Compare
require(bool,string) was also considered a FAIL, and revert(string) also, etc. Also added a number of tests for all of these.
99c8f7a
to
1a6a476
Compare
src/EVM/UnitTest.hs
Outdated
-- 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) |
There was a problem hiding this comment.
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
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" |
Adding a note about checkAssertions Ooops
c16aca9
to
be2a5eb
Compare
@@ -508,6 +508,7 @@ getExpr solvers c signature' concreteArgs opts = do | |||
- 0x51: If you call a zero-initialized variable of internal function type. | |||
|
|||
see: https://docs.soliditylang.org/en/v0.8.6/control-structures.html?highlight=Panic#panic-via-assert-and-error-via-require | |||
NOTE: does not deal with e.g. `assertEq()` | |||
-} | |||
checkAssertions :: [Word256] -> Postcondition s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used anywhere? can we either fix it or delete it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or is there a reason to only check for direct calls to assert
in solidity?
@@ -210,9 +212,12 @@ symRun opts@UnitTestOptions{..} vm (Sig testName types) = do | |||
Success _ _ _ store -> if opts.checkFailBit then PNeg (failed store) else PBool True | |||
Failure _ _ (Revert msg) -> case msg of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the sake of completeness, we should also handle the invalid opcode (0xFE
) which was raised by solc < 0.4.
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 |
There was a problem hiding this comment.
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"?
Description
As per discussion on the public matrix channel and the issue #751 we have a problem with
revert()
/revert("message")/
assertin
test` mode. Fixes:require(a==b, "str")
is no longer considered a FAILrevert(string)
is no longer considered a FAILAs 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 therequire(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 can also fix badVault to be actually bad, or it may also be that hevm is incorrect, though that seems unlikely?Checklist