Skip to content

Commit e73d267

Browse files
committed
Fixing bug related to zero-sized arrays
1 parent af8e6c0 commit e73d267

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

Diff for: CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3535
- Dumping of END states (.prop) files is now default for `--debug`
3636
- When cheatcode is missing, we produce a partial execution warning
3737
- Size of calldata can be up to 2**64, not 256. This is now reflected in the documentation
38+
- Zero-length buffers actually imply all-zero buffer, and vica-versa. This
39+
was assumed but not encoded. Fixed.
3840

3941
## Changed
4042
- Warnings now lead printing FAIL. This way, users don't accidentally think that

Diff for: src/EVM/SMT.hs

+9-1
Original file line numberDiff line numberDiff line change
@@ -420,12 +420,20 @@ discoverMaxReads props benv senv = bufMap
420420

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

430438
-- Given a list of variable names, create an SMT2 object with the variables declared
431439
declareVars :: [Builder] -> SMT2

Diff for: test/test.hs

+7
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,13 @@ tests = testGroup "hevm"
545545
simp = Expr.simplify e
546546
res <- checkEquiv e simp
547547
assertEqualM "readWord simplification" res True
548+
, test "simp-empty-buflength" $ do
549+
let e = PEq (BufLength (AbstractBuf "mybuf")) (Lit 0)
550+
let simp = Expr.simplifyProp e
551+
let simpExpected = PEq (AbstractBuf "mybuf") (ConcreteBuf "")
552+
assertEqualM "buflen-to-empty" simp simpExpected
553+
ret <- checkEquivPropAndLHS e simpExpected
554+
assertBoolM "Must be equivalent" ret
548555
, test "simp-max-buflength" $ do
549556
let simp = Expr.simplify $ Max (Lit 0) (BufLength (AbstractBuf "txdata"))
550557
assertEqualM "max-buflength rules" simp $ BufLength (AbstractBuf "txdata")

0 commit comments

Comments
 (0)