Skip to content

Commit

Permalink
Fixing bug related to zero-sized arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
msooseth committed Feb 18, 2025
1 parent af8e6c0 commit e73d267
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Dumping of END states (.prop) files is now default for `--debug`
- When cheatcode is missing, we produce a partial execution warning
- Size of calldata can be up to 2**64, not 256. This is now reflected in the documentation
- Zero-length buffers actually imply all-zero buffer, and vica-versa. This
was assumed but not encoded. Fixed.

## Changed
- Warnings now lead printing FAIL. This way, users don't accidentally think that
Expand Down
10 changes: 9 additions & 1 deletion src/EVM/SMT.hs
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,20 @@ discoverMaxReads props benv senv = bufMap

-- | Returns an SMT2 object with all buffers referenced from the input props declared, and with the appropriate cex extraction metadata attached
declareBufs :: [Prop] -> BufEnv -> StoreEnv -> SMT2
declareBufs props bufEnv storeEnv = SMT2 ("; buffers" : fmap declareBuf allBufs <> ("; buffer lengths" : fmap declareLength allBufs)) cexvars mempty
declareBufs props bufEnv storeEnv =
SMT2 (smtBufNames <> smtBufLengths <> smtEmptyRelations) cexvars mempty
where
smtBufNames = "; buffers" : fmap declareBuf allBufs
smtBufLengths = "; buffer lengths" : fmap declareLength allBufs
smtEmptyRelations = "; empty buffer relations" : concatMap emptyRelation allBufs
cexvars = (mempty :: CexVars){ buffers = discoverMaxReads props bufEnv storeEnv }
allBufs = fmap fromLazyText $ Map.keys cexvars.buffers
declareBuf n = "(declare-fun " <> n <> " () (Array (_ BitVec 256) (_ BitVec 8)))"
declareLength n = "(declare-fun " <> n <> "_length" <> " () (_ BitVec 256))"
emptyRelation buf =
let bufLen = buf <> "_length"
in ["(assert (=> (= " <> bufLen <> " (_ bv0 256)) (= " <> buf <> " ((as const Buf) #b00000000)) ))"
, "(assert (=> (= " <> buf <> " ((as const Buf) #b00000000)) (= " <> bufLen <> " (_ bv0 256)) ))" ]

-- Given a list of variable names, create an SMT2 object with the variables declared
declareVars :: [Builder] -> SMT2
Expand Down
7 changes: 7 additions & 0 deletions test/test.hs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,13 @@ tests = testGroup "hevm"
simp = Expr.simplify e
res <- checkEquiv e simp
assertEqualM "readWord simplification" res True
, test "simp-empty-buflength" $ do
let e = PEq (BufLength (AbstractBuf "mybuf")) (Lit 0)
let simp = Expr.simplifyProp e
let simpExpected = PEq (AbstractBuf "mybuf") (ConcreteBuf "")
assertEqualM "buflen-to-empty" simp simpExpected
ret <- checkEquivPropAndLHS e simpExpected
assertBoolM "Must be equivalent" ret
, test "simp-max-buflength" $ do
let simp = Expr.simplify $ Max (Lit 0) (BufLength (AbstractBuf "txdata"))
assertEqualM "max-buflength rules" simp $ BufLength (AbstractBuf "txdata")
Expand Down

0 comments on commit e73d267

Please sign in to comment.