@@ -82,7 +82,10 @@ instance Monoid CexVars where
82
82
data BufModel
83
83
= Comp CompressedBuf
84
84
| Flat ByteString
85
- deriving (Eq , Show )
85
+ deriving (Eq )
86
+ instance Show BufModel where
87
+ show (Comp c) = " Comp " <> show c
88
+ show (Flat b) = " Flat 0x" <> bsToHex b
86
89
87
90
-- | This representation lets us store buffers of arbitrary length without
88
91
-- exhausting the available memory, it closely matches the format used by
@@ -322,10 +325,10 @@ referencedFrameContext expr = nubOrd $ foldTerm go [] expr
322
325
where
323
326
go :: Expr a -> [(Builder , [Prop ])]
324
327
go = \ case
325
- TxValue -> [(fromString " txvalue " , [] )]
326
- v @ (Balance a ) -> [(fromString " balance_ " <> formatEAddr a , [PLT v (Lit $ 2 ^ (96 :: Int ))])]
327
- Gas freshVar -> [(fromString ( " gas_ " <> show freshVar) , [] )]
328
- CodeHash a @ (LitAddr _) -> [(fromString " codehash_ " <> formatEAddr a , [] )]
328
+ o @ TxValue -> [(fromRight' $ exprToSMT o , [] )]
329
+ o @ (Balance _ ) -> [(fromRight' $ exprToSMT o , [PLT o (Lit $ 2 ^ (96 :: Int ))])]
330
+ o @ ( Gas _ _) -> [(fromRight' $ exprToSMT o , [] )]
331
+ o @ ( CodeHash (LitAddr _)) -> [(fromRight' $ exprToSMT o , [] )]
329
332
_ -> []
330
333
331
334
referencedBlockContext :: TraversableTerm a => a -> [(Builder , [Prop ])]
@@ -443,20 +446,26 @@ declareConstrainAddrs names = SMT2 (["; concrete and symbolic addresses"] <> fma
443
446
assume n = " (assert (bvugt " <> n <> " (_ bv9 160)))"
444
447
cexvars = (mempty :: CexVars ){ addrs = fmap toLazyText names }
445
448
449
+ -- The gas is a tuple of (prefix, index). Within each prefix, the gas is strictly decreasing as the
450
+ -- index increases. This function gets a map of Prefix -> [Int], and for each prefix,
451
+ -- enforces the order
446
452
enforceGasOrder :: [Prop ] -> SMT2
447
- enforceGasOrder ps = SMT2 ([" ; gas ordering" ] <> order indices) mempty mempty
453
+ enforceGasOrder ps = SMT2 ([" ; gas ordering" ] <> ( concatMap ( uncurry order) indices) ) mempty mempty
448
454
where
449
- order :: [Int ] -> [Builder ]
450
- order n = consecutivePairs n >>= \ (x, y)->
455
+ order :: TS. Text -> [Int ] -> [Builder ]
456
+ order prefix n = consecutivePairs (nubInt n) >>= \ (x, y)->
451
457
-- The GAS instruction itself costs gas, so it's strictly decreasing
452
- [" (assert (bvugt gas_" <> (fromString . show $ x) <> " gas_" <> (fromString . show $ y) <> " ))" ]
458
+ [" (assert (bvugt " <> fromRight' (exprToSMT (Gas prefix x)) <> " " <>
459
+ fromRight' ((exprToSMT (Gas prefix y))) <> " ))" ]
453
460
consecutivePairs :: [Int ] -> [(Int , Int )]
454
461
consecutivePairs [] = []
455
462
consecutivePairs l = zip l (tail l)
456
- indices :: [Int ] = nubInt $ concatMap (foldProp go mempty ) ps
457
- go :: Expr a -> [Int ]
463
+ indices = Map. toList $ toMapOfLists $ concatMap (foldProp go mempty ) ps
464
+ toMapOfLists :: [(TS. Text , Int )] -> Map. Map TS. Text [Int ]
465
+ toMapOfLists = foldr (\ (k, v) acc -> Map. insertWith (++) k [v] acc) Map. empty
466
+ go :: Expr a -> [(TS. Text , Int )]
458
467
go e = case e of
459
- Gas freshVar -> [freshVar ]
468
+ Gas prefix v -> [(prefix, v) ]
460
469
_ -> []
461
470
462
471
declareFrameContext :: [(Builder , [Prop ])] -> Err SMT2
@@ -872,8 +881,8 @@ exprToSMT = \case
872
881
pure $ " (store" `sp` encPrev `sp` encIdx `sp` encVal <> " )"
873
882
SLoad idx store -> op2 " select" store idx
874
883
LitAddr n -> pure $ fromLazyText $ " (_ bv" <> T. pack (show (into n :: Integer )) <> " 160)"
875
- Gas freshVar -> pure $ fromLazyText $ " gas_" <> (T. pack $ show freshVar)
876
884
CodeHash a@ (LitAddr _) -> pure $ fromLazyText " codehash_" <> formatEAddr a
885
+ Gas prefix var -> pure $ fromLazyText $ " gas_" <> T. pack (TS. unpack prefix) <> T. pack (show var)
877
886
878
887
a -> internalError $ " TODO: implement: " <> show a
879
888
where
@@ -1060,14 +1069,12 @@ parseBlockCtx "prevrandao" = PrevRandao
1060
1069
parseBlockCtx " gaslimit" = GasLimit
1061
1070
parseBlockCtx " chainid" = ChainId
1062
1071
parseBlockCtx " basefee" = BaseFee
1063
- parseBlockCtx gas | TS. isPrefixOf (TS. pack " gas_" ) gas = Gas (textToInt $ TS. drop 4 gas)
1064
1072
parseBlockCtx val = internalError $ " cannot parse '" <> (TS. unpack val) <> " ' into an Expr"
1065
1073
1066
1074
parseTxCtx :: TS. Text -> Expr EWord
1067
1075
parseTxCtx name
1068
1076
| name == " txvalue" = TxValue
1069
1077
| Just a <- TS. stripPrefix " balance_" name = Balance (parseEAddr a)
1070
- | Just a <- TS. stripPrefix " gas_" name = Gas (textToInt a)
1071
1078
| Just a <- TS. stripPrefix " codehash_" name = CodeHash (parseEAddr a)
1072
1079
| otherwise = internalError $ " cannot parse " <> (TS. unpack name) <> " into an Expr"
1073
1080
0 commit comments