Skip to content

Commit 248e232

Browse files
committed
fix calldataload
1 parent 174f487 commit 248e232

File tree

4 files changed

+27
-25
lines changed

4 files changed

+27
-25
lines changed

src/hevm/hevm-cli/hevm-cli.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ symvmFromCommand cmd = do
729729
-- dynamic calldata via (bounded) haskell list
730730
(Nothing, Nothing, _) -> do
731731
cd <- sbytes256
732-
len <- freshVar_
732+
len <- sw256 <$> freshVar_
733733
return (CalldataDynamic (cd, len), len .<= 256)
734734

735735
-- fully concrete calldata

src/hevm/src/EVM.hs

+7-7
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ data FrameState = FrameState
225225
, _pc :: Int
226226
, _stack :: [SymWord]
227227
, _memory :: Buffer
228-
, _memorySize :: SWord 32
228+
, _memorySize :: SymWord
229229
, _calldata :: Calldata
230230
, _callvalue :: SymWord
231231
, _caller :: SAddr
@@ -723,7 +723,7 @@ exec1 = do
723723
0x35 -> stackOp1 (const g_verylow) $
724724
case the state calldata of
725725
CalldataBuffer bf -> flip readSWord bf
726-
CalldataDynamic bf -> \(S _ i) -> readStaticWordWithBound (sFromIntegral i) bf
726+
CalldataDynamic bf -> flip readStaticWordWithBound bf
727727

728728
-- op: CALLDATASIZE
729729
0x36 ->
@@ -1007,7 +1007,7 @@ exec1 = do
10071007
-- op: MSIZE
10081008
0x59 ->
10091009
limitStack 1 . burn g_base $
1010-
next >> pushSym (sw256 $ sFromIntegral $ the state memorySize)
1010+
next >> pushSym (the state memorySize)
10111011

10121012
-- op: GAS
10131013
0x5a ->
@@ -2175,10 +2175,10 @@ accessUnboundedMemoryRange fees f l continue =
21752175
if maybe False ((==) 0) (maybeLitWord l) then continue
21762176
-- TODO: check for l .== 0 in the symbolic case as well
21772177
else do
2178-
m0 <- sw256 <$> sFromIntegral <$> use (state . memorySize)
2179-
let m1@(S _ m1') = 32 * ceilSDiv (smax m0 (f + l)) 32
2178+
m0 <- use (state . memorySize)
2179+
let m1 = 32 * ceilSDiv (smax m0 (f + l)) 32
21802180
burnSym (memoryCost fees m1 - memoryCost fees m0) $ do
2181-
assign (state . memorySize) (sFromIntegral m1')
2181+
assign (state . memorySize) m1
21822182
continue
21832183

21842184
accessMemoryRange
@@ -2205,7 +2205,7 @@ copyCalldataToMemory
22052205
:: Calldata -> SymWord -> SymWord -> SymWord -> EVM ()
22062206
copyCalldataToMemory (CalldataBuffer bf) size xOffset yOffset =
22072207
copyBytesToMemory bf size xOffset yOffset
2208-
copyCalldataToMemory (CalldataDynamic (b, l)) size xOffset yOffset =
2208+
copyCalldataToMemory (CalldataDynamic (b, (S _ l))) size xOffset yOffset =
22092209
case (maybeLitWord size, maybeLitWord xOffset, maybeLitWord yOffset) of
22102210
(Just size', Just xOffset', Just yOffset') ->
22112211
copyBytesToMemory (StaticSymBuffer [ite (i .<= l) x 0 | (x, i) <- zip b [1..]]) (litWord size') (litWord xOffset') (litWord yOffset')

src/hevm/src/EVM/SymExec.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ abstractVM typesignature concreteArgs x storagemodel calldatamodel = do
111111

112112
BoundedCD -> do
113113
cd <- sbytes256
114-
len <- freshVar_
114+
len <- sw256 <$> freshVar_
115115
return (CalldataDynamic (cd, len), len .<= 256)
116116
Just (name, typs) -> do symbytes <- staticCalldata name typs concreteArgs
117117
return (CalldataBuffer (StaticSymBuffer symbytes), sTrue)
@@ -340,7 +340,7 @@ showCounterexample vm maybesig = do
340340
SAddr caller' = view (EVM.state . EVM.caller) vm
341341
-- cdlen' <- num <$> getValue cdlen
342342
calldatainput <- case calldata' of
343-
CalldataDynamic (cd, cdlen) -> do
343+
CalldataDynamic (cd, (S _ cdlen)) -> do
344344
cdlen' <- num <$> getValue cdlen
345345
mapM (getValue.fromSized) (take cdlen' cd) >>= return . pack
346346
CalldataBuffer (StaticSymBuffer cd) -> mapM (getValue.fromSized) cd >>= return . pack

src/hevm/src/EVM/Symbolic.hs

+17-15
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ writeMemory' bs1 (C _ n) (C _ src) (C _ dst) bs0 =
187187
readMemoryWord' :: Word -> [SWord 8] -> SymWord
188188
readMemoryWord' (C _ i) m = sw256 $ fromBytes $ truncpad 32 (drop (num i) m)
189189

190-
readMemoryWord32' :: Word -> [SWord 8] -> SWord 32
191-
readMemoryWord32' (C _ i) m = fromBytes $ truncpad 4 (drop (num i) m)
190+
readMemoryWord32' :: Word -> [SWord 8] -> SymWord
191+
readMemoryWord32' (C _ i) m = sw256 $ fromBytes $ truncpad 4 (drop (num i) m)
192192

193193
setMemoryWord' :: Word -> SymWord -> [SWord 8] -> [SWord 8]
194194
setMemoryWord' (C _ i) (S _ x) =
@@ -208,8 +208,8 @@ readSWord' (C _ i) x =
208208
else swordAt (num i) x
209209

210210
-- | Operations over dynamic symbolic memory (smt list of bytes)
211-
readByteOrZero'' :: SWord 32 -> SList (WordN 8) -> SWord 8
212-
readByteOrZero'' i bs =
211+
readByteOrZero'' :: SymWord -> SList (WordN 8) -> SWord 8
212+
readByteOrZero'' (S _ i) bs =
213213
ite (sFromIntegral (SL.length bs) .> i + 1)
214214
(bs .!! (sFromIntegral i))
215215
(literal 0)
@@ -265,24 +265,24 @@ read32At :: SInteger -> SList (WordN 8) -> SymWord
265265
read32At i x = sw256 $ fromBytes $ [x .!! literal i | i <- [0..31]]
266266

267267
-- | Although calldata can be modeled perfectly well directly as a Buffer,
268-
-- we allow for it to take on a special form; the pair ([SWord 8], SWord 32)
268+
-- we allow for it to take on a special form; the pair ([SWord 8], SymWord)
269269
-- where the second argument is understood as the length of the list.
270270
-- This allows us to 'fake' dynamically sized calldata arrays in a way
271271
-- that has proven more efficient than `SList`.
272272
data Calldata
273273
= CalldataBuffer Buffer
274-
| CalldataDynamic ([SWord 8], SWord 32)
274+
| CalldataDynamic ([SWord 8], SymWord)
275275
deriving Show
276276

277277
-- a whole foldable instance seems overkill, but length is always good to have!
278-
len :: Buffer -> SymWord --SWord 32
278+
len :: Buffer -> SymWord
279279
len (DynamicSymBuffer a) = sw256 $ sFromIntegral $ SL.length a
280280
len (StaticSymBuffer bs) = litWord . num $ length bs
281281
len (ConcreteBuffer bs) = litWord . num $ BS.length bs
282282

283283
cdlen :: Calldata -> SymWord
284284
cdlen (CalldataBuffer bf) = len bf
285-
cdlen (CalldataDynamic (_, a)) = sw256 $ sFromIntegral a
285+
cdlen (CalldataDynamic (_, a)) = a
286286

287287
grab :: Int -> Buffer -> Buffer
288288
grab n (StaticSymBuffer bs) = StaticSymBuffer $ take n bs
@@ -310,7 +310,7 @@ grabS n bs = case unliteral n of
310310
readByteOrZero :: Int -> Buffer -> SWord 8
311311
readByteOrZero i (StaticSymBuffer bs) = readByteOrZero' i bs
312312
readByteOrZero i (ConcreteBuffer bs) = num $ Concrete.readByteOrZero i bs
313-
readByteOrZero i (DynamicSymBuffer bs) = readByteOrZero'' (literal $ num i) bs
313+
readByteOrZero i (DynamicSymBuffer bs) = readByteOrZero'' (litWord $ num i) bs
314314

315315
-- pad up to 1000 bytes in the dynamic case
316316
sliceWithZero :: SymWord -> SymWord -> Buffer -> Buffer
@@ -343,11 +343,13 @@ readMemoryWord i bf = case (maybeLitWord i, bf) of
343343

344344
readMemoryWord32 :: SymWord -> Buffer -> SWord 32
345345
readMemoryWord32 i m = case (maybeLitWord i, m) of
346-
(Just i', StaticSymBuffer m') -> readMemoryWord32' i' m'
346+
(Just i', StaticSymBuffer m') -> let S _ s = readMemoryWord32' i' m'
347+
in sFromIntegral s
347348
(Just i', ConcreteBuffer m') -> num $ Concrete.readMemoryWord32 i' m'
348349
(_, DynamicSymBuffer m') -> case truncpad' 4 $ dropS i m' of
349350
ConcreteBuffer s -> literal $ num $ Concrete.readMemoryWord32 0 s
350-
StaticSymBuffer s -> readMemoryWord32' 0 s
351+
StaticSymBuffer s -> let S _ s' = readMemoryWord32' 0 s
352+
in sFromIntegral s'
351353
DynamicSymBuffer s -> fromBytes [s .!! literal k | k <- [0..3]]
352354

353355

@@ -369,7 +371,7 @@ setMemoryByte i x m = case (maybeLitWord i, m) of
369371
readSWord :: SymWord -> Buffer -> SymWord
370372
readSWord i bf = case (maybeLitWord i, bf) of
371373
(Just i', StaticSymBuffer x) -> readSWord' i' x
372-
(Just i', ConcreteBuffer x) -> num $ Concrete.readMemoryWord i' x
374+
(Just i', ConcreteBuffer x) -> litWord $ Concrete.readBlobWord i' x
373375
_ -> readSWord'' i (dynamize bf)
374376

375377

@@ -381,9 +383,9 @@ select' xs err ind = walk xs ind err
381383
-- Generates a ridiculously large set of constraints (roughly 25k) when
382384
-- the index is symbolic, but it still seems (kind of) manageable
383385
-- for the solvers.
384-
readStaticWordWithBound :: SWord 32 -> ([SWord 8], SWord 32) -> SymWord
385-
readStaticWordWithBound ind (xs, bound) =
386-
case (num <$> fromSized <$> unliteral ind, num <$> fromSized <$> unliteral bound) of
386+
readStaticWordWithBound :: SymWord -> ([SWord 8], SymWord) -> SymWord
387+
readStaticWordWithBound (S _ ind) (xs, S _ bound) =
388+
case (num <$> unliteral ind, num <$> unliteral bound) of
387389
(Just i, Just b) ->
388390
let bs = truncpad 32 $ drop i (take b xs)
389391
in S (FromBytes (StaticSymBuffer bs)) (fromBytes bs)

0 commit comments

Comments
 (0)