|
3 | 3 |
|
4 | 4 | module Echidna.Events where |
5 | 5 |
|
| 6 | +import Data.Binary.Get |
6 | 7 | import Data.ByteString (ByteString) |
7 | 8 | import Data.ByteString qualified as BS |
8 | 9 | import Data.ByteString.Lazy (fromStrict) |
| 10 | +import Data.List (foldl') |
9 | 11 | import Data.Map (Map) |
10 | 12 | import Data.Map qualified as Map |
11 | 13 | import Data.Maybe (fromJust, catMaybes, maybeToList) |
| 14 | +import Data.Set (Set) |
| 15 | +import Data.Set qualified as Set |
12 | 16 | import Data.Text (pack, Text) |
13 | 17 | import Data.Tree (flatten) |
14 | 18 | import Data.Tree.Zipper (fromForest, TreePos, Empty) |
15 | 19 | import Data.Vector (fromList) |
16 | 20 |
|
17 | 21 | import EVM (traceForest) |
18 | | -import EVM.ABI (Event(..), Indexed(..), decodeAbiValue, AbiType(..), AbiValue(..)) |
| 22 | +import EVM.ABI (Event(..), Indexed(..), decodeAbiValue, getAbi, AbiType(..), AbiValue(..)) |
19 | 23 | import EVM.Dapp (DappContext(..), DappInfo(..)) |
20 | 24 | import EVM.Expr (maybeLitWordSimp) |
21 | 25 | import EVM.Format (showValues, showError, contractNamePart) |
@@ -72,6 +76,35 @@ extractEvents decodeErrors dappInfo vm = |
72 | 76 | Just $ humanPanic $ decodePanic d |
73 | 77 | _ -> Nothing |
74 | 78 |
|
| 79 | +-- | Extract all non‑indexed event values emitted between two VM states. |
| 80 | +extractEventValues :: DappInfo -> VM Concrete s -> VM Concrete s -> Map AbiType (Set AbiValue) |
| 81 | +extractEventValues dappInfo vm vm' = |
| 82 | + let |
| 83 | + oldLogs = vm.logs |
| 84 | + newLogs = vm'.logs |
| 85 | + |
| 86 | + -- only the newly emitted entries |
| 87 | + delta = filter (`notElem` oldLogs) newLogs |
| 88 | + |
| 89 | + -- decode each Expr Log |
| 90 | + goLog = \case |
| 91 | + LogEntry _addr (ConcreteBuf bs) (sigHash : _) -> |
| 92 | + case Map.lookup (forceWord sigHash) dappInfo.eventMap of |
| 93 | + Just (Event _ _ params) -> |
| 94 | + [ (ty, val) |
| 95 | + | (_, ty, NotIndexed) <- params |
| 96 | + , Right (_, _, val) <- [ runGetOrFail (getAbi ty) (fromStrict bs) ] |
| 97 | + ] |
| 98 | + Nothing -> [] |
| 99 | + _ -> [] |
| 100 | + |
| 101 | + pairs = concatMap goLog delta |
| 102 | + in |
| 103 | + foldl' |
| 104 | + (\m (ty,v) -> Map.insertWith Set.union ty (Set.singleton v) m) |
| 105 | + Map.empty |
| 106 | + pairs |
| 107 | + |
75 | 108 | maybeContractNameFromCodeHash :: DappInfo -> W256 -> Maybe Text |
76 | 109 | maybeContractNameFromCodeHash info codeHash = contractToName <$> maybeContract |
77 | 110 | where maybeContract = snd <$> Map.lookup codeHash info.solcByHash |
|
0 commit comments