ethereum-analyzer 1.3.0 → 2.0.0
raw patch · 26 files changed
+4653/−1050 lines, 26 filesdep +GenericPrettydep +aesondep +prettydep ~base
Dependencies added: GenericPretty, aeson, pretty, protolude, split, unordered-containers, wl-pprint-text
Dependency ranges changed: base
Files
- ethereum-analyzer.cabal +29/−5
- src/Ethereum/Analyzer.hs +1/−1
- src/Ethereum/Analyzer/CfgAugWithTopNPass.hs +55/−49
- src/Ethereum/Analyzer/CfgAugmentPass.hs +24/−21
- src/Ethereum/Analyzer/Common.hs +34/−5
- src/Ethereum/Analyzer/Debug.hs +21/−0
- src/Ethereum/Analyzer/Disasm.hs +6/−6
- src/Ethereum/Analyzer/IR.hs +30/−49
- src/Ethereum/Analyzer/Solidity.hs +11/−0
- src/Ethereum/Analyzer/Solidity/AstJson.hs +282/−0
- src/Ethereum/Analyzer/Solidity/Finding.hs +20/−0
- src/Ethereum/Analyzer/Solidity/Foreach.hs +39/−0
- src/Ethereum/Analyzer/Solidity/Simple.hs +306/−0
- src/Ethereum/Analyzer/Util.hs +27/−26
- test/Ethereum/Analyzer/CfgAugWithTopNPassSpec.hs +19/−10
- test/Ethereum/Analyzer/CfgAugmentPassSpec.hs +170/−161
- test/Ethereum/Analyzer/IRSpec.hs +175/−169
- test/Ethereum/Analyzer/Solidity/ForeachSpec.hs +37/−0
- test/Ethereum/Analyzer/Solidity/SimpleSpec.hs +411/−0
- test/Ethereum/Analyzer/SoliditySpec.hs +365/−0
- test/Ethereum/Analyzer/TestData/Basic.hs +25/−0
- test/Ethereum/Analyzer/TestData/DaoJson.hs +1790/−0
- test/Ethereum/Analyzer/TestData/StorageJson.hs +237/−0
- test/Ethereum/Analyzer/UtilSpec.hs +389/−376
- test/Ethereum/AnalyzerSpec.hs +150/−147
- test/SpecCommon.hs +0/−25
ethereum-analyzer.cabal view
@@ -1,5 +1,5 @@ name: ethereum-analyzer-version: 1.3.0+version: 2.0.0 synopsis: A Ethereum contract analyzer. homepage: https://github.com/ethereumK/ethereum-analyzer license: Apache-2.0@@ -21,11 +21,13 @@ source-repository this type: git location: https://github.com/zchn/ethereum-analyzer- tag: v1.3.0+ tag: v2.0.0 subdir: ethereum-analyzer library build-depends: base >= 4 && < 5+ , GenericPretty+ , aeson , bimap , bytestring , containers@@ -35,20 +37,32 @@ , graphviz , hexstring , hoopl >= 3.10.2.1+ , pretty+ , protolude+ , split , text+ , unordered-containers+ , wl-pprint-text exposed-modules: Ethereum.Analyzer , Ethereum.Analyzer.Common , Ethereum.Analyzer.CfgAugmentPass , Ethereum.Analyzer.CfgAugWithTopNPass+ , Ethereum.Analyzer.Debug , Ethereum.Analyzer.Disasm+ , Ethereum.Analyzer.Solidity , Ethereum.Analyzer.Util other-modules: Ethereum.Analyzer.IR+ , Ethereum.Analyzer.Solidity.AstJson+ , Ethereum.Analyzer.Solidity.Finding+ , Ethereum.Analyzer.Solidity.Foreach+ , Ethereum.Analyzer.Solidity.Simple ghc-options: -Wall hs-source-dirs: src buildable: True default-language: Haskell98- default-extensions: OverloadedStrings+ default-extensions: NoImplicitPrelude+ , OverloadedStrings test-suite spec type: exitcode-stdio-1.0@@ -58,15 +72,25 @@ other-modules: Ethereum.Analyzer.CfgAugmentPassSpec , Ethereum.Analyzer.CfgAugWithTopNPassSpec , Ethereum.Analyzer.IRSpec+ , Ethereum.Analyzer.SoliditySpec+ , Ethereum.Analyzer.Solidity.ForeachSpec+ , Ethereum.Analyzer.Solidity.SimpleSpec+ , Ethereum.Analyzer.TestData.Basic+ , Ethereum.Analyzer.TestData.DaoJson+ , Ethereum.Analyzer.TestData.StorageJson , Ethereum.Analyzer.UtilSpec , Ethereum.AnalyzerSpec- , SpecCommon- build-depends: base+ build-depends: base >= 4 && < 5+ , GenericPretty , bytestring , ethereum-analyzer , ethereum-analyzer-deps , extra , hoopl , hspec+ , protolude , text+ , wl-pprint-text default-language: Haskell98+ default-extensions: NoImplicitPrelude+ , OverloadedStrings
src/Ethereum/Analyzer.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} module Ethereum.Analyzer ( module Ethereum.Analyzer.Disasm
src/Ethereum/Analyzer/CfgAugWithTopNPass.hs view
@@ -1,13 +1,13 @@ {-# LANGUAGE OverloadedStrings, FlexibleContexts,- FlexibleInstances, GADTs, Rank2Types, DeriveGeneric, TypeFamilies,- UndecidableInstances #-}+ NoImplicitPrelude, FlexibleInstances, GADTs, Rank2Types,+ TypeFamilies, UndecidableInstances #-} module Ethereum.Analyzer.CfgAugWithTopNPass ( doCfgAugWithTopNPass ) where -import Ethereum.Analyzer-import Ethereum.Analyzer.Common+import Protolude hiding (show)+ import Blockchain.ExtWord import Blockchain.VM.Opcodes as BVO import Compiler.Hoopl@@ -15,8 +15,10 @@ import Data.ByteString as DB import Data.List as DL import Data.List.Extra as DLE-import Data.Maybe as DM-import Data.Set as DS+import Data.Set as DS hiding (toList)+import Ethereum.Analyzer+import Ethereum.Analyzer.Common+import GHC.Show import Legacy.Haskoin.V0102.Network.Haskoin.Crypto.BigWord type StackElemFact = WithTop (Set Word256)@@ -25,7 +27,7 @@ :: Label -> OldFact (Set Word256) -> NewFact (Set Word256)- -> (ChangeFlag, (Set Word256))+ -> (ChangeFlag, Set Word256) joinStackElemBase _ (OldFact oldF) (NewFact newF) = if newF `isSubsetOf` oldF then (NoChange, oldF)@@ -46,14 +48,17 @@ -> (ChangeFlag, StackNFact) joinStackNFact l (OldFact oldF) (NewFact newF) = let zipped =- DL.zipWith (\a b -> joinStackElemFact l (OldFact a) (NewFact b)) oldF newF+ DL.zipWith+ (\a b -> joinStackElemFact l (OldFact a) (NewFact b))+ oldF+ newF (changedL, joinedF) = DL.unzip zipped in ( changeIf $ DL.any (\c ->- case c of- SomeChange -> True- NoChange -> False)+ case c of+ SomeChange -> True+ NoChange -> False) changedL , joinedF) @@ -78,20 +83,20 @@ case flist of [] -> mkTopList flist [_] -> mkTopList flist- Top:_:tl -> (Top : tl) ++ [Top]- _:Top:tl -> (Top : tl) ++ [Top]+ Top:_:tl -> (Top : tl) <> [Top]+ _:Top:tl -> (Top : tl) <> [Top] PElem st1:PElem st2:tl -> let l1 = toList st1- in ((PElem $ DS.unions $ DL.map (\e1 -> DS.map (fun e1) st2) l1) : tl) +++ in ((PElem $ DS.unions $ DL.map (\e1 -> DS.map (fun e1) st2) l1) : tl) <> [Top] popStack :: Int -> StackNFact -> StackNFact popStack 0 f = f-popStack n (_:t) = popStack (n - 1) (t ++ [Top])+popStack n (_:t) = popStack (n - 1) (t <> [Top]) popStack _ [] = [] pushStack' :: StackElemFact -> StackNFact -> StackNFact-pushStack' e flist = e : (DLE.dropEnd 1 flist)+pushStack' e flist = e : DLE.dropEnd 1 flist pushStack :: Word256 -> StackNFact -> StackNFact pushStack wd = pushStack' (PElem $ DS.singleton wd)@@ -127,7 +132,7 @@ if n + 1 > DL.length stk then pushTop $ popStack 1 stk else let (h1:t1, h2:t2) = DL.splitAt n stk- in (h2 : t1) ++ (h1 : t2)+ in (h2 : t1) <> (h1 : t2) stackNTransfer :: FwdTransfer HplOp StackNFact stackNTransfer = mkFTransfer3 coT ooT ocT@@ -136,12 +141,12 @@ coT _ = DL.map (\f ->- case f of- Top -> Top- PElem st ->- if DS.size st > _sizeBound- then Top- else PElem st)+ case f of+ Top -> Top+ PElem st ->+ if DS.size st > _sizeBound+ then Top+ else PElem st) ooT :: HplOp O O -> StackNFact -> StackNFact ooT (OoOp (_, op)) f = opT op f ooT (HpCodeCopy _) f = f@@ -257,12 +262,15 @@ -- opT PUSHDIFF String String flist = flist -- opT DATA ByteString flist = flist -- opT MalformedOpcode Word8 flist = flist- opT op@LABEL {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op- opT op@PUSHLABEL {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op- opT op@PUSHDIFF {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op- opT op@DATA {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op+ opT op@LABEL {} _ =+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op)+ opT op@PUSHLABEL {} _ =+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op)+ opT op@PUSHDIFF {} _ =+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op)+ opT op@DATA {} _ = panic $ "Unexpected(stackTopTransfer): " <> toS (show op) opT op@MalformedOpcode {} _ =- error $ "Unexpected(stackTopTransfer): " ++ show op+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op) -- TODO(zchn): Implement interp opT _ flist = DL.map (const Top) flist @@ -312,7 +320,7 @@ newll <- liftFuel $ labelsFor $ toList st return $ Just $- opGUnit $ OcOp (loc, ope) $ toList $ fromList (ll ++ newll)+ opGUnit $ OcOp (loc, ope) $ toList $ fromList (ll <> newll) _depthBound :: Int _depthBound = 16@@ -346,27 +354,24 @@ body (mapSingleton entry $ fact_bot $ fp_lattice cfgAugWithTopNPass)) let blocks = DL.map snd $ bodyList newBody- ooOps = DL.concatMap ((\(_, b, _) -> blockToList b) . blockSplit) blocks+ ooOps =+ DL.concatMap ((\(_, b, _) -> blockToList b) . blockSplit) blocks newHexstrings = mapMaybe (\op ->- case op of- HpCodeCopy offset ->- let newhs =- EvmBytecode $- DB.drop (fromInteger (getBigWordInteger offset)) $- unEvmBytecode (evmBytecodeOf a)- in if DB.null $ unEvmBytecode newhs- then Nothing- else Just newhs- _ -> Nothing)+ case op of+ HpCodeCopy offset ->+ let newhs =+ EvmBytecode $+ DB.drop (fromInteger (getBigWordInteger offset)) $+ unEvmBytecode (evmBytecodeOf a)+ in if DB.null $ unEvmBytecode newhs+ then Nothing+ else Just newhs+ _ -> Nothing) ooOps case newHexstrings of- [] ->- return- contract- { ctorOf = HplCode (Just entry) newBody- }+ [] -> return contract {ctorOf = HplCode (Just entry) newBody} [newhs] -> do HplCode (Just disEntry) disBody <- evmOps2HplCode $ disasm newhs newDisBody <-@@ -377,13 +382,14 @@ cfgAugWithTopNPass disEntry disBody- (mapSingleton disEntry $ fact_bot $ fp_lattice cfgAugWithTopNPass))+ (mapSingleton disEntry $+ fact_bot $ fp_lattice cfgAugWithTopNPass)) return HplContract { ctorOf = HplCode (Just entry) newBody , dispatcherOf = HplCode (Just disEntry) newDisBody } _ ->- error $- "doCfgAugWithTopNPass: unexpected newHexstrings length: " ++- (show $ DL.length newHexstrings)+ panic $+ "doCfgAugWithTopNPass: unexpected newHexstrings length: " <>+ toS (show (DL.length newHexstrings))
src/Ethereum/Analyzer/CfgAugmentPass.hs view
@@ -1,19 +1,23 @@ {-# LANGUAGE OverloadedStrings, FlexibleContexts,- FlexibleInstances, GADTs, Rank2Types, DeriveGeneric, TypeFamilies,+ FlexibleInstances, GADTs, Rank2Types, TypeFamilies, UndecidableInstances #-} module Ethereum.Analyzer.CfgAugmentPass ( doCfgAugmentPass ) where -import Ethereum.Analyzer-import Ethereum.Analyzer.Common+import Protolude hiding (show)+ import Blockchain.ExtWord import Blockchain.VM.Opcodes import Compiler.Hoopl-import Data.Bits++-- import Data.Bits import Data.List as DL-import Data.Set as DS+import Data.Set as DS hiding (toList)+import Ethereum.Analyzer+import Ethereum.Analyzer.Common+import GHC.Show type StackTopFact = WithTop (Set Word256) @@ -21,7 +25,7 @@ :: Label -> OldFact (Set Word256) -> NewFact (Set Word256)- -> (ChangeFlag, (Set Word256))+ -> (ChangeFlag, Set Word256) joinJumpTargets _ (OldFact oldF) (NewFact newF) = if newF `isSubsetOf` oldF then (NoChange, oldF)@@ -58,22 +62,24 @@ PElem $ DS.map (\wd ->- if wd == 0- then 1- else 0)+ if wd == 0+ then 1+ else 0) st opT JUMPDEST f = f opT NEG (PElem st) = PElem $ DS.map (\wd -> -wd) st opT NOT (PElem st) =- PElem $- DS.map (\wd -> bytesToWord256 $ DL.map complement $ word256ToBytes wd) st+ PElem $ DS.map (bytesToWord256 . DL.map complement . word256ToBytes) st opT (PUSH w8l) _ = PElem $ DS.singleton $ varBytesToWord256 w8l- opT op@LABEL {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op- opT op@PUSHLABEL {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op- opT op@PUSHDIFF {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op- opT op@DATA {} _ = error $ "Unexpected(stackTopTransfer): " ++ show op+ opT op@LABEL {} _ =+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op)+ opT op@PUSHLABEL {} _ =+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op)+ opT op@PUSHDIFF {} _ =+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op)+ opT op@DATA {} _ = panic $ "Unexpected(stackTopTransfer): " <> toS (show op) opT op@MalformedOpcode {} _ =- error $ "Unexpected(stackTopTransfer): " ++ show op+ panic $ "Unexpected(stackTopTransfer): " <> toS (show op) opT _ _ = Top opGUnit :: HplOp e x -> Graph HplOp e x@@ -110,7 +116,7 @@ newll <- liftFuel $ labelsFor $ toList st return $ Just $- opGUnit $ OcOp (loc, ope) $ toList $ fromList (ll ++ newll)+ opGUnit $ OcOp (loc, ope) $ toList $ fromList (ll <> newll) cfgAugmentPass :: FwdPass WordLabelMapFuelM HplOp StackTopFact cfgAugmentPass =@@ -136,7 +142,4 @@ entry body (mapSingleton entry Top))- return- contract- { ctorOf = HplCode (Just entry) newBody- }+ return contract {ctorOf = HplCode (Just entry) newBody}
src/Ethereum/Analyzer/Common.hs view
@@ -1,15 +1,44 @@+{-# LANGUAGE FlexibleContexts #-}+ module Ethereum.Analyzer.Common- ( varBytesToWord256+ ( fromRight+ , s2t4Either+ , unexpectedPanic+ , unimplementedPanic+ , varBytesToWord256 ) where -import Data.ByteString as DB-import Data.Word+import Protolude hiding (show)+ import Blockchain.ExtWord+import Data.ByteString as DB+import Data.Either (Either(..))+import GHC.Show (Show(..)) -zero256 :: ByteString-zero256 = DB.replicate 32 0+fromRight :: b -> Either a b -> b+fromRight _ (Right v) = v+fromRight v (Left _) = v +s2t4Either+ :: StringConv s Text+ => Either s a -> Either Text a+s2t4Either (Left s) = (Left $ toS s)+s2t4Either (Right r) = (Right r)++unexpectedPanic+ :: Show a+ => a -> b+unexpectedPanic n = panic . toS $ "unexpected: " ++ show n++unimplementedPanic+ :: Show a+ => a -> b+unimplementedPanic n = panic . toS $ "unimplemented: " ++ show n+ varBytesToWord256 :: [Word8] -> Word256 varBytesToWord256 w8l = let extended = (zero256 `append` DB.pack w8l) in bytesToWord256 $ DB.unpack $ DB.drop (DB.length extended - 32) extended++zero256 :: ByteString+zero256 = DB.replicate 32 0
+ src/Ethereum/Analyzer/Debug.hs view
@@ -0,0 +1,21 @@+module Ethereum.Analyzer.Debug+ ( pprintContracts+ , pprintSimpleSol+ , dbgGetSimpleSol+ ) where++import Protolude++import Compiler.Hoopl+import Ethereum.Analyzer.Common+import Ethereum.Analyzer.Solidity+import qualified Text.PrettyPrint.GenericPretty as GP++dbgGetSimpleSol :: Text -> Either Text [Contract]+dbgGetSimpleSol = decodeContracts++pprintSimpleSol :: Text -> IO ()+pprintSimpleSol = GP.pp . dbgGetSimpleSol++pprintContracts :: [Contract] -> IO ()+pprintContracts = GP.pp
src/Ethereum/Analyzer/Disasm.hs view
@@ -5,17 +5,16 @@ , disasm ) where +import Protolude hiding (show)+ import Blockchain.Data.Code import Blockchain.ExtWord import Blockchain.Util import Blockchain.VM.Code import Blockchain.VM.Opcodes-import Data.ByteString import Data.HexString-import Data.Text-import Data.Text.Encoding -class HasEvmBytecode a where+class HasEvmBytecode a where evmBytecodeOf :: a -> EvmBytecode newtype EvmBytecode = EvmBytecode@@ -27,10 +26,11 @@ } deriving (Show, Eq) instance HasEvmBytecode EvmBytecode where- evmBytecodeOf = id+ evmBytecodeOf = identity instance HasEvmBytecode EvmHexString where- evmBytecodeOf = EvmBytecode . toBytes . hexString . encodeUtf8 . unEvmHexString+ evmBytecodeOf =+ EvmBytecode . toBytes . hexString . encodeUtf8 . unEvmHexString instance HasEvmBytecode Code where evmBytecodeOf (Code bs) = EvmBytecode bs
src/Ethereum/Analyzer/IR.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE OverloadedStrings, FlexibleContexts,- FlexibleInstances, GADTs, Rank2Types, DeriveGeneric, TypeFamilies,- UndecidableInstances #-}+{-# LANGUAGE FlexibleContexts, OverloadedStrings,+ NoImplicitPrelude, FlexibleInstances, GADTs, Rank2Types,+ TypeFamilies, ScopedTypeVariables, UndecidableInstances #-} module Ethereum.Analyzer.IR ( HplBody@@ -18,16 +18,20 @@ , showOps ) where +import Protolude hiding (show)+ import Blockchain.ExtWord as BE import Blockchain.VM.Opcodes as BVO import Compiler.Hoopl as CH-import Control.Monad as CM++-- import Control.Monad as CM import Data.Bimap as DB+import Data.List as DL+import Data.String (String) -- import Data.Graph.Inductive.Graph as DGIG-import Data.Text as DT import qualified Data.Text.Lazy as DTL-import Data.List as DL+import GHC.Show import Legacy.Haskoin.V0102.Network.Haskoin.Crypto.BigWord data HplOp e x where@@ -40,21 +44,21 @@ showLoc = show . getBigWordInteger showOp :: (Word256, Operation) -> String-showOp (lineNo, op) = showLoc lineNo ++ ": " ++ show op+showOp (lineNo, op) = showLoc lineNo <> ": " <> show op showOps :: [(Word256, Operation)] -> [String]-showOps = Prelude.map showOp+showOps = fmap showOp instance Show (HplOp e x) where- show (CoOp l) = "CO: " ++ show l- show (OoOp op) = "OO: " ++ showOp op- show (OcOp op ll) = "OC: " ++ showOp op ++ " -> " ++ show ll- show (HpCodeCopy offset) = "HpCodeCopy " ++ show offset+ show (CoOp l) = "CO: " <> show l+ show (OoOp op) = "OO: " <> showOp op+ show (OcOp op ll) = "OC: " <> showOp op <> " -> " <> show ll+ show (HpCodeCopy offset) = "HpCodeCopy " <> show offset instance Show (Block HplOp C C) where- show a =+ show (a :: Block HplOp C C) = let (h, m, t) = blockSplit a- in DL.unlines $ [show h] ++ DL.map show (blockToList m) ++ [show t]+ in DL.unlines $ [show h] <> DL.map show (blockToList m) <> [show t] instance Eq (HplOp C O) where (==) (CoOp a) (CoOp b) = a == b@@ -89,22 +93,14 @@ evmOps2HplContract :: [(Word256, Operation)] -> WordLabelMapM HplContract evmOps2HplContract l = do ctorBody <- evmOps2HplCode l- return- HplContract- { ctorOf = ctorBody- , dispatcherOf = emptyCode- }+ return HplContract {ctorOf = ctorBody, dispatcherOf = emptyCode} evmOps2HplCode :: [(Word256, Operation)] -> WordLabelMapM HplCode evmOps2HplCode [] = return emptyCode evmOps2HplCode l@((loc, _):_) = do entry <- labelFor loc body <- _evmOps2HplBody l- return- HplCode- { entryOf = Just entry- , bodyOf = body- }+ return HplCode {entryOf = Just entry, bodyOf = body} _evmOps2HplBody :: [(Word256, Operation)] -> WordLabelMapM HplBody _evmOps2HplBody [] = return emptyBody@@ -112,10 +108,11 @@ l <- labelFor loc doEvmOps2HplBody emptyBody (blockJoinHead (CoOp l) emptyBlock) el where- doEvmOps2HplBody :: HplBody- -> (Block HplOp C O)- -> [(Word256, Operation)]- -> WordLabelMapM HplBody+ doEvmOps2HplBody+ :: HplBody+ -> Block HplOp C O+ -> [(Word256, Operation)]+ -> WordLabelMapM HplBody doEvmOps2HplBody body _ [] = return body -- sliently discarding bad hds doEvmOps2HplBody body hd [h'] = if isTerminator (snd h')@@ -126,13 +123,7 @@ l' <- labelFor loc' doEvmOps2HplBody (addBlock- (blockJoinTail- hd- (OcOp- h'- (if canPassThrough (snd h')- then [l']- else [])))+ (blockJoinTail hd (OcOp h' [l' | canPassThrough (snd h')])) body) (blockJoinHead (CoOp l') emptyBlock) t'@@ -141,13 +132,7 @@ l' <- labelFor loc' doEvmOps2HplBody (addBlock- (blockJoinTail- hd- (OcOp- h'- (if canPassThrough (snd h')- then [l']- else [])))+ (blockJoinTail hd (OcOp h' [l' | canPassThrough (snd h')])) body) (blockJoinHead (CoOp l') emptyBlock) t'@@ -177,7 +162,7 @@ -------------------------------------------------------------------------------- type WordLabelMap = Bimap Word256 Label -data WordLabelMapM a =+newtype WordLabelMapM a = WordLabelMapM (WordLabelMap -> SimpleUniqueMonad (WordLabelMap, a)) instance CheckpointMonad WordLabelMapM where@@ -216,8 +201,7 @@ instance Monad WordLabelMapM where return = pure WordLabelMapM f1 >>= k =- WordLabelMapM $- \m -> do+ WordLabelMapM $ \m -> do (m', x) <- f1 m let (WordLabelMapM f2) = k x f2 m'@@ -229,13 +213,10 @@ pure x = WordLabelMapM (\m -> return (m, x)) (<*>) = ap -class UnWordLabelMapM a where+class UnWordLabelMapM a where unWordLabelMapM :: WordLabelMapM a -> a instance UnWordLabelMapM Int where- unWordLabelMapM = internalUnWordLabelMapM--instance UnWordLabelMapM String where unWordLabelMapM = internalUnWordLabelMapM instance UnWordLabelMapM Text where
+ src/Ethereum/Analyzer/Solidity.hs view
@@ -0,0 +1,11 @@+module Ethereum.Analyzer.Solidity+ ( module Ethereum.Analyzer.Solidity.AstJson+ , module Ethereum.Analyzer.Solidity.Finding+ , module Ethereum.Analyzer.Solidity.Foreach+ , module Ethereum.Analyzer.Solidity.Simple+ ) where++import Ethereum.Analyzer.Solidity.AstJson+import Ethereum.Analyzer.Solidity.Finding+import Ethereum.Analyzer.Solidity.Foreach+import Ethereum.Analyzer.Solidity.Simple
+ src/Ethereum/Analyzer/Solidity/AstJson.hs view
@@ -0,0 +1,282 @@+{-# LANGUAGE DeriveGeneric #-}+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}++module Ethereum.Analyzer.Solidity.AstJson+ ( SolNode(..)+ , decodeSoleNodes+ , defSolNode+ ) where++import Protolude hiding (show)++import Data.Aeson+import Data.Aeson.Types+import Data.HashMap.Lazy hiding (map)+import Ethereum.Analyzer.Common+import GHC.Show (Show(..))+import Text.PrettyPrint.Leijen.Text as PP++decodeSoleNodes :: LByteString -> Either Text [SolNode]+decodeSoleNodes combined_ast = do+ value <- (s2t4Either (eitherDecode combined_ast) :: Either Text Value)+ case value of+ Object o1 -> do+ srcObj <-+ (maybeToRight "Could not find 'sources' in object" (lookup "sources" o1) :: Either Text Value)+ case srcObj of+ Object o2 -> do+ let srcUnitObjs = elems o2+ mapM (s2t4Either . eitherDecode . encode) (srcUnitObjs :: [Value])+ _ -> Left "'sources''s value is not an Aeson Object"+ _ -> Left "input is not an Aeson Object"++-- import Data.Default+-- import GHC.Generics+data SolNode = SolNode+ { name :: Maybe Text+ , _id :: Maybe Int+ , _type :: Maybe Text+ , _AST :: Maybe SolNode+ , attributes :: Maybe SolNode+ , constant :: Maybe Bool+ , fullyImplemented :: Maybe Bool+ , hexvalue :: Maybe Text+ , isLibrary :: Maybe Bool+ , linearizedBaseContracts :: Maybe [Int]+ , literals :: Maybe [Text]+ , member_name :: Maybe Text+ , operator :: Maybe Text+ , payable :: Maybe Bool+ , src :: Maybe Text+ , storageLocation :: Maybe Text+ , subdenomination :: Maybe Text+ , token :: Maybe Text+ , type_conversion :: Maybe Bool+ , value :: Maybe Text+ , visibility :: Maybe Text+ , children :: Maybe [SolNode]+ } deriving (Eq, Generic, Show)++instance ToJSON SolNode where+ toJSON =+ genericToJSON defaultOptions {fieldLabelModifier = dropWhile (== '_')}++instance FromJSON SolNode where+ parseJSON =+ genericParseJSON defaultOptions {fieldLabelModifier = dropWhile (== '_')}++defSolNode :: SolNode+defSolNode =+ SolNode+ { children = Nothing+ , _id = Nothing+ , _type = Nothing+ , _AST = Nothing+ , attributes = Nothing+ , constant = Nothing+ , fullyImplemented = Nothing+ , hexvalue = Nothing+ , isLibrary = Nothing+ , linearizedBaseContracts = Nothing+ , literals = Nothing+ , member_name = Nothing+ , name = Nothing+ , operator = Nothing+ , payable = Nothing+ , src = Nothing+ , storageLocation = Nothing+ , subdenomination = Nothing+ , token = Nothing+ , type_conversion = Nothing+ , value = Nothing+ , visibility = Nothing+ }++instance Pretty SolNode where+ pretty n@SolNode {name = name}+ | name == Nothing = prettyAst n -- Top level AST+ | name == Just "SourceUnit" = prettySourceUnit n+ | name == Just "PragmaDirective" = PP.empty+ | name == Just "ContractDefinition" = prettyContractDefinition n+ | name == Just "VariableDeclaration" = prettyVariableDeclaration n+ | name == Just "ElementaryTypeName" = prettyElementTypeName n+ | name == Just "FunctionDefinition" = prettyFunctionDefinition n+ | name == Just "ParameterList" = prettyParameterList n+ | name == Just "Block" = prettyBlock n+ | name == Just "ExpressionStatement" = prettyExpressionStatement n+ | name == Just "Assignment" = prettyAssignment n+ | name == Just "Identifier" = prettyIdentifier n+ | name == Just "Return" = prettyReturn n+ | name == Just "Mapping" = prettyMapping n+ | name == Just "IndexAccess" = prettyIndexAccess n+ | name == Just "MemberAccess" = prettyMemberAccess n+ | name == Just "IfStatement" = prettyIfStatement n+ | name == Just "BinaryOperation" = prettyBinaryOperation n+ | name == Just "VariableDeclarationStatement" =+ prettyVariableDeclarationStatement n+ | name == Just "FunctionCall" = prettyFunctionCall n+ | name == Just "UserDefinedTypeName" = prettyUserDefinedTypeName n+ | name == Just "Literal" = prettyLiteral n+ | otherwise = panic . toS $ "unimplemented: " <> showWithoutChildren n++showWithoutChildren :: SolNode -> Text+showWithoutChildren n = toS $ show (n {children = Nothing})++prettyAst :: SolNode -> Doc+prettyAst SolNode {name = Nothing, _AST = Just ast} = pretty ast+prettyAst n = unexpectedPanic n++prettySourceUnit :: SolNode -> Doc+prettySourceUnit SolNode {name = Just "SourceUnit", children = Just children} =+ textStrict "//--SourceUnit--" PP.<$> vsep (map pretty children)+prettySourceUnit n = unexpectedPanic n++prettyContractDefinition :: SolNode -> Doc+prettyContractDefinition SolNode { name = Just "ContractDefinition"+ , children = Just children+ , attributes = Just SolNode { children = Nothing+ , name = Just cName+ }+ } =+ textStrict "contract" </> textStrict cName </>+ semiBraces (map pretty children)+prettyContractDefinition n = unexpectedPanic n++prettyVariableDeclaration :: SolNode -> Doc+prettyVariableDeclaration SolNode { name = Just "VariableDeclaration"+ -- , children = Just children+ , children = Just _+ , attributes = Just SolNode { children = Nothing+ , name = Just vName+ , _type = Just vType+ }+ }+ -- textStrict (vType <> "/") <> (tupled $ map pretty children) </> textStrict vName+ = textStrict vType </> textStrict vName+prettyVariableDeclaration n = unexpectedPanic n++prettyElementTypeName :: SolNode -> Doc+prettyElementTypeName SolNode { name = Just "ElementaryTypeName"+ , children = Nothing+ , attributes = Just SolNode {name = Just veType}+ } = textStrict veType+prettyElementTypeName n = unexpectedPanic n++prettyFunctionDefinition :: SolNode -> Doc+prettyFunctionDefinition SolNode { name = Just "FunctionDefinition"+ , children = Just [params, returns, body]+ , attributes = Just SolNode { children = Nothing+ , name = Just fName+ }+ } =+ textStrict "fun" </>+ align (textStrict fName </> cat (map pretty [params, returns, body]))+prettyFunctionDefinition n = unexpectedPanic n++prettyParameterList :: SolNode -> Doc+prettyParameterList SolNode { name = Just "ParameterList"+ , children = Just pChildren+ } =+ parens (align (cat (punctuate comma $ map pretty pChildren)))+prettyParameterList n = unexpectedPanic n++prettyBlock :: SolNode -> Doc+prettyBlock SolNode {name = Just "Block", children = Just children} =+ semiBraces $ map pretty children+prettyBlock n = unexpectedPanic n++prettyExpressionStatement :: SolNode -> Doc+prettyExpressionStatement SolNode { name = Just "ExpressionStatement"+ , children = Just children+ } = tupled $ map pretty children+prettyExpressionStatement n = unexpectedPanic n++prettyAssignment :: SolNode -> Doc+prettyAssignment SolNode { name = Just "Assignment"+ , children = Just [lval, rval]+ , attributes = Just SolNode { _type = Just _+ , operator = Just operator+ }+ } = pretty lval <> textStrict operator <> pretty rval+prettyAssignment n = unexpectedPanic n++prettyIdentifier :: SolNode -> Doc+prettyIdentifier SolNode { name = Just "Identifier"+ , children = Nothing+ , attributes = Just SolNode { _type = Just _ -- _type+ , value = Just idName+ }+ } -- textStrict (idName <> ":" <> _type)+ = textStrict idName+prettyIdentifier n = unexpectedPanic n++prettyReturn :: SolNode -> Doc+prettyReturn SolNode {name = Just "Return", children = Just children} =+ textStrict "return" <> tupled (map pretty children)+prettyReturn n = unexpectedPanic n++prettyMapping :: SolNode -> Doc+prettyMapping SolNode {name = Just "Mapping", children = Just children} =+ textStrict "mapping" <> tupled (map pretty children)+prettyMapping n = unexpectedPanic n++prettyIndexAccess :: SolNode -> Doc+prettyIndexAccess SolNode { name = Just "IndexAccess"+ , children = Just (c1:ctail)+ , attributes = Just SolNode {_type = Just _}+ } = pretty c1 <> pretty ctail+prettyIndexAccess n = unexpectedPanic n++prettyMemberAccess :: SolNode -> Doc+prettyMemberAccess SolNode { name = Just "MemberAccess"+ , children = Just [obj]+ , attributes = Just SolNode { _type = Just _+ , member_name = Just mName+ }+ } = pretty obj <> textStrict "." <> textStrict mName+prettyMemberAccess n = unexpectedPanic n++prettyIfStatement :: SolNode -> Doc+prettyIfStatement SolNode {name = Just "IfStatement", children = Just children} =+ textStrict "if" <> tupled (map pretty children)+prettyIfStatement n = unexpectedPanic n++prettyBinaryOperation :: SolNode -> Doc+prettyBinaryOperation SolNode { name = Just "BinaryOperation"+ , children = Just [op1, op2]+ , attributes = Just SolNode { _type = Just _+ , operator = Just vOp+ }+ } =+ parens (pretty op1 <> textStrict vOp <> pretty op2)+prettyBinaryOperation n = unexpectedPanic n++prettyVariableDeclarationStatement :: SolNode -> Doc+prettyVariableDeclarationStatement SolNode { name = Just "VariableDeclarationStatement"+ , children = Just [vdec, vinit]+ } =+ pretty vdec </> textStrict "=" </> pretty vinit+prettyVariableDeclarationStatement n = unexpectedPanic n++prettyFunctionCall :: SolNode -> Doc+prettyFunctionCall SolNode { name = Just "FunctionCall"+ , children = Just (func:params)+ , attributes = Just SolNode {_type = Just _}+ } = pretty func <> tupled (map pretty params)+prettyFunctionCall n = unexpectedPanic n++prettyUserDefinedTypeName :: SolNode -> Doc+prettyUserDefinedTypeName SolNode { name = Just "UserDefinedTypeName"+ , children = Nothing+ , attributes = Just SolNode {name = Just vName}+ } = textStrict vName+prettyUserDefinedTypeName n = unexpectedPanic n++prettyLiteral :: SolNode -> Doc+prettyLiteral SolNode { name = Just "Literal"+ , children = Nothing+ , attributes = Just SolNode { _type = Just _+ , value = Just vValue+ }+ } = textStrict vValue+prettyLiteral n = unexpectedPanic n
+ src/Ethereum/Analyzer/Solidity/Finding.hs view
@@ -0,0 +1,20 @@+module Ethereum.Analyzer.Solidity.Finding+ ( findingsFor+ ) where++import Protolude++import Ethereum.Analyzer.Solidity.Foreach+import Ethereum.Analyzer.Solidity.Simple++findingsFor :: Contract -> [Text]+findingsFor = selfdestruct++selfdestruct :: Contract -> [Text]+selfdestruct c = concatMap sdExp $ expressionsOf c+ where+ sdExp exp =+ case exp of+ ExpCall (JustId (Idfr "suicide")) _ ->+ ["Prefer 'selfdestruct' than 'suicide'."]+ _ -> []
+ src/Ethereum/Analyzer/Solidity/Foreach.hs view
@@ -0,0 +1,39 @@+module Ethereum.Analyzer.Solidity.Foreach+ ( statementsOf+ , expressionsOf+ ) where++import Protolude++import Data.List (concatMap)+import Ethereum.Analyzer.Common+import Ethereum.Analyzer.Solidity.Simple++statementsOf :: Contract -> [Statement]+statementsOf = _sOf++class HasStatements a where+ _sOf :: a -> [Statement]++instance HasStatements Contract where+ _sOf Contract {cFunctions = funs} = concatMap _sOf funs++instance HasStatements FunDefinition where+ _sOf FunDefinition {fBody = stmts} = concatMap _sOf stmts++instance HasStatements Statement where+ _sOf s@(StIf _ thenSts elseSts) =+ [s] <> concatMap _sOf thenSts <> concatMap _sOf elseSts+ _sOf s = [s]++expressionsOf :: Contract -> [Expression]+expressionsOf c = concatMap _eOf $ statementsOf c++_eOf :: Statement -> [Expression]+_eOf (StLocalVarDecl _) = []+_eOf (StAssign _ e) = [e]+_eOf (StIf _ _ _) = []+_eOf (StReturn _) = []+_eOf (StDelete _) = []+_eOf st@(StTodo _) = unimplementedPanic st+_eOf StThrow = []
+ src/Ethereum/Analyzer/Solidity/Simple.hs view
@@ -0,0 +1,306 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}++module Ethereum.Analyzer.Solidity.Simple+ ( Contract(..)+ , VarDecl(..)+ , Idfr(..)+ , LValue(..)+ , VarType(..)+ , FunDefinition(..)+ , Statement(..)+ , Expression(..)+ , s2sContracts+ , decodeContracts+ ) where++import Protolude hiding (show)++import Compiler.Hoopl+import Ethereum.Analyzer.Common+import Ethereum.Analyzer.Solidity.AstJson+import GHC.Show (Show(..))+import Text.PrettyPrint.Leijen.Text hiding ((<$>))++import qualified Text.PrettyPrint as PP+import qualified Text.PrettyPrint.GenericPretty as GP++decodeContracts :: Text -> Either Text [Contract]+decodeContracts astJsonText = do+ solNodes <- decodeSoleNodes (toS astJsonText)+ let mContracts = mapM s2sContracts solNodes+ let contracts = concat $ runSimpleUniqueMonad mContracts+ return contracts++data Contract = Contract+ { cName :: Text+ , cStateVars :: [VarDecl]+ , cFunctions :: [FunDefinition]+ } deriving (Eq, Generic, Show, GP.Out)++data VarDecl = VarDecl+ { vName :: Idfr+ , vType :: VarType+ } deriving (Eq, Generic, Show, GP.Out)++newtype Idfr =+ Idfr Text+ deriving (Eq, Generic, Show, GP.Out)++data LValue+ = JustId Idfr+ | Index { iArray :: LValue+ , iIndex :: LValue}+ | Member { mObj :: LValue+ , mField :: Idfr}+ deriving (Eq, Generic, Show, GP.Out)++data VarType+ = Int256+ | Uint256+ | Address+ | Mapping VarType+ VarType+ | Unknown Text+ deriving (Eq, Generic, Show, GP.Out)++data FunDefinition = FunDefinition+ { fName :: Idfr+ , fParams :: [VarDecl]+ , fReturns :: [VarDecl]+ , fBody :: [Statement]+ } deriving (Eq, Generic, Show, GP.Out)++data Statement+ = StLocalVarDecl VarDecl+ | StAssign LValue+ Expression+ | StIf LValue+ [Statement]+ [Statement]+ | StReturn [LValue]+ | StDelete LValue+ | StTodo Text+ | StThrow+ deriving (Eq, Generic, Show, GP.Out)++data Expression+ = ExpUnary Text+ LValue+ | ExpBin Text+ LValue+ LValue+ | ExpLiteral Text+ | ExpLval LValue+ | ExpCall LValue+ [LValue]+ deriving (Eq, Generic, Show, GP.Out)++instance GP.Out Text where+ doc = PP.quotes . PP.text . toS+ docPrec _ = GP.doc++instance GP.Out SolNode++s2sContracts+ :: UniqueMonad m+ => SolNode -> m [Contract]+s2sContracts SolNode {_AST = Just n} = s2sContracts n+s2sContracts SolNode {name = Just "SourceUnit", children = Just sChildren} =+ concat <$> mapM s2sContracts sChildren+s2sContracts SolNode { name = Just "ContractDefinition"+ , children = Just vChildren+ , attributes = Just SolNode {name = Just cName}+ } = do+ (vars, funs) <- s2sVarsFuns vChildren+ return [Contract cName vars funs]+ where+ s2sVarsFuns+ :: UniqueMonad m+ => [SolNode] -> m ([VarDecl], [FunDefinition])+ s2sVarsFuns [] = return ([], [])+ s2sVarsFuns (h:t) = do+ (vars', funs') <- s2sVarsFuns t+ hFuns <- s2sFuns h+ return (s2sVarDecls h <> vars', hFuns <> funs')+s2sContracts _ = return []++-- s2sContracts n = unexpectedPanic n+s2sVarDecls :: SolNode -> [VarDecl]+s2sVarDecls SolNode { name = Just "VariableDeclaration"+ , attributes = Just SolNode { name = Just vName+ , _type = Just vType+ }+ } = [VarDecl (Idfr vName) (Unknown vType)]+s2sVarDecls SolNode {name = Just "ParameterList", children = Just pChildren} =+ concat (map s2sVarDecls pChildren)+s2sVarDecls _ = []++s2sFuns+ :: UniqueMonad m+ => SolNode -> m [FunDefinition]+s2sFuns SolNode { name = Just "FunctionDefinition"+ , children = Just [params, returns, body]+ , attributes = Just SolNode {name = Just fName}+ } = do+ sBody <- s2sStatements body+ return+ [ FunDefinition+ (Idfr fName)+ (s2sVarDecls params)+ (s2sVarDecls returns)+ sBody+ ]+s2sFuns _ = return []++s2sStatements+ :: UniqueMonad m+ => SolNode -> m [Statement]+s2sStatements SolNode {name = Just "Block", children = Just sChildren} =+ concat <$> (mapM s2sStatements sChildren)+s2sStatements SolNode { name = Just "ExpressionStatement"+ , children = Just sChildren+ } = concat <$> (mapM s2sStatements sChildren)+s2sStatements SolNode { name = Just "Assignment"+ , children = Just [lval, rval]+ , attributes = Just SolNode {operator = Just op}+ } = do+ (prelval, simpleLval) <- s2sLval lval+ (prerval, simpleRval) <- s2sLval rval+ return $ prerval <> prelval <> [StAssign simpleLval $ ExpLval simpleRval]+s2sStatements e@SolNode {name = Just "Return", children = Just sChildren} = do+ presAndRvals <- mapM s2sLval sChildren+ let prerval = concat (map fst presAndRvals)+ let simpleRvals = map snd presAndRvals+ return $ prerval <> [StReturn simpleRvals]+s2sStatements e@SolNode { name = Just "UnaryOperation"+ , children = Just [op1]+ , attributes = Just SolNode {operator = Just "delete"}+ } = do+ (preOp1, lvalOp1) <- s2sLval op1+ newVar <- uniqueVar+ return $ preOp1 <> [StDelete (JustId $ Idfr newVar)]+s2sStatements e@SolNode { name = Just "UnaryOperation"+ , children = Just [SolNode { name = Just "Identifier"+ , attributes = Just SolNode {value = Just idName}+ }]+ , attributes = Just SolNode {operator = Just "++"}+ } = do+ let idfr = JustId $ Idfr idName+ newVar <- uniqueVar+ let newidfr = JustId $ Idfr newVar+ return+ [StAssign newidfr $ ExpLiteral "1", StAssign idfr $ ExpBin "+" idfr newidfr]+s2sStatements SolNode { name = Just "IfStatement"+ , children = Just [cond, thenBr]+ } = do+ (precond, lvalcond) <- s2sLval cond+ thenSts <- s2sStatements thenBr+ return $ precond <> [StIf lvalcond thenSts []]+s2sStatements SolNode { name = Just "IfStatement"+ , children = Just [cond, thenBr, elseBr]+ } = do+ (precond, lvalcond) <- s2sLval cond+ thenSts <- s2sStatements thenBr+ elseSts <- s2sStatements elseBr+ return $ precond <> [StIf lvalcond thenSts elseSts]+s2sStatements SolNode { name = Just "VariableDeclarationStatement"+ , children = Just [vdec@SolNode {name = Just "VariableDeclaration"}, vinit]+ } = do+ let varDecl@(VarDecl vId _):_ =+ s2sVarDecls vdec -- because VariableDeclaration only emits one decl+ (preDef, lvalDef) <- s2sLval vinit+ return $+ preDef <> [StLocalVarDecl varDecl] <>+ [StAssign (JustId vId) (ExpLval lvalDef)]+s2sStatements n@SolNode {name = Just "FunctionCall"} = do+ (precall, lvalcall) <- s2sLval n+ return $ precall <> [StAssign (JustId $ Idfr "_") (ExpLval lvalcall)]+s2sStatements SolNode {name = Just "VariableDeclarationStatement"}+ -- TODO(zchn): Handle this properly.+ = return []+s2sStatements SolNode {name = Just "Throw"} = return [StThrow]+s2sStatements s = unimplementedPanic s {children = Nothing}++s2sLval+ :: UniqueMonad m+ => SolNode -> m ([Statement], LValue)+s2sLval SolNode { name = Just "Identifier"+ , attributes = Just SolNode {value = Just idName}+ } = return ([], JustId (Idfr idName))+s2sLval SolNode { name = Just "MemberAccess"+ , children = Just [obj]+ , attributes = Just SolNode { _type = Just _+ , member_name = Just mName+ }+ } = do+ (prelval, simpleLval) <- s2sLval obj+ return (prelval, Member simpleLval (Idfr mName))+s2sLval n@SolNode {name = Just "IndexAccess", children = Just (c1:ctail)} = do+ (prelval, simpleLval) <- s2sLval c1+ (presub, simpleLvalSub) <- handleSubscription simpleLval ctail+ return (presub <> prelval, Index simpleLval simpleLvalSub)+ where+ handleSubscription+ :: UniqueMonad m+ => LValue -> [SolNode] -> m ([Statement], LValue)+ handleSubscription lv [] = unexpectedPanic lv+ handleSubscription lv [subNode] = do+ (presub', simpleLvalSub') <- s2sLval subNode+ return (presub', Index lv simpleLvalSub')+ handleSubscription lv (subNode:t) = do+ (presub', simpleLvalSub') <- handleSubscription lv [subNode]+ (presub'', simpleLvalSub'') <- handleSubscription simpleLvalSub' t+ return (presub'' <> presub', simpleLvalSub'')+s2sLval SolNode { name = Just "UnaryOperation"+ , children = Just [op1]+ , attributes = Just SolNode {operator = Just vOp}+ } = do+ (preOp1, lvalOp1) <- s2sLval op1+ newVar <- uniqueVar+ return+ ( preOp1 <> [StAssign (JustId $ Idfr newVar) (ExpUnary vOp lvalOp1)]+ , JustId $ Idfr newVar)+s2sLval SolNode { name = Just "BinaryOperation"+ , children = Just [op1, op2]+ , attributes = Just SolNode {operator = Just vOp}+ } = do+ (preOp1, lvalOp1) <- s2sLval op1+ (preOp2, lvalOp2) <- s2sLval op2+ newVar <- uniqueVar+ return+ ( preOp1 <> preOp2 <>+ [StAssign (JustId $ Idfr newVar) (ExpBin vOp lvalOp1 lvalOp2)]+ , JustId $ Idfr newVar)+s2sLval SolNode {name = Just "FunctionCall", children = Just (func:params)} = do+ (preFun, lvalFun) <- s2sLval func+ preAndlvals <- mapM s2sLval params+ let preArgs = concat (map fst preAndlvals) -- TODO(zchn): reverse?+ let lvalArgs = map snd preAndlvals+ newVar <- uniqueVar+ return+ ( preArgs <> preFun <>+ [StAssign (JustId $ Idfr newVar) (ExpCall lvalFun lvalArgs)]+ , JustId $ Idfr newVar)+s2sLval SolNode { name = Just "Literal"+ , attributes = Just SolNode {value = Just vValue}+ } = do+ newVar <- uniqueVar+ return+ ( [StAssign (JustId $ Idfr newVar) (ExpLiteral vValue)]+ , JustId $ Idfr newVar)+s2sLval SolNode { name = Just "ElementaryTypeNameExpression"+ , attributes = Just SolNode {value = Just v}+ } = return ([], JustId $ Idfr v)+s2sLval n = unimplementedPanic n {children = Nothing}++uniqueVar+ :: UniqueMonad m+ => m Text+uniqueVar = ("v" <>) . toS . show <$> freshUnique++-- lastLvalOf :: [Statement] -> LValue+-- lastLvalOf [_, StAssign lval _] = lval+-- lastLvalOf (_ : t) = lastLvalOf t+-- lastLvalOf _ = errorLValue+errorLValue = JustId (Idfr "ERROR!")
src/Ethereum/Analyzer/Util.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE OverloadedStrings, FlexibleContexts,- OverloadedStrings, FlexibleInstances, GADTs, Rank2Types,- DeriveGeneric, TypeFamilies, UndecidableInstances #-}+{-# LANGUAGE FlexibleContexts, FlexibleInstances, GADTs,+ NoImplicitPrelude, Rank2Types, TypeFamilies, UndecidableInstances+ #-} module Ethereum.Analyzer.Util ( toDotText@@ -8,17 +8,20 @@ , disasmToDotText2 ) where -import Ethereum.Analyzer.Disasm-import Ethereum.Analyzer.IR-import Ethereum.Analyzer.CfgAugWithTopNPass-import Ethereum.Analyzer.CfgAugmentPass+import Protolude hiding (show)+ import Compiler.Hoopl-import Data.GraphViz-import Data.GraphViz.Printing import Data.Graph.Inductive.Graph as DGIG import Data.Graph.Inductive.PatriciaTree-import Data.Text as DT+import Data.GraphViz+import Data.GraphViz.Printing hiding ((<>)) import qualified Data.Text.Lazy as DTL+import Ethereum.Analyzer.CfgAugWithTopNPass+import Ethereum.Analyzer.CfgAugmentPass+import Ethereum.Analyzer.Disasm+import Ethereum.Analyzer.IR+import GHC.Show+import Text.Read (read) disasmToDotText :: HasEvmBytecode a@@ -26,9 +29,9 @@ disasmToDotText a = let disasmd = disasm a result =- unWordLabelMapM $- do contract <- evmOps2HplContract disasmd- toDotText <$> (bodyOf . ctorOf <$> doCfgAugmentPass contract)+ unWordLabelMapM $ do+ contract <- evmOps2HplContract disasmd+ toDotText <$> (bodyOf . ctorOf <$> doCfgAugmentPass contract) in result disasmToDotText2@@ -36,11 +39,11 @@ => a -> (Text, Text) disasmToDotText2 a = let result =- unWordLabelMapM $- do contract' <- doCfgAugWithTopNPass a- return- ( toDotText $ bodyOf (ctorOf contract')- , toDotText $ bodyOf (dispatcherOf contract'))+ unWordLabelMapM $ do+ contract' <- doCfgAugWithTopNPass a+ return+ ( toDotText $ bodyOf (ctorOf contract')+ , toDotText $ bodyOf (dispatcherOf contract')) in result toDotText :: HplBody -> Text@@ -52,14 +55,13 @@ toGr :: HplBody -> Gr (Block HplOp C C) () toGr bd =- let lblToNode l = read (Prelude.drop 1 $ show l)+ let lblToNode l = read (drop 1 $ toS $ show l) (nList, eList) = mapFoldWithKey (\lbl blk (nList', eList') ->- let node = lblToNode lbl- edgs =- Prelude.map (\l -> (node, lblToNode l, ())) (successors blk)- in (nList' ++ [(node, blk)], eList' ++ edgs))+ let node = lblToNode lbl+ edgs = map (\l -> (node, lblToNode l, ())) (successors blk)+ in (nList' <> [(node, blk)], eList' <> edgs)) ([], []) bd in mkGraph nList eList@@ -69,8 +71,7 @@ GraphvizParams n (Block HplOp C C) el () (Block HplOp C C) visParams = nonClusteredParams- { fmtNode = \(_, nl) -> [toLabel $ show nl, shape BoxShape]- }+ {fmtNode = \(_, nl) -> [textLabel (toS $ show nl), shape BoxShape]} toDotGraph :: Gr (Block HplOp C C) () -> DotGraph Node-toDotGraph gr = graphToDot visParams gr+toDotGraph = graphToDot visParams
test/Ethereum/Analyzer/CfgAugWithTopNPassSpec.hs view
@@ -1,20 +1,29 @@-{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings, NoImplicitPrelude, FlexibleContexts+ #-} module Ethereum.Analyzer.CfgAugWithTopNPassSpec ( spec ) where +import Protolude hiding (show)++import Data.Text as DT import Ethereum.Analyzer import Ethereum.Analyzer.CfgAugWithTopNPass-import SpecCommon+import Ethereum.Analyzer.TestData.Basic+import GHC.Show import Test.Hspec spec :: Spec-spec = do- describe "doCfgAugWithTopNPass" $- do it "works for hexstring1" $- do let result = unWordLabelMapM $ show <$> doCfgAugWithTopNPass hexstring1- length result `shouldBe` 4815- it "works for hexstring2" $- do let result = unWordLabelMapM $ show <$> doCfgAugWithTopNPass hexstring2- result `shouldContain` "OC: 9: JUMPI -> [L2,L4]"+spec =+ describe "doCfgAugWithTopNPass" $ do+ it "works for hexstring1" $ do+ let result =+ unWordLabelMapM $ toS . show <$> doCfgAugWithTopNPass hexstring1+ DT.length result `shouldBe` 4815+ it "works for hexstring2" $ do+ let result =+ toS $+ unWordLabelMapM+ ((toS . show <$> doCfgAugWithTopNPass hexstring2) :: WordLabelMapM Text)+ result `shouldContain` "OC: 9: JUMPI -> [L2,L4]"
test/Ethereum/Analyzer/CfgAugmentPassSpec.hs view
@@ -4,169 +4,178 @@ ( spec ) where +import Protolude hiding (show)++import Data.Text (length) import Ethereum.Analyzer import Ethereum.Analyzer.CfgAugmentPass-import SpecCommon+import Ethereum.Analyzer.TestData.Basic+import GHC.Show import Test.Hspec spec :: Spec-spec = do- describe "doCfgAugmentPass" $- do it "works for hexstring1" $- do let disasmd = disasm hexstring1- result =- unWordLabelMapM $- do contract <- evmOps2HplContract disasmd- show <$> doCfgAugmentPass contract- length result `shouldBe` 4769- it "works for hexstring2" $- do let disasmd@((_, _):_) = disasm hexstring2- result =- unWordLabelMapM $- do contract <- evmOps2HplContract disasmd- show . bodyOf . ctorOf <$> doCfgAugmentPass contract- result `shouldBe` "LM (UM (fromList [(1,CO: L1\n" ++- "OO: 0: PUSH [96]\n" ++- "OO: 2: PUSH [64]\n" ++- "OO: 4: MSTORE\n" ++- "OO: 5: CALLDATASIZE\n" ++- "OO: 6: ISZERO\n" ++- "OO: 7: PUSH [39]\n" ++- "OC: 9: JUMPI -> [L2,L4]\n" ++- "),(2,CO: L2\n" ++- "OO: 10: PUSH [224]\n" ++- "OO: 12: PUSH [2]\n" ++- "OO: 14: EXP\n" ++- "OO: 15: PUSH [0]\n" ++- "OO: 17: CALLDATALOAD\n" ++- "OO: 18: DIV\n" ++- "OO: 19: PUSH [65,192,225,181]\n" ++- "OO: 24: DUP2\n" ++- "OO: 25: EQ\n" ++- "OO: 26: PUSH [110]\n" ++- "OC: 28: JUMPI -> [L3,L7]\n" ++- "),(3,CO: L3\n" ++- "OO: 29: DUP1\n" ++- "OO: 30: PUSH [229,34,83,129]\n" ++- "OO: 35: EQ\n" ++- "OO: 36: PUSH [150]\n" ++- "OC: 38: JUMPI -> [L4,L9]\n" ++- "),(4,CO: L4\n" ++- "OO: 39: JUMPDEST\n" ++- "OO: 40: PUSH [213]\n" ++- "OO: 42: PUSH [0]\n" ++- "OO: 44: CALLVALUE\n" ++- "OO: 45: GT\n" ++- "OO: 46: ISZERO\n" ++- "OO: 47: PUSH [108]\n" ++- "OC: 49: JUMPI -> [L5,L6]\n" ++- "),(5,CO: L5\n" ++- "OO: 50: CALLVALUE\n" ++- "OO: 51: PUSH [96]\n" ++- "OO: 53: SWAP1\n" ++- "OO: 54: DUP2\n" ++- "OO: 55: MSTORE\n" ++- "OO: 56: PUSH [88]\n" ++- "OO: 58: SWAP1\n" ++- "OO: 59: PUSH [1]\n" ++- "OO: 61: PUSH [160]\n" ++- "OO: 63: PUSH [2]\n" ++- "OO: 65: EXP\n" ++- "OO: 66: SUB\n" ++- "OO: 67: CALLER\n" ++- "OO: 68: AND\n" ++- "OO: 69: SWAP1\n" ++- "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\n" ++- "OO: 103: SWAP1\n" ++- "OO: 104: PUSH [32]\n" ++- "OO: 106: SWAP1\n" ++- "OC: 107: LOG3 -> [L6]\n" ++- "),(6,CO: L6\n" ++- "OO: 108: JUMPDEST\n" ++- "OC: 109: JUMP -> []\n" ++- "),(7,CO: L7\n" ++- "OO: 110: JUMPDEST\n" ++- "OO: 111: PUSH [213]\n" ++- "OO: 113: PUSH [0]\n" ++- "OO: 115: SLOAD\n" ++- "OO: 116: PUSH [1]\n" ++- "OO: 118: PUSH [160]\n" ++- "OO: 120: PUSH [2]\n" ++- "OO: 122: EXP\n" ++- "OO: 123: SUB\n" ++- "OO: 124: SWAP1\n" ++- "OO: 125: DUP2\n" ++- "OO: 126: AND\n" ++- "OO: 127: CALLER\n" ++- "OO: 128: SWAP2\n" ++- "OO: 129: SWAP1\n" ++- "OO: 130: SWAP2\n" ++- "OO: 131: AND\n" ++- "OO: 132: EQ\n" ++- "OO: 133: ISZERO\n" ++- "OO: 134: PUSH [108]\n" ++- "OC: 136: JUMPI -> [L6,L8]\n" ++- "),(8,CO: L8\n" ++- "OO: 137: PUSH [0]\n" ++- "OO: 139: SLOAD\n" ++- "OO: 140: PUSH [1]\n" ++- "OO: 142: PUSH [160]\n" ++- "OO: 144: PUSH [2]\n" ++- "OO: 146: EXP\n" ++- "OO: 147: SUB\n" ++- "OO: 148: AND\n" ++- "OC: 149: SUICIDE -> []\n" ++- "),(9,CO: L9\n" ++- "OO: 150: JUMPDEST\n" ++- "OO: 151: PUSH [213]\n" ++- "OO: 153: PUSH [0]\n" ++- "OO: 155: SLOAD\n" ++- "OO: 156: PUSH [1]\n" ++- "OO: 158: PUSH [160]\n" ++- "OO: 160: PUSH [2]\n" ++- "OO: 162: EXP\n" ++- "OO: 163: SUB\n" ++- "OO: 164: SWAP1\n" ++- "OO: 165: DUP2\n" ++- "OO: 166: AND\n" ++- "OO: 167: CALLER\n" ++- "OO: 168: SWAP2\n" ++- "OO: 169: SWAP1\n" ++- "OO: 170: SWAP2\n" ++- "OO: 171: AND\n" ++- "OO: 172: EQ\n" ++- "OO: 173: ISZERO\n" ++- "OO: 174: PUSH [108]\n" ++- "OC: 176: JUMPI -> [L6,L10]\n" ++- "),(10,CO: L10\n" ++- "OO: 177: PUSH [0]\n" ++- "OO: 179: DUP1\n" ++- "OO: 180: SLOAD\n" ++- "OO: 181: PUSH [1]\n" ++- "OO: 183: PUSH [160]\n" ++- "OO: 185: PUSH [2]\n" ++- "OO: 187: EXP\n" ++- "OO: 188: SUB\n" ++- "OO: 189: SWAP1\n" ++- "OO: 190: DUP2\n" ++- "OO: 191: AND\n" ++- "OO: 192: SWAP2\n" ++- "OO: 193: SWAP1\n" ++- "OO: 194: ADDRESS\n" ++- "OO: 195: AND\n" ++- "OO: 196: BALANCE\n" ++- "OO: 197: PUSH [96]\n" ++- "OO: 199: DUP3\n" ++- "OO: 200: DUP2\n" ++- "OO: 201: DUP2\n" ++- "OO: 202: DUP2\n" ++- "OO: 203: DUP6\n" ++- "OO: 204: DUP9\n" ++- "OO: 205: DUP4\n" ++- "OC: 206: CALL -> [L11]\n" ++- "),(11,CO: L11\n" ++- "OO: 207: POP\n" ++- "OO: 208: POP\n" ++- "OO: 209: POP\n" ++- "OO: 210: POP\n" ++- "OO: 211: POP\n" ++ "OC: 212: JUMP -> []\n" ++ ")]))"+spec =+ describe "doCfgAugmentPass" $ do+ it "works for hexstring1" $ do+ let disasmd = disasm hexstring1+ result =+ unWordLabelMapM $ do+ contract <- evmOps2HplContract disasmd+ (toS . show <$> doCfgAugmentPass contract) :: WordLabelMapM Text+ Data.Text.length result `shouldBe` 4769+ it "works for hexstring2" $ do+ let disasmd@((_, _):_) = disasm hexstring2+ result =+ unWordLabelMapM $ do+ contract <- evmOps2HplContract disasmd+ toS . show . bodyOf . ctorOf <$> doCfgAugmentPass contract+ result `shouldBe` expectedHexString2CtorBody++expectedHexString2CtorBody :: Text+expectedHexString2CtorBody =+ "LM (UM (fromList [(1,CO: L1\n" <> "OO: 0: PUSH [96]\n" <>+ "OO: 2: PUSH [64]\n" <>+ "OO: 4: MSTORE\n" <>+ "OO: 5: CALLDATASIZE\n" <>+ "OO: 6: ISZERO\n" <>+ "OO: 7: PUSH [39]\n" <>+ "OC: 9: JUMPI -> [L2,L4]\n" <>+ "),(2,CO: L2\n" <>+ "OO: 10: PUSH [224]\n" <>+ "OO: 12: PUSH [2]\n" <>+ "OO: 14: EXP\n" <>+ "OO: 15: PUSH [0]\n" <>+ "OO: 17: CALLDATALOAD\n" <>+ "OO: 18: DIV\n" <>+ "OO: 19: PUSH [65,192,225,181]\n" <>+ "OO: 24: DUP2\n" <>+ "OO: 25: EQ\n" <>+ "OO: 26: PUSH [110]\n" <>+ "OC: 28: JUMPI -> [L3,L7]\n" <>+ "),(3,CO: L3\n" <>+ "OO: 29: DUP1\n" <>+ "OO: 30: PUSH [229,34,83,129]\n" <>+ "OO: 35: EQ\n" <>+ "OO: 36: PUSH [150]\n" <>+ "OC: 38: JUMPI -> [L4,L9]\n" <>+ "),(4,CO: L4\n" <>+ "OO: 39: JUMPDEST\n" <>+ "OO: 40: PUSH [213]\n" <>+ "OO: 42: PUSH [0]\n" <>+ "OO: 44: CALLVALUE\n" <>+ "OO: 45: GT\n" <>+ "OO: 46: ISZERO\n" <>+ "OO: 47: PUSH [108]\n" <>+ "OC: 49: JUMPI -> [L5,L6]\n" <>+ "),(5,CO: L5\n" <>+ "OO: 50: CALLVALUE\n" <>+ "OO: 51: PUSH [96]\n" <>+ "OO: 53: SWAP1\n" <>+ "OO: 54: DUP2\n" <>+ "OO: 55: MSTORE\n" <>+ "OO: 56: PUSH [88]\n" <>+ "OO: 58: SWAP1\n" <>+ "OO: 59: PUSH [1]\n" <>+ "OO: 61: PUSH [160]\n" <>+ "OO: 63: PUSH [2]\n" <>+ "OO: 65: EXP\n" <>+ "OO: 66: SUB\n" <>+ "OO: 67: CALLER\n" <>+ "OO: 68: AND\n" <>+ "OO: 69: SWAP1\n" <>+ "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\n" <>+ "OO: 103: SWAP1\n" <>+ "OO: 104: PUSH [32]\n" <>+ "OO: 106: SWAP1\n" <>+ "OC: 107: LOG3 -> [L6]\n" <>+ "),(6,CO: L6\n" <>+ "OO: 108: JUMPDEST\n" <>+ "OC: 109: JUMP -> []\n" <>+ "),(7,CO: L7\n" <>+ "OO: 110: JUMPDEST\n" <>+ "OO: 111: PUSH [213]\n" <>+ "OO: 113: PUSH [0]\n" <>+ "OO: 115: SLOAD\n" <>+ "OO: 116: PUSH [1]\n" <>+ "OO: 118: PUSH [160]\n" <>+ "OO: 120: PUSH [2]\n" <>+ "OO: 122: EXP\n" <>+ "OO: 123: SUB\n" <>+ "OO: 124: SWAP1\n" <>+ "OO: 125: DUP2\n" <>+ "OO: 126: AND\n" <>+ "OO: 127: CALLER\n" <>+ "OO: 128: SWAP2\n" <>+ "OO: 129: SWAP1\n" <>+ "OO: 130: SWAP2\n" <>+ "OO: 131: AND\n" <>+ "OO: 132: EQ\n" <>+ "OO: 133: ISZERO\n" <>+ "OO: 134: PUSH [108]\n" <>+ "OC: 136: JUMPI -> [L6,L8]\n" <>+ "),(8,CO: L8\n" <>+ "OO: 137: PUSH [0]\n" <>+ "OO: 139: SLOAD\n" <>+ "OO: 140: PUSH [1]\n" <>+ "OO: 142: PUSH [160]\n" <>+ "OO: 144: PUSH [2]\n" <>+ "OO: 146: EXP\n" <>+ "OO: 147: SUB\n" <>+ "OO: 148: AND\n" <>+ "OC: 149: SUICIDE -> []\n" <>+ "),(9,CO: L9\n" <>+ "OO: 150: JUMPDEST\n" <>+ "OO: 151: PUSH [213]\n" <>+ "OO: 153: PUSH [0]\n" <>+ "OO: 155: SLOAD\n" <>+ "OO: 156: PUSH [1]\n" <>+ "OO: 158: PUSH [160]\n" <>+ "OO: 160: PUSH [2]\n" <>+ "OO: 162: EXP\n" <>+ "OO: 163: SUB\n" <>+ "OO: 164: SWAP1\n" <>+ "OO: 165: DUP2\n" <>+ "OO: 166: AND\n" <>+ "OO: 167: CALLER\n" <>+ "OO: 168: SWAP2\n" <>+ "OO: 169: SWAP1\n" <>+ "OO: 170: SWAP2\n" <>+ "OO: 171: AND\n" <>+ "OO: 172: EQ\n" <>+ "OO: 173: ISZERO\n" <>+ "OO: 174: PUSH [108]\n" <>+ "OC: 176: JUMPI -> [L6,L10]\n" <>+ "),(10,CO: L10\n" <>+ "OO: 177: PUSH [0]\n" <>+ "OO: 179: DUP1\n" <>+ "OO: 180: SLOAD\n" <>+ "OO: 181: PUSH [1]\n" <>+ "OO: 183: PUSH [160]\n" <>+ "OO: 185: PUSH [2]\n" <>+ "OO: 187: EXP\n" <>+ "OO: 188: SUB\n" <>+ "OO: 189: SWAP1\n" <>+ "OO: 190: DUP2\n" <>+ "OO: 191: AND\n" <>+ "OO: 192: SWAP2\n" <>+ "OO: 193: SWAP1\n" <>+ "OO: 194: ADDRESS\n" <>+ "OO: 195: AND\n" <>+ "OO: 196: BALANCE\n" <>+ "OO: 197: PUSH [96]\n" <>+ "OO: 199: DUP3\n" <>+ "OO: 200: DUP2\n" <>+ "OO: 201: DUP2\n" <>+ "OO: 202: DUP2\n" <>+ "OO: 203: DUP6\n" <>+ "OO: 204: DUP9\n" <>+ "OO: 205: DUP4\n" <>+ "OC: 206: CALL -> [L11]\n" <>+ "),(11,CO: L11\n" <>+ "OO: 207: POP\n" <>+ "OO: 208: POP\n" <>+ "OO: 209: POP\n" <>+ "OO: 210: POP\n" <>+ "OO: 211: POP\n" <>+ "OC: 212: JUMP -> []\n" <>+ ")]))"
test/Ethereum/Analyzer/IRSpec.hs view
@@ -2,176 +2,182 @@ ( spec ) where -import Ethereum.Analyzer+import Protolude hiding (show)+ import Compiler.Hoopl-import SpecCommon+import Ethereum.Analyzer+import Ethereum.Analyzer.TestData.Basic+import GHC.Show import Test.Hspec spec :: Spec-spec = do- describe "e2h" $- do it "works for hexstring1" $- do let disasmd = disasm hexstring1- unWordLabelMapM- (mapSize . bodyOf . ctorOf <$> (evmOps2HplContract disasmd)) `shouldBe`- 327- it "works for hexstring2" $- do let disasmd = disasm hexstring2- unWordLabelMapM- (mapSize . bodyOf . ctorOf <$> (evmOps2HplContract disasmd)) `shouldBe`- 12- -- it "shows voteHexstring" $- -- do let disasmd = disasm voteHexstring- -- unWordLabelMapM (show <$> (evmOps2HplBody disasmd)) `shouldBe` ""- it "shows HplBody" $- do let disasmd = disasm hexstring2- unWordLabelMapM- (show . bodyOf . ctorOf <$> (evmOps2HplContract disasmd)) `shouldBe`- "LM (UM (fromList [(1,CO: L1\n" ++- "OO: 0: PUSH [96]\n" ++- "OO: 2: PUSH [64]\n" ++- "OO: 4: MSTORE\n" ++- "OO: 5: CALLDATASIZE\n" ++- "OO: 6: ISZERO\n" ++- "OO: 7: PUSH [39]\n" ++- "OC: 9: JUMPI -> [L2]\n" ++- "),(2,CO: L2\n" ++- "OO: 10: PUSH [224]\n" ++- "OO: 12: PUSH [2]\n" ++- "OO: 14: EXP\n" ++- "OO: 15: PUSH [0]\n" ++- "OO: 17: CALLDATALOAD\n" ++- "OO: 18: DIV\n" ++- "OO: 19: PUSH [65,192,225,181]\n" ++- "OO: 24: DUP2\n" ++- "OO: 25: EQ\n" ++- "OO: 26: PUSH [110]\n" ++- "OC: 28: JUMPI -> [L3]\n" ++- "),(3,CO: L3\n" ++- "OO: 29: DUP1\n" ++- "OO: 30: PUSH [229,34,83,129]\n" ++- "OO: 35: EQ\n" ++- "OO: 36: PUSH [150]\n" ++- "OC: 38: JUMPI -> [L4]\n" ++- "),(4,CO: L4\n" ++- "OO: 39: JUMPDEST\n" ++- "OO: 40: PUSH [213]\n" ++- "OO: 42: PUSH [0]\n" ++- "OO: 44: CALLVALUE\n" ++- "OO: 45: GT\n" ++- "OO: 46: ISZERO\n" ++- "OO: 47: PUSH [108]\n" ++- "OC: 49: JUMPI -> [L5]\n" ++- "),(5,CO: L5\n" ++- "OO: 50: CALLVALUE\n" ++- "OO: 51: PUSH [96]\n" ++- "OO: 53: SWAP1\n" ++- "OO: 54: DUP2\n" ++- "OO: 55: MSTORE\n" ++- "OO: 56: PUSH [88]\n" ++- "OO: 58: SWAP1\n" ++- "OO: 59: PUSH [1]\n" ++- "OO: 61: PUSH [160]\n" ++- "OO: 63: PUSH [2]\n" ++- "OO: 65: EXP\n" ++- "OO: 66: SUB\n" ++- "OO: 67: CALLER\n" ++- "OO: 68: AND\n" ++- "OO: 69: SWAP1\n" ++- "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\n" ++- "OO: 103: SWAP1\n" ++- "OO: 104: PUSH [32]\n" ++- "OO: 106: SWAP1\n" ++- "OC: 107: LOG3 -> [L6]\n" ++- "),(6,CO: L6\n" ++- "OO: 108: JUMPDEST\n" ++- "OC: 109: JUMP -> []\n" ++- "),(7,CO: L7\n" ++- "OO: 110: JUMPDEST\n" ++- "OO: 111: PUSH [213]\n" ++- "OO: 113: PUSH [0]\n" ++- "OO: 115: SLOAD\n" ++- "OO: 116: PUSH [1]\n" ++- "OO: 118: PUSH [160]\n" ++- "OO: 120: PUSH [2]\n" ++- "OO: 122: EXP\n" ++- "OO: 123: SUB\n" ++- "OO: 124: SWAP1\n" ++- "OO: 125: DUP2\n" ++- "OO: 126: AND\n" ++- "OO: 127: CALLER\n" ++- "OO: 128: SWAP2\n" ++- "OO: 129: SWAP1\n" ++- "OO: 130: SWAP2\n" ++- "OO: 131: AND\n" ++- "OO: 132: EQ\n" ++- "OO: 133: ISZERO\n" ++- "OO: 134: PUSH [108]\n" ++- "OC: 136: JUMPI -> [L8]\n" ++- "),(8,CO: L8\n" ++- "OO: 137: PUSH [0]\n" ++- "OO: 139: SLOAD\n" ++- "OO: 140: PUSH [1]\n" ++- "OO: 142: PUSH [160]\n" ++- "OO: 144: PUSH [2]\n" ++- "OO: 146: EXP\n" ++- "OO: 147: SUB\n" ++- "OO: 148: AND\n" ++- "OC: 149: SUICIDE -> []\n" ++- "),(9,CO: L9\n" ++- "OO: 150: JUMPDEST\n" ++- "OO: 151: PUSH [213]\n" ++- "OO: 153: PUSH [0]\n" ++- "OO: 155: SLOAD\n" ++- "OO: 156: PUSH [1]\n" ++- "OO: 158: PUSH [160]\n" ++- "OO: 160: PUSH [2]\n" ++- "OO: 162: EXP\n" ++- "OO: 163: SUB\n" ++- "OO: 164: SWAP1\n" ++- "OO: 165: DUP2\n" ++- "OO: 166: AND\n" ++- "OO: 167: CALLER\n" ++- "OO: 168: SWAP2\n" ++- "OO: 169: SWAP1\n" ++- "OO: 170: SWAP2\n" ++- "OO: 171: AND\n" ++- "OO: 172: EQ\n" ++- "OO: 173: ISZERO\n" ++- "OO: 174: PUSH [108]\n" ++- "OC: 176: JUMPI -> [L10]\n" ++- "),(10,CO: L10\n" ++- "OO: 177: PUSH [0]\n" ++- "OO: 179: DUP1\n" ++- "OO: 180: SLOAD\n" ++- "OO: 181: PUSH [1]\n" ++- "OO: 183: PUSH [160]\n" ++- "OO: 185: PUSH [2]\n" ++- "OO: 187: EXP\n" ++- "OO: 188: SUB\n" ++- "OO: 189: SWAP1\n" ++- "OO: 190: DUP2\n" ++- "OO: 191: AND\n" ++- "OO: 192: SWAP2\n" ++- "OO: 193: SWAP1\n" ++- "OO: 194: ADDRESS\n" ++- "OO: 195: AND\n" ++- "OO: 196: BALANCE\n" ++- "OO: 197: PUSH [96]\n" ++- "OO: 199: DUP3\n" ++- "OO: 200: DUP2\n" ++- "OO: 201: DUP2\n" ++- "OO: 202: DUP2\n" ++- "OO: 203: DUP6\n" ++- "OO: 204: DUP9\n" ++- "OO: 205: DUP4\n" ++- "OC: 206: CALL -> [L11]\n" ++- "),(11,CO: L11\n" ++- "OO: 207: POP\n" ++- "OO: 208: POP\n" ++- "OO: 209: POP\n" ++- "OO: 210: POP\n" ++- "OO: 211: POP\n" ++- "OC: 212: JUMP -> []\n" ++- "),(12,CO: L12\n" ++- "OO: 213: JUMPDEST\n" ++ "OC: 214: STOP -> []\n" ++ ")]))"+spec =+ describe "e2h" $ do+ it "works for hexstring1" $ do+ let disasmd = disasm hexstring1+ unWordLabelMapM (mapSize . bodyOf . ctorOf <$> evmOps2HplContract disasmd) `shouldBe`+ 327+ it "works for hexstring2" $ do+ let disasmd = disasm hexstring2+ unWordLabelMapM (mapSize . bodyOf . ctorOf <$> evmOps2HplContract disasmd) `shouldBe`+ 12+ -- it "shows voteHexstring" $+ -- do let disasmd = disasm voteHexstring+ -- unWordLabelMapM (show <$> (evmOps2HplBody disasmd)) `shouldBe` ""+ it "shows HplBody" $ do+ let disasmd = disasm hexstring2+ unWordLabelMapM+ ((toS . show . bodyOf . ctorOf <$> evmOps2HplContract disasmd) :: WordLabelMapM Text) `shouldBe`+ toS expectedHexString2CtorBody++expectedHexString2CtorBody :: Text+expectedHexString2CtorBody =+ "LM (UM (fromList [(1,CO: L1\n" <> "OO: 0: PUSH [96]\n" <>+ "OO: 2: PUSH [64]\n" <>+ "OO: 4: MSTORE\n" <>+ "OO: 5: CALLDATASIZE\n" <>+ "OO: 6: ISZERO\n" <>+ "OO: 7: PUSH [39]\n" <>+ "OC: 9: JUMPI -> [L2]\n" <>+ "),(2,CO: L2\n" <>+ "OO: 10: PUSH [224]\n" <>+ "OO: 12: PUSH [2]\n" <>+ "OO: 14: EXP\n" <>+ "OO: 15: PUSH [0]\n" <>+ "OO: 17: CALLDATALOAD\n" <>+ "OO: 18: DIV\n" <>+ "OO: 19: PUSH [65,192,225,181]\n" <>+ "OO: 24: DUP2\n" <>+ "OO: 25: EQ\n" <>+ "OO: 26: PUSH [110]\n" <>+ "OC: 28: JUMPI -> [L3]\n" <>+ "),(3,CO: L3\n" <>+ "OO: 29: DUP1\n" <>+ "OO: 30: PUSH [229,34,83,129]\n" <>+ "OO: 35: EQ\n" <>+ "OO: 36: PUSH [150]\n" <>+ "OC: 38: JUMPI -> [L4]\n" <>+ "),(4,CO: L4\n" <>+ "OO: 39: JUMPDEST\n" <>+ "OO: 40: PUSH [213]\n" <>+ "OO: 42: PUSH [0]\n" <>+ "OO: 44: CALLVALUE\n" <>+ "OO: 45: GT\n" <>+ "OO: 46: ISZERO\n" <>+ "OO: 47: PUSH [108]\n" <>+ "OC: 49: JUMPI -> [L5]\n" <>+ "),(5,CO: L5\n" <>+ "OO: 50: CALLVALUE\n" <>+ "OO: 51: PUSH [96]\n" <>+ "OO: 53: SWAP1\n" <>+ "OO: 54: DUP2\n" <>+ "OO: 55: MSTORE\n" <>+ "OO: 56: PUSH [88]\n" <>+ "OO: 58: SWAP1\n" <>+ "OO: 59: PUSH [1]\n" <>+ "OO: 61: PUSH [160]\n" <>+ "OO: 63: PUSH [2]\n" <>+ "OO: 65: EXP\n" <>+ "OO: 66: SUB\n" <>+ "OO: 67: CALLER\n" <>+ "OO: 68: AND\n" <>+ "OO: 69: SWAP1\n" <>+ "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\n" <>+ "OO: 103: SWAP1\n" <>+ "OO: 104: PUSH [32]\n" <>+ "OO: 106: SWAP1\n" <>+ "OC: 107: LOG3 -> [L6]\n" <>+ "),(6,CO: L6\n" <>+ "OO: 108: JUMPDEST\n" <>+ "OC: 109: JUMP -> []\n" <>+ "),(7,CO: L7\n" <>+ "OO: 110: JUMPDEST\n" <>+ "OO: 111: PUSH [213]\n" <>+ "OO: 113: PUSH [0]\n" <>+ "OO: 115: SLOAD\n" <>+ "OO: 116: PUSH [1]\n" <>+ "OO: 118: PUSH [160]\n" <>+ "OO: 120: PUSH [2]\n" <>+ "OO: 122: EXP\n" <>+ "OO: 123: SUB\n" <>+ "OO: 124: SWAP1\n" <>+ "OO: 125: DUP2\n" <>+ "OO: 126: AND\n" <>+ "OO: 127: CALLER\n" <>+ "OO: 128: SWAP2\n" <>+ "OO: 129: SWAP1\n" <>+ "OO: 130: SWAP2\n" <>+ "OO: 131: AND\n" <>+ "OO: 132: EQ\n" <>+ "OO: 133: ISZERO\n" <>+ "OO: 134: PUSH [108]\n" <>+ "OC: 136: JUMPI -> [L8]\n" <>+ "),(8,CO: L8\n" <>+ "OO: 137: PUSH [0]\n" <>+ "OO: 139: SLOAD\n" <>+ "OO: 140: PUSH [1]\n" <>+ "OO: 142: PUSH [160]\n" <>+ "OO: 144: PUSH [2]\n" <>+ "OO: 146: EXP\n" <>+ "OO: 147: SUB\n" <>+ "OO: 148: AND\n" <>+ "OC: 149: SUICIDE -> []\n" <>+ "),(9,CO: L9\n" <>+ "OO: 150: JUMPDEST\n" <>+ "OO: 151: PUSH [213]\n" <>+ "OO: 153: PUSH [0]\n" <>+ "OO: 155: SLOAD\n" <>+ "OO: 156: PUSH [1]\n" <>+ "OO: 158: PUSH [160]\n" <>+ "OO: 160: PUSH [2]\n" <>+ "OO: 162: EXP\n" <>+ "OO: 163: SUB\n" <>+ "OO: 164: SWAP1\n" <>+ "OO: 165: DUP2\n" <>+ "OO: 166: AND\n" <>+ "OO: 167: CALLER\n" <>+ "OO: 168: SWAP2\n" <>+ "OO: 169: SWAP1\n" <>+ "OO: 170: SWAP2\n" <>+ "OO: 171: AND\n" <>+ "OO: 172: EQ\n" <>+ "OO: 173: ISZERO\n" <>+ "OO: 174: PUSH [108]\n" <>+ "OC: 176: JUMPI -> [L10]\n" <>+ "),(10,CO: L10\n" <>+ "OO: 177: PUSH [0]\n" <>+ "OO: 179: DUP1\n" <>+ "OO: 180: SLOAD\n" <>+ "OO: 181: PUSH [1]\n" <>+ "OO: 183: PUSH [160]\n" <>+ "OO: 185: PUSH [2]\n" <>+ "OO: 187: EXP\n" <>+ "OO: 188: SUB\n" <>+ "OO: 189: SWAP1\n" <>+ "OO: 190: DUP2\n" <>+ "OO: 191: AND\n" <>+ "OO: 192: SWAP2\n" <>+ "OO: 193: SWAP1\n" <>+ "OO: 194: ADDRESS\n" <>+ "OO: 195: AND\n" <>+ "OO: 196: BALANCE\n" <>+ "OO: 197: PUSH [96]\n" <>+ "OO: 199: DUP3\n" <>+ "OO: 200: DUP2\n" <>+ "OO: 201: DUP2\n" <>+ "OO: 202: DUP2\n" <>+ "OO: 203: DUP6\n" <>+ "OO: 204: DUP9\n" <>+ "OO: 205: DUP4\n" <>+ "OC: 206: CALL -> [L11]\n" <>+ "),(11,CO: L11\n" <>+ "OO: 207: POP\n" <>+ "OO: 208: POP\n" <>+ "OO: 209: POP\n" <>+ "OO: 210: POP\n" <>+ "OO: 211: POP\n" <>+ "OC: 212: JUMP -> []\n" <>+ "),(12,CO: L12\n" <>+ "OO: 213: JUMPDEST\n" <>+ "OC: 214: STOP -> []\n" <>+ ")]))"
+ test/Ethereum/Analyzer/Solidity/ForeachSpec.hs view
@@ -0,0 +1,37 @@+module Ethereum.Analyzer.Solidity.ForeachSpec+ ( spec+ ) where++import Protolude hiding (show)++import Ethereum.Analyzer.Solidity+import Ethereum.Analyzer.TestData.DaoJson (simpleDaoJson)+import Ethereum.Analyzer.TestData.StorageJson (storageJson)+import Test.Hspec++spec :: Spec+spec = do+ describe "statementsOf" $+ parallel $ do+ it "works for storageJson" $ do+ case decodeContracts storageJson of+ Right contracts ->+ sum (map (length . statementsOf) contracts) `shouldBe` 2+ Left err -> expectationFailure $ toS err+ it "works for simpleDaoJson" $ do+ case decodeContracts simpleDaoJson of+ Right contracts ->+ sum (map (length . statementsOf) contracts) `shouldBe` 39+ Left err -> expectationFailure $ toS err+ describe "expressionsOf" $+ parallel $ do+ it "works for storageJson" $ do+ case decodeContracts storageJson of+ Right contracts ->+ sum (map (length . expressionsOf) contracts) `shouldBe` 1+ Left err -> expectationFailure $ toS err+ it "works for simpleDaoJson" $ do+ case decodeContracts simpleDaoJson of+ Right contracts ->+ sum (map (length . expressionsOf) contracts) `shouldBe` 33+ Left err -> expectationFailure $ toS err
+ test/Ethereum/Analyzer/Solidity/SimpleSpec.hs view
@@ -0,0 +1,411 @@+module Ethereum.Analyzer.Solidity.SimpleSpec+ ( spec+ ) where++import Protolude hiding (show)++import Compiler.Hoopl++-- import Ethereum.Analyzer.Common+import Ethereum.Analyzer.Solidity+import Ethereum.Analyzer.TestData.DaoJson (simpleDaoJson)+import Ethereum.Analyzer.TestData.StorageJson (storageJson)++-- import GHC.Show (Show(..))+import Test.Hspec+import qualified Text.PrettyPrint.GenericPretty as GP++spec :: Spec+spec =+ describe "e2h" $+ parallel $ do+ it "parses storageJson" $ do+ let eitherContracts = do+ solNodes <- decodeSoleNodes (toS storageJson)+ let mContracts = mapM s2sContracts solNodes+ let contracts = concat $ runSimpleUniqueMonad mContracts+ return contracts+ GP.pp eitherContracts+ eitherContracts `shouldBe`+ Right+ [ Contract+ { cName = "SimpleStorage"+ , cStateVars =+ [VarDecl {vName = Idfr "storedData", vType = Unknown "uint256"}]+ , cFunctions =+ [ FunDefinition+ { fName = Idfr "set"+ , fParams =+ [VarDecl {vName = Idfr "x", vType = Unknown "uint256"}]+ , fReturns = []+ , fBody =+ [ StAssign+ (JustId (Idfr "storedData"))+ (ExpLval (JustId (Idfr "x")))+ ]+ }+ , FunDefinition+ { fName = Idfr "get"+ , fParams = []+ , fReturns =+ [VarDecl {vName = Idfr "", vType = Unknown "uint256"}]+ , fBody = [StReturn [JustId (Idfr "storedData")]]+ }+ ]+ }+ ]+ it "parses simpleDaoJson" $ do+ let eitherContracts = do+ solNodes <- decodeSoleNodes (toS simpleDaoJson)+ let mContracts = mapM s2sContracts solNodes+ let contracts = concat $ runSimpleUniqueMonad mContracts+ return contracts+ GP.pp eitherContracts+ eitherContracts `shouldBe`+ Right+ [ Contract+ { cName = "SimpleDAO"+ , cStateVars =+ [ VarDecl+ { vName = Idfr "credit"+ , vType = Unknown "mapping(address => uint256)"+ }+ ]+ , cFunctions =+ [ FunDefinition+ { fName = Idfr "donate"+ , fParams =+ [VarDecl {vName = Idfr "to", vType = Unknown "address"}]+ , fReturns = []+ , fBody =+ [ StAssign+ (Index+ { iArray = JustId (Idfr "credit")+ , iIndex =+ Index+ { iArray = JustId (Idfr "credit")+ , iIndex = JustId (Idfr "to")+ }+ })+ (ExpLval+ (Member+ { mObj = JustId (Idfr "msg")+ , mField = Idfr "value"+ }))+ ]+ }+ , FunDefinition+ { fName = Idfr "withdraw"+ , fParams =+ [ VarDecl+ {vName = Idfr "amount", vType = Unknown "uint256"}+ ]+ , fReturns = []+ , fBody =+ [ StAssign+ (JustId (Idfr "v1"))+ (ExpBin+ ">="+ (Index+ { iArray = JustId (Idfr "credit")+ , iIndex =+ Index+ { iArray = JustId (Idfr "credit")+ , iIndex =+ Member+ { mObj = JustId (Idfr "msg")+ , mField = Idfr "sender"+ }+ }+ })+ (JustId (Idfr "amount")))+ , StIf+ (JustId (Idfr "v1"))+ [ StAssign+ (JustId (Idfr "v2"))+ (ExpCall+ (Member+ { mObj =+ Member+ { mObj =+ Member+ { mObj = JustId (Idfr "msg")+ , mField = Idfr "sender"+ }+ , mField = Idfr "call"+ }+ , mField = Idfr "value"+ })+ [JustId (Idfr "amount")])+ , StAssign+ (JustId (Idfr "v3"))+ (ExpCall (JustId (Idfr "v2")) [])+ , StLocalVarDecl+ (VarDecl+ {vName = Idfr "res", vType = Unknown "bool"})+ , StAssign+ (JustId (Idfr "res"))+ (ExpLval (JustId (Idfr "v3")))+ , StAssign+ (Index+ { iArray = JustId (Idfr "credit")+ , iIndex =+ Index+ { iArray = JustId (Idfr "credit")+ , iIndex =+ Member+ { mObj = JustId (Idfr "msg")+ , mField = Idfr "sender"+ }+ }+ })+ (ExpLval (JustId (Idfr "amount")))+ ]+ []+ ]+ }+ , FunDefinition+ { fName = Idfr "queryCredit"+ , fParams =+ [VarDecl {vName = Idfr "to", vType = Unknown "address"}]+ , fReturns =+ [VarDecl {vName = Idfr "", vType = Unknown "uint256"}]+ , fBody =+ [ StReturn+ [ Index+ { iArray = JustId (Idfr "credit")+ , iIndex =+ Index+ { iArray = JustId (Idfr "credit")+ , iIndex = JustId (Idfr "to")+ }+ }+ ]+ ]+ }+ ]+ }+ , Contract+ { cName = "Mallory"+ , cStateVars =+ [ VarDecl+ {vName = Idfr "dao", vType = Unknown "contract SimpleDAO"}+ , VarDecl {vName = Idfr "owner", vType = Unknown "address"}+ ]+ , cFunctions =+ [ FunDefinition+ { fName = Idfr "Mallory"+ , fParams =+ [ VarDecl+ { vName = Idfr "addr"+ , vType = Unknown "contract SimpleDAO"+ }+ ]+ , fReturns = []+ , fBody =+ [ StAssign+ (JustId (Idfr "owner"))+ (ExpLval+ (Member+ { mObj = JustId (Idfr "msg")+ , mField = Idfr "sender"+ }))+ , StAssign+ (JustId (Idfr "dao"))+ (ExpLval (JustId (Idfr "addr")))+ ]+ }+ , FunDefinition+ { fName = Idfr "getJackpot"+ , fParams = []+ , fReturns = []+ , fBody =+ [ StAssign+ (JustId (Idfr "v6"))+ (ExpCall+ (Member+ { mObj = JustId (Idfr "owner")+ , mField = Idfr "send"+ })+ [ Member+ { mObj = JustId (Idfr "this")+ , mField = Idfr "balance"+ }+ ])+ , StLocalVarDecl+ (VarDecl {vName = Idfr "res", vType = Unknown "bool"})+ , StAssign+ (JustId (Idfr "res"))+ (ExpLval (JustId (Idfr "v6")))+ ]+ }+ , FunDefinition+ { fName = Idfr ""+ , fParams = []+ , fReturns = []+ , fBody =+ [ StAssign+ (JustId (Idfr "v4"))+ (ExpCall+ (Member+ { mObj = JustId (Idfr "dao")+ , mField = Idfr "queryCredit"+ })+ [JustId (Idfr "this")])+ , StAssign+ (JustId (Idfr "v5"))+ (ExpCall+ (Member+ { mObj = JustId (Idfr "dao")+ , mField = Idfr "withdraw"+ })+ [JustId (Idfr "v4")])+ , StAssign+ (JustId (Idfr "_"))+ (ExpLval (JustId (Idfr "v5")))+ ]+ }+ ]+ }+ , Contract+ { cName = "Mallory2"+ , cStateVars =+ [ VarDecl+ {vName = Idfr "dao", vType = Unknown "contract SimpleDAO"}+ , VarDecl {vName = Idfr "owner", vType = Unknown "address"}+ , VarDecl {vName = Idfr "performAttack", vType = Unknown "bool"}+ ]+ , cFunctions =+ [ FunDefinition+ { fName = Idfr "Mallory2"+ , fParams =+ [ VarDecl+ { vName = Idfr "addr"+ , vType = Unknown "contract SimpleDAO"+ }+ ]+ , fReturns = []+ , fBody =+ [ StAssign+ (JustId (Idfr "owner"))+ (ExpLval+ (Member+ { mObj = JustId (Idfr "msg")+ , mField = Idfr "sender"+ }))+ , StAssign+ (JustId (Idfr "dao"))+ (ExpLval (JustId (Idfr "addr")))+ ]+ }+ , FunDefinition+ { fName = Idfr "attack"+ , fParams = []+ , fReturns = []+ , fBody =+ [ StAssign (JustId (Idfr "v13")) (ExpLiteral "1")+ , StAssign+ (JustId (Idfr "v14"))+ (ExpCall+ (Member+ { mObj =+ Member+ { mObj = JustId (Idfr "dao")+ , mField = Idfr "donate"+ }+ , mField = Idfr "value"+ })+ [JustId (Idfr "v13")])+ , StAssign+ (JustId (Idfr "v15"))+ (ExpCall (JustId (Idfr "v14")) [JustId (Idfr "this")])+ , StAssign+ (JustId (Idfr "_"))+ (ExpLval (JustId (Idfr "v15")))+ , StAssign (JustId (Idfr "v16")) (ExpLiteral "1")+ , StAssign+ (JustId (Idfr "v17"))+ (ExpCall+ (Member+ { mObj = JustId (Idfr "dao")+ , mField = Idfr "withdraw"+ })+ [JustId (Idfr "v16")])+ , StAssign+ (JustId (Idfr "_"))+ (ExpLval (JustId (Idfr "v17")))+ ]+ }+ , FunDefinition+ { fName = Idfr "getJackpot"+ , fParams = []+ , fReturns = []+ , fBody =+ [ StAssign+ (JustId (Idfr "v10"))+ (ExpCall+ (Member+ { mObj = JustId (Idfr "dao")+ , mField = Idfr "withdraw"+ })+ [ Member+ { mObj = JustId (Idfr "dao")+ , mField = Idfr "balance"+ }+ ])+ , StAssign+ (JustId (Idfr "_"))+ (ExpLval (JustId (Idfr "v10")))+ , StAssign+ (JustId (Idfr "v11"))+ (ExpCall+ (Member+ { mObj = JustId (Idfr "owner")+ , mField = Idfr "send"+ })+ [ Member+ { mObj = JustId (Idfr "this")+ , mField = Idfr "balance"+ }+ ])+ , StLocalVarDecl+ (VarDecl {vName = Idfr "res", vType = Unknown "bool"})+ , StAssign+ (JustId (Idfr "res"))+ (ExpLval (JustId (Idfr "v11")))+ , StAssign (JustId (Idfr "v12")) (ExpLiteral "true")+ , StAssign+ (JustId (Idfr "performAttack"))+ (ExpLval (JustId (Idfr "v12")))+ ]+ }+ , FunDefinition+ { fName = Idfr ""+ , fParams = []+ , fReturns = []+ , fBody =+ [ StIf+ (JustId (Idfr "performAttack"))+ [ StAssign (JustId (Idfr "v7")) (ExpLiteral "false")+ , StAssign+ (JustId (Idfr "performAttack"))+ (ExpLval (JustId (Idfr "v7")))+ , StAssign (JustId (Idfr "v8")) (ExpLiteral "1")+ , StAssign+ (JustId (Idfr "v9"))+ (ExpCall+ (Member+ { mObj = JustId (Idfr "dao")+ , mField = Idfr "withdraw"+ })+ [JustId (Idfr "v8")])+ , StAssign+ (JustId (Idfr "_"))+ (ExpLval (JustId (Idfr "v9")))+ ]+ []+ ]+ }+ ]+ }+ ]
+ test/Ethereum/Analyzer/SoliditySpec.hs view
@@ -0,0 +1,365 @@+module Ethereum.Analyzer.SoliditySpec+ ( spec+ ) where++import Protolude hiding (show)++import Ethereum.Analyzer.Common+import Ethereum.Analyzer.Solidity+import Ethereum.Analyzer.TestData.DaoJson (simpleDaoJson)+import Ethereum.Analyzer.TestData.StorageJson (storageJson)+import GHC.Show (Show(..))+import Test.Hspec+import Text.PrettyPrint.Leijen.Text (Doc, pretty, renderPretty)++spec :: Spec+spec =+ describe "e2h" $+ parallel $ do+ it "pretty-prints simpleDaoJson" $ do+ let prettySol =+ (show <$> renderPretty 1.0 80) . (pretty :: [SolNode] -> Doc) <$>+ decodeSoleNodes (toS simpleDaoJson)+ -- putStrLn $ fromRight "" prettySol+ prettySol `shouldBe`+ Right+ ("[//--SourceUnit--\n" <>+ "contract SimpleDAO {mapping(address => uint256) credit\n" <>+ " ;fun donate (address to)(){(credit[to]+=msg.value)}\n" <>+ " ;fun withdraw (uint256 amount)\n" <>+ " ()\n" <>+ " {if((credit[msg.sender]>=amount)\n" <>+ " ,{bool res = msg.sender.call.value(amount)()\n" <>+ " ;(credit[msg.sender]-=amount)})}\n" <>+ " ;fun queryCredit (address to)(uint256){return(credit[to])}}\n" <>+ "contract Mallory {contract SimpleDAO dao\n" <>+ " ;address owner\n" <>+ " ;fun Mallory (contract SimpleDAO addr)\n" <>+ " ()\n" <>+ " {(owner=msg.sender);(dao=addr)}\n" <>+ " ;fun getJackpot ()(){bool res = owner.send(this.balance)}\n" <>+ " ;fun ()(){(dao.withdraw(dao.queryCredit(this)))}}\n" <>+ "contract Mallory2 {contract SimpleDAO dao\n" <>+ " ;address owner\n" <>+ " ;bool performAttack\n" <>+ " ;fun Mallory2 (contract SimpleDAO addr)\n" <>+ " ()\n" <>+ " {(owner=msg.sender);(dao=addr)}\n" <>+ " ;fun attack ()\n" <>+ " ()\n" <>+ " {(dao.donate.value(1)(this));(dao.withdraw(1))}\n" <>+ " ;fun getJackpot ()\n" <>+ " ()\n" <>+ " {(dao.withdraw(dao.balance))\n" <>+ " ;bool res = owner.send(this.balance)\n" <>+ " ;(performAttack=true)}\n" <>+ " ;fun ()\n" <>+ " ()\n" <>+ " {if(performAttack\n" <>+ " ,{(performAttack=false);(dao.withdraw(1))})}}]")+ it "pretty-prints storageJson" $ do+ let prettySol =+ (show <$> renderPretty 1.0 80) . (pretty :: [SolNode] -> Doc) <$>+ decodeSoleNodes (toS storageJson)+ -- putStrLn $ fromRight "" prettySol+ prettySol `shouldBe`+ Right+ ("[//--SourceUnit--\n" <>+ "contract SimpleStorage {uint256 storedData\n" <>+ " ;fun set (uint256 x)(){(storedData=x)}\n" <>+ " ;fun get ()(uint256){return(storedData)}}]")+ it "works for storageJson" $+ decodeSoleNodes (toS storageJson) `shouldBe`+ Right+ [ defSolNode+ { _AST =+ Just+ (defSolNode+ { children =+ Just+ [ defSolNode+ { _id = Just 1+ , name = Just "PragmaDirective"+ , src = Just "0:23:0"+ , attributes =+ Just+ (defSolNode+ {literals = Just ["solidity", "^", "0.4", ".0"]})+ }+ , defSolNode+ { children =+ Just+ [ defSolNode+ { children =+ Just+ [ defSolNode+ { _id = Just 2+ , name = Just "ElementaryTypeName"+ , src = Just "52:4:0"+ , attributes =+ Just+ (defSolNode {name = Just "uint"})+ }+ ]+ , _id = Just 3+ , name = Just "VariableDeclaration"+ , src = Just "52:15:0"+ , attributes =+ Just+ (defSolNode+ { name = Just "storedData"+ , _type = Just "uint256"+ , visibility = Just "internal"+ , constant = Just False+ , storageLocation = Just "default"+ })+ }+ , defSolNode+ { children =+ Just+ [ defSolNode+ { children =+ Just+ [ defSolNode+ { children =+ Just+ [ defSolNode+ { _id = Just 4+ , name =+ Just+ "ElementaryTypeName"+ , src = Just "85:4:0"+ , attributes =+ Just+ (defSolNode+ { name =+ Just "uint"+ })+ }+ ]+ , _id = Just 5+ , name =+ Just "VariableDeclaration"+ , src = Just "85:6:0"+ , attributes =+ Just+ (defSolNode+ { name = Just "x"+ , _type = Just "uint256"+ , visibility =+ Just "internal"+ , constant = Just False+ , storageLocation =+ Just "default"+ })+ }+ ]+ , _id = Just 6+ , name = Just "ParameterList"+ , src = Just "84:8:0"+ }+ , defSolNode+ { children = Just []+ , _id = Just 7+ , name = Just "ParameterList"+ , src = Just "93:0:0"+ }+ , defSolNode+ { children =+ Just+ [ defSolNode+ { children =+ Just+ [ defSolNode+ { children =+ Just+ [ defSolNode+ { _id = Just 8+ , name =+ Just+ "Identifier"+ , src =+ Just+ "99:10:0"+ , attributes =+ Just+ (defSolNode+ { _type =+ Just+ "uint256"+ , value =+ Just+ "storedData"+ })+ }+ , defSolNode+ { _id = Just 9+ , name =+ Just+ "Identifier"+ , src =+ Just+ "112:1:0"+ , attributes =+ Just+ (defSolNode+ { _type =+ Just+ "uint256"+ , value =+ Just+ "x"+ })+ }+ ]+ , _id = Just 10+ , name =+ Just "Assignment"+ , src = Just "99:14:0"+ , attributes =+ Just+ (defSolNode+ { _type =+ Just+ "uint256"+ , operator =+ Just "="+ })+ }+ ]+ , _id = Just 11+ , name =+ Just "ExpressionStatement"+ , src = Just "99:14:0"+ }+ ]+ , _id = Just 12+ , name = Just "Block"+ , src = Just "93:25:0"+ }+ ]+ , _id = Just 13+ , name = Just "FunctionDefinition"+ , src = Just "72:46:0"+ , attributes =+ Just+ (defSolNode+ { name = Just "set"+ , visibility = Just "public"+ , payable = Just False+ , constant = Just False+ })+ }+ , defSolNode+ { children =+ Just+ [ defSolNode+ { children = Just []+ , _id = Just 14+ , name = Just "ParameterList"+ , src = Just "134:2:0"+ }+ , defSolNode+ { children =+ Just+ [ defSolNode+ { children =+ Just+ [ defSolNode+ { _id = Just 15+ , name =+ Just+ "ElementaryTypeName"+ , src = Just "155:4:0"+ , attributes =+ Just+ (defSolNode+ { name =+ Just "uint"+ })+ }+ ]+ , _id = Just 16+ , name =+ Just "VariableDeclaration"+ , src = Just "155:4:0"+ , attributes =+ Just+ (defSolNode+ { name = Just ""+ , _type = Just "uint256"+ , visibility =+ Just "internal"+ , constant = Just False+ , storageLocation =+ Just "default"+ })+ }+ ]+ , _id = Just 17+ , name = Just "ParameterList"+ , src = Just "154:6:0"+ }+ , defSolNode+ { children =+ Just+ [ defSolNode+ { children =+ Just+ [ defSolNode+ { _id = Just 18+ , name =+ Just "Identifier"+ , src = Just "174:10:0"+ , attributes =+ Just+ (defSolNode+ { _type =+ Just+ "uint256"+ , value =+ Just+ "storedData"+ })+ }+ ]+ , _id = Just 19+ , name = Just "Return"+ , src = Just "167:17:0"+ }+ ]+ , _id = Just 20+ , name = Just "Block"+ , src = Just "161:28:0"+ }+ ]+ , _id = Just 21+ , name = Just "FunctionDefinition"+ , src = Just "122:67:0"+ , attributes =+ Just+ (defSolNode+ { name = Just "get"+ , visibility = Just "public"+ , payable = Just False+ , constant = Just True+ })+ }+ ]+ , _id = Just 22+ , name = Just "ContractDefinition"+ , src = Just "25:166:0"+ , attributes =+ Just+ (defSolNode+ { name = Just "SimpleStorage"+ , fullyImplemented = Just True+ , isLibrary = Just False+ , linearizedBaseContracts = Just [22]+ })+ }+ ]+ , name = Just "SourceUnit"+ })+ }+ ]
+ test/Ethereum/Analyzer/TestData/Basic.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}++module Ethereum.Analyzer.TestData.Basic+ ( hexstring1+ , hexstring2+ , voteHexstring+ ) where++import Ethereum.Analyzer.Disasm++hexstring1 :: EvmHexString+hexstring1 =+ EvmHexString+ "6060604052600261010860005055604051611b51380380611b51833981016040528080518201919060200180519060200190919080519060200190919050505b805b83835b600060018351016001600050819055503373ffffffffffffffffffffffffffffffffffffffff16600260005060016101008110156100025790900160005b5081905550600161010260005060003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005081905550600090505b825181101561016e5782818151811015610002579060200190602002015173ffffffffffffffffffffffffffffffffffffffff166002600050826002016101008110156100025790900160005b508190555080600201610102600050600085848151811015610002579060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b80600101905080506100c2565b816000600050819055505b505050806101056000508190555061018f6101ad565b610107600050819055505b505b505050611992806101bf6000396000f35b600062015180420490506101bc565b9056606060405236156100f8576000357c010000000000000000000000000000000000000000000000000000000090048063173825d9146101605780632f54bf6e146101785780634123cb6b146101a457806352375093146101c757806354fd4d50146101ea5780635c52c2f51461020d578063659010e71461021c5780637065cb481461023f578063746c917114610257578063797af6271461027a578063b20d30a9146102a6578063b61d27f6146102be578063b75c7dc614610307578063ba51a6df1461031f578063c2cf732614610337578063cbf0b0c01461036c578063f00d4b5d14610384578063f1736d86146103a5576100f8565b61015e5b600034111561015b577fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3334604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b565b005b61017660048080359060200190919050506107c4565b005b61018e60048080359060200190919050506109a5565b6040518082815260200191505060405180910390f35b6101b16004805050610a91565b6040518082815260200191505060405180910390f35b6101d46004805050610b38565b6040518082815260200191505060405180910390f35b6101f76004805050610b42565b6040518082815260200191505060405180910390f35b61021a6004805050610adf565b005b6102296004805050610b2e565b6040518082815260200191505060405180910390f35b610255600480803590602001909190505061066e565b005b6102646004805050610a88565b6040518082815260200191505060405180910390f35b6102906004808035906020019091905050610f0e565b6040518082815260200191505060405180910390f35b6102bc6004808035906020019091905050610a9a565b005b6102f160048080359060200190919080359060200190919080359060200190820180359060200191909192905050610b9e565b6040518082815260200191505060405180910390f35b61031d60048080359060200190919050506103c8565b005b610335600480803590602001909190505061090f565b005b61035660048080359060200190919080359060200190919050506109e7565b6040518082815260200191505060405180910390f35b6103826004808035906020019091905050610b4c565b005b6103a360048080359060200190919080359060200190919050506104ca565b005b6103b26004805050610b24565b6040518082815260200191505060405180910390f35b60006000600061010260005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549250600083141561040f576104c4565b8260020a91506101036000506000858152602001908152602001600020600050905060008282600101600050541611156104c3578060000160008181505480929190600101919050555081816001016000828282505403925050819055507fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b3385604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b50505050565b600060003643604051808484808284378201915050828152602001935050505060405180910390206104fb816112db565b1561066757610509836109a5565b156105145750610669565b61010260005060008573ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054915060008214156105565750610669565b61055e611777565b8273ffffffffffffffffffffffffffffffffffffffff166002600050836101008110156100025790900160005b5081905550600061010260005060008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055508161010260005060008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c8484604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b505b505050565b600036436040518084848082843782019150508281526020019350505050604051809103902061069d816112db565b156107bf576106ab826109a5565b156106b657506107c1565b6106be611777565b60fa6001600050541015156106d7576106d561153d565b505b60fa6001600050541015156106ec57506107c1565b60016000818150548092919060010191905055508173ffffffffffffffffffffffffffffffffffffffff1660026000506001600050546101008110156100025790900160005b508190555060016000505461010260005060008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c382604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b505b50565b600060003643604051808484808284378201915050828152602001935050505060405180910390206107f5816112db565b156109095761010260005060008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549150600082141561083c575061090b565b6001600160005054036000600050541115610857575061090b565b60006002600050836101008110156100025790900160005b5081905550600061010260005060008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055506108b2611777565b6108ba61153d565b507f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da83604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b505b5050565b600036436040518084848082843782019150508281526020019350505050604051809103902061093e816112db565b156109a05760016000505482111561095657506109a2565b81600060005081905550610968611777565b7facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da826040518082815260200191505060405180910390a15b505b50565b6000600061010260005060008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050541190506109e2565b919050565b60006000600060006101036000506000878152602001908152602001600020600050925061010260005060008673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505491506000821415610a505760009350610a7f565b8160020a90506000818460010160005054161415610a755760009350610a7f56610a7e565b60019350610a7f565b5b50505092915050565b60006000505481565b60016000505481565b6000364360405180848480828437820191505082815260200193505050506040518091039020610ac9816112db565b15610ada5781610105600050819055505b505b50565b6000364360405180848480828437820191505082815260200193505050506040518091039020610b0e816112db565b15610b20576000610106600050819055505b505b565b6101056000505481565b6101066000505481565b6101076000505481565b6101086000505481565b6000364360405180848480828437820191505082815260200193505050506040518091039020610b7b816112db565b15610b99578173ffffffffffffffffffffffffffffffffffffffff16ff5b505b50565b6000610ba9336109a5565b15610f0557610bb7846116d7565b15610ca0577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd0043385878686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a18473ffffffffffffffffffffffffffffffffffffffff168484846040518083838082843782019150509250505060006040518083038185876185025a03f1925050505060006001029050610f06565b600036436040518084848082843782019150508281526020019350505050604051809103902090508050610cd381610f0e565b158015610d3357506000610109600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15610f045784610109600050600083815260200190815260200160002060005060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff0219169083021790555083610109600050600083815260200190815260200160002060005060010160005081905550828261010960005060008481526020019081526020016000206000506002016000509190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610e0857803560ff1916838001178555610e39565b82800160010185558215610e39579182015b82811115610e38578235826000505591602001919060010190610e1a565b5b509050610e649190610e46565b80821115610e605760008181506000905550600101610e46565b5090565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32813386888787604051808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b5b5b949350505050565b600081610f1a816112db565b156112d4576000610109600050600085815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156112d357610109600050600084815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16610109600050600085815260200190815260200160002060005060010160005054610109600050600086815260200190815260200160002060005060020160005060405180828054600181600116156101000203166002900480156110765780601f1061104b57610100808354040283529160200191611076565b820191906000526020600020905b81548152906001019060200180831161105957829003601f168201915b505091505060006040518083038185876185025a03f192505050507fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a3384610109600050600087815260200190815260200160002060005060010160005054610109600050600088815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166101096000506000898152602001908152602001600020600050600201600050604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156112005780601f106111d557610100808354040283529160200191611200565b820191906000526020600020905b8154815290600101906020018083116111e357829003601f168201915b5050965050505050505060405180910390a1610109600050600084815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000506000905560028201600050805460018160011615610100020316600290046000825580601f1061128957506112c6565b601f0160209004906000526020600020908101906112c591906112a7565b808211156112c157600081815060009055506001016112a7565b5090565b5b50505060019150506112d6565b5b505b919050565b600060006000600061010260005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549250600083141561132457611535565b610103600050600086815260200190815260200160002060005091506000826000016000505414156113fd57600060005054826000016000508190555060008260010160005081905550610104600050805480919060010190908154818355818115116113c3578183600052602060002091820191016113c291906113a4565b808211156113be57600081815060009055506001016113a4565b5090565b5b5050508260020160005081905550846101046000508360020160005054815481101561000257906000526020600020900160005b50819055505b8260020a90506000818360010160005054161415611534577fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda3386604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a16001826000016000505411151561150757610104600050610103600050600087815260200190815260200160002060005060020160005054815481101561000257906000526020600020900160005b50600090556101036000506000868152602001908152602001600020600060008201600050600090556001820160005060009055600282016000506000905550506001935061153556611533565b816000016000818150548092919060019003919050555080826001016000828282505417925050819055505b5b5b505050919050565b60006000600190505b6001600050548110156116d2575b60016000505481108015611580575060006002600050826101008110156100025790900160005b505414155b15611592578080600101915050611554565b5b60016001600050541180156115c45750600060026000506001600050546101008110156100025790900160005b5054145b156115e357600160008181505480929190600190039190505550611593565b600160005054811080156116145750600060026000506001600050546101008110156100025790900160005b505414155b8015611637575060006002600050826101008110156100025790900160005b5054145b156116cd5760026000506001600050546101008110156100025790900160005b50546002600050826101008110156100025790900160005b50819055508061010260005060006002600050846101008110156100025790900160005b5054815260200190815260200160002060005081905550600060026000506001600050546101008110156100025790900160005b50819055505b611546565b5b5090565b60006116e2336109a5565b1561177157610107600050546116f6611980565b111561171b57600061010660005081905550611710611980565b610107600050819055505b610106600050548261010660005054011015801561174757506101056000505482610106600050540111155b15611768578161010660008282825054019250508190555060019050611772565b60009050611772565b5b919050565b60006000610104600050805490509150600090505b8181101561187857610109600050600061010460005083815481101561000257906000526020600020900160005b5054815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000506000905560028201600050805460018160011615610100020316600290046000825580601f1061182a5750611867565b601f0160209004906000526020600020908101906118669190611848565b808211156118625760008181506000905550600101611848565b5090565b5b5050505b806001019050805061178c565b611880611885565b5b5050565b60006000610104600050805490509150600090505b8181101561193857600060010261010460005082815481101561000257906000526020600020900160005b505414151561192a57610103600050600061010460005083815481101561000257906000526020600020900160005b50548152602001908152602001600020600060008201600050600090556001820160005060009055600282016000506000905550505b5b806001019050805061189a565b61010460005080546000825590600052602060002090810190611979919061195b565b80821115611975576000818150600090555060010161195b565b5090565b5b505b5050565b6000620151804204905061198f565b9056"++hexstring2 :: EvmHexString+hexstring2 =+ EvmHexString+ "6060604052361560275760e060020a600035046341c0e1b58114606e578063e5225381146096575b60d56000341115606c57346060908152605890600160a060020a033316907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1590602090a35b565b60d5600054600160a060020a0390811633919091161415606c57600054600160a060020a0316ff5b60d5600054600160a060020a0390811633919091161415606c5760008054600160a060020a039081169190301631606082818181858883f15050505050565b00"++-- http://solidity.readthedocs.io/en/develop/solidity-by-example.html+voteHexstring :: EvmHexString+voteHexstring =+ EvmHexString+ "6060604052341561000c57fe5b604051610abd380380610abd833981016040528080518201919050505b600033600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160016000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600090505b815181101561016b57600280548060010182816100f89190610173565b916000526020600020906002020160005b604060405190810160405280868681518110151561012357fe5b906020019060200201516000191681526020016000815250909190915060008201518160000190600019169055602082015181600101555050505b80806001019150506100db565b5b50506101d5565b8154818355818115116101a05760020281600202836000526020600020918201910161019f91906101a5565b5b505050565b6101d291905b808211156101ce57600060008201600090556001820160009055506002016101ab565b5090565b90565b6108d9806101e46000396000f3006060604052361561008c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630121b93f1461008e578063013cf08b146100ae5780632e4176cf146100f15780635c19a95c14610143578063609ff1bd146101795780639e7b8d611461019f578063a3ec138d146101d5578063e2ba53f014610264575bfe5b341561009657fe5b6100ac6004808035906020019091905050610292565b005b34156100b657fe5b6100cc6004808035906020019091905050610352565b6040518083600019166000191681526020018281526020019250505060405180910390f35b34156100f957fe5b610101610386565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561014b57fe5b610177600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506103ac565b005b341561018157fe5b610189610696565b6040518082815260200191505060405180910390f35b34156101a757fe5b6101d3600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061071d565b005b34156101dd57fe5b610209600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061081c565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b341561026c57fe5b610274610879565b60405180826000191660001916815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156102f157610000565b60018160010160006101000a81548160ff021916908315150217905550818160020181905550806000015460028381548110151561032b57fe5b906000526020600020906002020160005b50600101600082825401925050819055505b5050565b60028181548110151561036157fe5b906000526020600020906002020160005b915090508060000154908060010154905082565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091508160010160009054906101000a900460ff161561040d57610000565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561044657610000565b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561058257600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561057d57610000565b610447565b60018260010160006101000a81548160ff021916908315150217905550828260010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156106795781600001546002826002015481548110151561065257fe5b906000526020600020906002020160005b5060010160008282540192505081905550610690565b816000015481600001600082825401925050819055505b5b505050565b60006000600060009150600090505b60028054905081101561071757816002828154811015156106c257fe5b906000526020600020906002020160005b50600101541115610709576002818154811015156106ed57fe5b906000526020600020906002020160005b506001015491508092505b5b80806001019150506106a5565b5b505090565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415806107c65750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff165b156107d057610000565b6001600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055505b50565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610885610696565b81548110151561089157fe5b906000526020600020906002020160005b506000015490505b905600a165627a7a7230582083216429ab08775d8e6d7b7643b8ab38785e52186a5dca7d37aefaf2103eabcb0029"
+ test/Ethereum/Analyzer/TestData/DaoJson.hs view
@@ -0,0 +1,1790 @@+module Ethereum.Analyzer.TestData.DaoJson+ ( simpleDaoJson+ ) where++import Protolude hiding (show)++simpleDaoJson :: Text+simpleDaoJson =+ "{" <> " \"contracts\": {" <> " \"SimpleDAO_0.4.2.sol:Mallory\": {" <>+ " }," <>+ " \"SimpleDAO_0.4.2.sol:Mallory2\": {" <>+ " }," <>+ " \"SimpleDAO_0.4.2.sol:SimpleDAO\": {" <>+ " }" <>+ " }," <>+ " \"sourceList\": [" <>+ " \"SimpleDAO_0.4.2.sol\"" <>+ " ]," <>+ " \"sources\": {" <>+ " \"SimpleDAO_0.4.2.sol\": {" <>+ " \"AST\": {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"literals\": [" <>+ " \"solidity\"," <>+ " \"^\"," <>+ " \"0.4\"," <>+ " \".2\"" <>+ " ]" <>+ " }," <>+ " \"id\": 1," <>+ " \"name\": \"PragmaDirective\"," <>+ " \"src\": \"0:23:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"fullyImplemented\": true," <>+ " \"isLibrary\": false," <>+ " \"linearizedBaseContracts\": [" <>+ " 62" <>+ " ]," <>+ " \"name\": \"SimpleDAO\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"credit\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"mapping(address => uint256)\"," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"address\"" <>+ " }," <>+ " \"id\": 2," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"60:7:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"uint\"" <>+ " }," <>+ " \"id\": 3," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"71:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 4," <>+ " \"name\": \"Mapping\"," <>+ " \"src\": \"51:25:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 5," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"51:39:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"donate\"," <>+ " \"payable\": true," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"to\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"address\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"address\"" <>+ " }," <>+ " \"id\": 6," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"115:7:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 7," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"115:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 8," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"114:12:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 9," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"135:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"+=\"," <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"mapping(address => uint256)\"," <>+ " \"value\": \"credit\"" <>+ " }," <>+ " \"id\": 10," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"141:6:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"address\"," <>+ " \"value\": \"to\"" <>+ " }," <>+ " \"id\": 11," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"148:2:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 12," <>+ " \"name\": \"IndexAccess\"," <>+ " \"src\": \"141:10:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"value\"," <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"msg\"," <>+ " \"value\": \"msg\"" <>+ " }," <>+ " \"id\": 13," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"155:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 14," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"155:9:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 15," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"141:23:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 16," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"141:23:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 17," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"135:34:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 18," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"99:70:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"withdraw\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"amount\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"uint256\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"uint\"" <>+ " }," <>+ " \"id\": 19," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"195:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 20," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"195:11:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 21," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"194:13:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 22," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"208:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \">=\"," <>+ " \"type\": \"bool\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"mapping(address => uint256)\"," <>+ " \"value\": \"credit\"" <>+ " }," <>+ " \"id\": 23," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"218:6:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"sender\"," <>+ " \"type\": \"address\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"msg\"," <>+ " \"value\": \"msg\"" <>+ " }," <>+ " \"id\": 24," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"225:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 25," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"225:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 26," <>+ " \"name\": \"IndexAccess\"," <>+ " \"src\": \"218:18:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"," <>+ " \"value\": \"amount\"" <>+ " }," <>+ " \"id\": 27," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"239:6:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 28," <>+ " \"name\": \"BinaryOperation\"," <>+ " \"src\": \"218:27:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"res\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"bool\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"bool\"" <>+ " }," <>+ " \"id\": 29," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"255:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 30," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"255:8:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"bool\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"function () payable returns (bool)\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"value\"," <>+ " \"type\": \"function (uint256) returns (function () payable returns (bool))\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"call\"," <>+ " \"type\": \"function () payable returns (bool)\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"sender\"," <>+ " \"type\": \"address\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"msg\"," <>+ " \"value\": \"msg\"" <>+ " }," <>+ " \"id\": 31," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"266:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 32," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"266:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 33," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"266:15:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 34," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"266:21:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"," <>+ " \"value\": \"amount\"" <>+ " }," <>+ " \"id\": 35," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"288:6:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 36," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"266:29:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 37," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"266:31:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 38," <>+ " \"name\": \"VariableDeclarationStatement\"," <>+ " \"src\": \"255:42:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"-=\"," <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"mapping(address => uint256)\"," <>+ " \"value\": \"credit\"" <>+ " }," <>+ " \"id\": 39," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"305:6:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"sender\"," <>+ " \"type\": \"address\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"msg\"," <>+ " \"value\": \"msg\"" <>+ " }," <>+ " \"id\": 40," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"312:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 41," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"312:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 42," <>+ " \"name\": \"IndexAccess\"," <>+ " \"src\": \"305:18:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"," <>+ " \"value\": \"amount\"" <>+ " }," <>+ " \"id\": 43," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"325:6:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 44," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"305:26:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 45," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"305:26:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 46," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"247:91:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 47," <>+ " \"name\": \"IfStatement\"," <>+ " \"src\": \"214:124:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 48," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"208:134:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 49," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"177:165:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"queryCredit\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"to\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"address\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"address\"" <>+ " }," <>+ " \"id\": 50," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"369:7:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 51," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"369:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 52," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"368:12:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"uint256\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"uint\"" <>+ " }," <>+ " \"id\": 53," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"390:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 54," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"390:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 55," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"389:6:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"mapping(address => uint256)\"," <>+ " \"value\": \"credit\"" <>+ " }," <>+ " \"id\": 56," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"408:6:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"address\"," <>+ " \"value\": \"to\"" <>+ " }," <>+ " \"id\": 57," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"415:2:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 58," <>+ " \"name\": \"IndexAccess\"," <>+ " \"src\": \"408:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 59," <>+ " \"name\": \"Return\"," <>+ " \"src\": \"401:17:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 60," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"395:28:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 61," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"348:75:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 62," <>+ " \"name\": \"ContractDefinition\"," <>+ " \"src\": \"25:400:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"fullyImplemented\": true," <>+ " \"isLibrary\": false," <>+ " \"linearizedBaseContracts\": [" <>+ " 107" <>+ " ]," <>+ " \"name\": \"Mallory\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"dao\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"SimpleDAO\"" <>+ " }," <>+ " \"id\": 63," <>+ " \"name\": \"UserDefinedTypeName\"," <>+ " \"src\": \"449:9:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 64," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"449:20:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"owner\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"address\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"address\"" <>+ " }," <>+ " \"id\": 65," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"473:7:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 66," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"473:13:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"Mallory\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"addr\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"SimpleDAO\"" <>+ " }," <>+ " \"id\": 67," <>+ " \"name\": \"UserDefinedTypeName\"," <>+ " \"src\": \"508:9:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 68," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"508:14:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 69," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"507:16:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 70," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"523:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"=\"," <>+ " \"type\": \"address\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"address\"," <>+ " \"value\": \"owner\"" <>+ " }," <>+ " \"id\": 71," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"530:5:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"sender\"," <>+ " \"type\": \"address\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"msg\"," <>+ " \"value\": \"msg\"" <>+ " }," <>+ " \"id\": 72," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"538:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 73," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"538:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 74," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"530:18:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 75," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"530:18:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"=\"," <>+ " \"type\": \"contract SimpleDAO\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 76," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"554:3:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"addr\"" <>+ " }," <>+ " \"id\": 77," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"560:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 78," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"554:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 79," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"554:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 80," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"523:46:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 81," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"491:78:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"getJackpot\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 82," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"594:2:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 83," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"597:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"res\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"bool\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"bool\"" <>+ " }," <>+ " \"id\": 84," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"604:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 85," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"604:8:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"bool\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"send\"," <>+ " \"type\": \"function (uint256) returns (bool)\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"address\"," <>+ " \"value\": \"owner\"" <>+ " }," <>+ " \"id\": 86," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"615:5:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 87," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"615:10:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"balance\"," <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract Mallory\"," <>+ " \"value\": \"this\"" <>+ " }," <>+ " \"id\": 88," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"626:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 89," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"626:12:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 90," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"615:24:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 91," <>+ " \"name\": \"VariableDeclarationStatement\"," <>+ " \"src\": \"604:35:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 92," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"597:48:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 93," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"575:70:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"\"," <>+ " \"payable\": true," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 94," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"657:2:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 95," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"668:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"tuple()\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"withdraw\"," <>+ " \"type\": \"function (uint256) external\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 96," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"675:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 98," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"675:12:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"queryCredit\"," <>+ " \"type\": \"function (address) external returns (uint256)\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 99," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"688:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 100," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"688:15:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract Mallory\"," <>+ " \"value\": \"this\"" <>+ " }," <>+ " \"id\": 101," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"704:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 102," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"688:21:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 103," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"675:35:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 104," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"675:35:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 105," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"668:48:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 106," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"649:67:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 107," <>+ " \"name\": \"ContractDefinition\"," <>+ " \"src\": \"428:290:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"fullyImplemented\": true," <>+ " \"isLibrary\": false," <>+ " \"linearizedBaseContracts\": [" <>+ " 190" <>+ " ]," <>+ " \"name\": \"Mallory2\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"dao\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"SimpleDAO\"" <>+ " }," <>+ " \"id\": 108," <>+ " \"name\": \"UserDefinedTypeName\"," <>+ " \"src\": \"742:9:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 109," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"742:20:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"owner\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"address\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"address\"" <>+ " }," <>+ " \"id\": 110," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"766:7:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 111," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"766:13:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"performAttack\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"bool\"," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"bool\"" <>+ " }," <>+ " \"id\": 112," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"784:4:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"hexvalue\": \"74727565\"," <>+ " \"subdenomination\": null," <>+ " \"token\": \"true\"," <>+ " \"type\": \"bool\"," <>+ " \"value\": \"true\"" <>+ " }," <>+ " \"id\": 113," <>+ " \"name\": \"Literal\"," <>+ " \"src\": \"812:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 114," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"784:32:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"Mallory2\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"addr\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"SimpleDAO\"" <>+ " }," <>+ " \"id\": 115," <>+ " \"name\": \"UserDefinedTypeName\"," <>+ " \"src\": \"839:9:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 116," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"839:14:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 117," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"838:16:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 118," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"854:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"=\"," <>+ " \"type\": \"address\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"address\"," <>+ " \"value\": \"owner\"" <>+ " }," <>+ " \"id\": 119," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"860:5:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"sender\"," <>+ " \"type\": \"address\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"msg\"," <>+ " \"value\": \"msg\"" <>+ " }," <>+ " \"id\": 120," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"868:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 121," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"868:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 122," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"860:18:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 123," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"860:18:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"=\"," <>+ " \"type\": \"contract SimpleDAO\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 124," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"884:3:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"addr\"" <>+ " }," <>+ " \"id\": 125," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"890:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 126," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"884:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 127," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"884:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 128," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"854:45:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 129," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"821:78:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"attack\"," <>+ " \"payable\": true," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 130," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"922:2:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 131," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"932:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"tuple()\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"function (address) payable external\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"value\"," <>+ " \"type\": \"function (uint256) returns (function (address) payable external)\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"donate\"," <>+ " \"type\": \"function (address) payable external\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 132," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"938:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 135," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"938:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 136," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"938:16:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"hexvalue\": \"31\"," <>+ " \"subdenomination\": null," <>+ " \"token\": null," <>+ " \"type\": \"int_const 1\"," <>+ " \"value\": \"1\"" <>+ " }," <>+ " \"id\": 137," <>+ " \"name\": \"Literal\"," <>+ " \"src\": \"955:1:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 138," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"938:19:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract Mallory2\"," <>+ " \"value\": \"this\"" <>+ " }," <>+ " \"id\": 139," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"958:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 140," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"938:25:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 141," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"938:25:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"tuple()\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"withdraw\"," <>+ " \"type\": \"function (uint256) external\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 142," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"969:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 144," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"969:12:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"hexvalue\": \"31\"," <>+ " \"subdenomination\": null," <>+ " \"token\": null," <>+ " \"type\": \"int_const 1\"," <>+ " \"value\": \"1\"" <>+ " }," <>+ " \"id\": 145," <>+ " \"name\": \"Literal\"," <>+ " \"src\": \"982:1:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 146," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"969:15:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 147," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"969:15:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 148," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"932:57:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 149," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"907:82:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"getJackpot\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 150," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"1012:2:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 151," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"1014:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"tuple()\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"withdraw\"," <>+ " \"type\": \"function (uint256) external\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 152," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1020:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 154," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"1020:12:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"balance\"," <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 155," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1033:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 156," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"1033:11:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 157," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"1020:25:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 158," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"1020:25:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"res\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"bool\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"bool\"" <>+ " }," <>+ " \"id\": 159," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"1051:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 160," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"1051:8:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"bool\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"send\"," <>+ " \"type\": \"function (uint256) returns (bool)\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"address\"," <>+ " \"value\": \"owner\"" <>+ " }," <>+ " \"id\": 161," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1062:5:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 162," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"1062:10:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"balance\"," <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract Mallory2\"," <>+ " \"value\": \"this\"" <>+ " }," <>+ " \"id\": 163," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1073:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 164," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"1073:12:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 165," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"1062:24:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 166," <>+ " \"name\": \"VariableDeclarationStatement\"," <>+ " \"src\": \"1051:35:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"=\"," <>+ " \"type\": \"bool\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"bool\"," <>+ " \"value\": \"performAttack\"" <>+ " }," <>+ " \"id\": 167," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1092:13:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"hexvalue\": \"74727565\"," <>+ " \"subdenomination\": null," <>+ " \"token\": \"true\"," <>+ " \"type\": \"bool\"," <>+ " \"value\": \"true\"" <>+ " }," <>+ " \"id\": 168," <>+ " \"name\": \"Literal\"," <>+ " \"src\": \"1108:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 169," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"1092:20:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 170," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"1092:20:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 171," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"1014:103:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 172," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"993:124:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"\"," <>+ " \"payable\": true," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 173," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"1129:2:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 174," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"1140:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"bool\"," <>+ " \"value\": \"performAttack\"" <>+ " }," <>+ " \"id\": 175," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1150:13:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"=\"," <>+ " \"type\": \"bool\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"bool\"," <>+ " \"value\": \"performAttack\"" <>+ " }," <>+ " \"id\": 176," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1174:13:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"hexvalue\": \"66616c7365\"," <>+ " \"subdenomination\": null," <>+ " \"token\": \"false\"," <>+ " \"type\": \"bool\"," <>+ " \"value\": \"false\"" <>+ " }," <>+ " \"id\": 177," <>+ " \"name\": \"Literal\"," <>+ " \"src\": \"1190:5:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 178," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"1174:21:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 179," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"1174:21:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"tuple()\"," <>+ " \"type_conversion\": false" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"member_name\": \"withdraw\"," <>+ " \"type\": \"function (uint256) external\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"contract SimpleDAO\"," <>+ " \"value\": \"dao\"" <>+ " }," <>+ " \"id\": 180," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"1204:3:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 182," <>+ " \"name\": \"MemberAccess\"," <>+ " \"src\": \"1204:12:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"hexvalue\": \"31\"," <>+ " \"subdenomination\": null," <>+ " \"token\": null," <>+ " \"type\": \"int_const 1\"," <>+ " \"value\": \"1\"" <>+ " }," <>+ " \"id\": 183," <>+ " \"name\": \"Literal\"," <>+ " \"src\": \"1217:1:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 184," <>+ " \"name\": \"FunctionCall\"," <>+ " \"src\": \"1204:15:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 185," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"1204:15:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 186," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"1165:61:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 187," <>+ " \"name\": \"IfStatement\"," <>+ " \"src\": \"1146:80:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 188," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"1140:90:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 189," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"1121:109:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 190," <>+ " \"name\": \"ContractDefinition\"," <>+ " \"src\": \"720:512:0\"" <>+ " }" <>+ " ]," <>+ " \"name\": \"SourceUnit\"" <>+ " }" <>+ " }" <>+ " }," <>+ " \"version\": \"0.4.11+commit.68ef5810.Linux.g++\"" <>+ "}"
+ test/Ethereum/Analyzer/TestData/StorageJson.hs view
@@ -0,0 +1,237 @@+module Ethereum.Analyzer.TestData.StorageJson+ ( storageJson+ ) where++import Protolude hiding (show)++storageJson :: Text+storageJson =+ "{" <> " \"contracts\": {" <> " \"storage.sol:SimpleStorage\": {" <>+ " }" <>+ " }," <>+ " \"sourceList\": [" <>+ " \"storage.sol\"" <>+ " ]," <>+ " \"sources\": {" <>+ " \"storage.sol\": {" <>+ " \"AST\": {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"literals\": [" <>+ " \"solidity\"," <>+ " \"^\"," <>+ " \"0.4\"," <>+ " \".0\"" <>+ " ]" <>+ " }," <>+ " \"id\": 1," <>+ " \"name\": \"PragmaDirective\"," <>+ " \"src\": \"0:23:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"fullyImplemented\": true," <>+ " \"isLibrary\": false," <>+ " \"linearizedBaseContracts\": [" <>+ " 22" <>+ " ]," <>+ " \"name\": \"SimpleStorage\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"storedData\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"uint256\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"uint\"" <>+ " }," <>+ " \"id\": 2," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"52:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 3," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"52:15:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"set\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"x\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"uint256\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"uint\"" <>+ " }," <>+ " \"id\": 4," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"85:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 5," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"85:6:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 6," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"84:8:0\"" <>+ " }," <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 7," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"93:0:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"operator\": \"=\"," <>+ " \"type\": \"uint256\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"," <>+ " \"value\": \"storedData\"" <>+ " }," <>+ " \"id\": 8," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"99:10:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"," <>+ " \"value\": \"x\"" <>+ " }," <>+ " \"id\": 9," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"112:1:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 10," <>+ " \"name\": \"Assignment\"," <>+ " \"src\": \"99:14:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 11," <>+ " \"name\": \"ExpressionStatement\"," <>+ " \"src\": \"99:14:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 12," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"93:25:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 13," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"72:46:0\"" <>+ " }," <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": true," <>+ " \"name\": \"get\"," <>+ " \"payable\": false," <>+ " \"visibility\": \"public\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"children\": []," <>+ " \"id\": 14," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"134:2:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"constant\": false," <>+ " \"name\": \"\"," <>+ " \"storageLocation\": \"default\"," <>+ " \"type\": \"uint256\"," <>+ " \"visibility\": \"internal\"" <>+ " }," <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"name\": \"uint\"" <>+ " }," <>+ " \"id\": 15," <>+ " \"name\": \"ElementaryTypeName\"," <>+ " \"src\": \"155:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 16," <>+ " \"name\": \"VariableDeclaration\"," <>+ " \"src\": \"155:4:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 17," <>+ " \"name\": \"ParameterList\"," <>+ " \"src\": \"154:6:0\"" <>+ " }," <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"children\": [" <>+ " {" <>+ " \"attributes\": {" <>+ " \"type\": \"uint256\"," <>+ " \"value\": \"storedData\"" <>+ " }," <>+ " \"id\": 18," <>+ " \"name\": \"Identifier\"," <>+ " \"src\": \"174:10:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 19," <>+ " \"name\": \"Return\"," <>+ " \"src\": \"167:17:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 20," <>+ " \"name\": \"Block\"," <>+ " \"src\": \"161:28:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 21," <>+ " \"name\": \"FunctionDefinition\"," <>+ " \"src\": \"122:67:0\"" <>+ " }" <>+ " ]," <>+ " \"id\": 22," <>+ " \"name\": \"ContractDefinition\"," <>+ " \"src\": \"25:166:0\"" <>+ " }" <>+ " ]," <>+ " \"name\": \"SourceUnit\"" <>+ " }" <>+ " }" <>+ " }," <>+ " \"version\": \"0.4.11+commit.68ef5810.Linux.g++\"" <>+ "}"
test/Ethereum/Analyzer/UtilSpec.hs view
@@ -1,386 +1,399 @@+{-# LANGUAGE OverloadedStrings, NoImplicitPrelude #-}+ module Ethereum.Analyzer.UtilSpec ( spec ) where +import Protolude hiding (show)++import Data.Text import Ethereum.Analyzer import Ethereum.Analyzer.CfgAugmentPass+import Ethereum.Analyzer.TestData.Basic import Ethereum.Analyzer.Util-import Data.Text-import SpecCommon import Test.Hspec spec :: Spec-spec = do- describe "toDotText" $- do it "shows HplBody's dot graph" $- do let disasmd = disasm hexstring2- unWordLabelMapM- (unpack . toDotText . bodyOf . ctorOf <$>- (evmOps2HplContract disasmd)) `shouldBe`- "digraph {\n" ++- " 1 [label=\"CO: L1\\n" ++- "OO: 0: PUSH [96]\\n" ++- "OO: 2: PUSH [64]\\n" ++- "OO: 4: MSTORE\\n" ++- "OO: 5: CALLDATASIZE\\n" ++- "OO: 6: ISZERO\\n" ++- "OO: 7: PUSH [39]\\n" ++- "OC: 9: JUMPI -> [L2]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 2 [label=\"CO: L2\\n" ++- "OO: 10: PUSH [224]\\n" ++- "OO: 12: PUSH [2]\\n" ++- "OO: 14: EXP\\n" ++- "OO: 15: PUSH [0]\\n" ++- "OO: 17: CALLDATALOAD\\n" ++- "OO: 18: DIV\\n" ++- "OO: 19: PUSH [65,192,225,181]\\n" ++- "OO: 24: DUP2\\n" ++- "OO: 25: EQ\\n" ++- "OO: 26: PUSH [110]\\n" ++- "OC: 28: JUMPI -> [L3]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 3 [label=\"CO: L3\\n" ++- "OO: 29: DUP1\\n" ++- "OO: 30: PUSH [229,34,83,129]\\n" ++- "OO: 35: EQ\\n" ++- "OO: 36: PUSH [150]\\n" ++- "OC: 38: JUMPI -> [L4]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 4 [label=\"CO: L4\\n" ++- "OO: 39: JUMPDEST\\n" ++- "OO: 40: PUSH [213]\\n" ++- "OO: 42: PUSH [0]\\n" ++- "OO: 44: CALLVALUE\\n" ++- "OO: 45: GT\\n" ++- "OO: 46: ISZERO\\n" ++- "OO: 47: PUSH [108]\\n" ++- "OC: 49: JUMPI -> [L5]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 5 [label=\"CO: L5\\n" ++- "OO: 50: CALLVALUE\\n" ++- "OO: 51: PUSH [96]\\n" ++- "OO: 53: SWAP1\\n" ++- "OO: 54: DUP2\\n" ++- "OO: 55: MSTORE\\n" ++- "OO: 56: PUSH [88]\\n" ++- "OO: 58: SWAP1\\n" ++- "OO: 59: PUSH [1]\\n" ++- "OO: 61: PUSH [160]\\n" ++- "OO: 63: PUSH [2]\\n" ++- "OO: 65: EXP\\n" ++- "OO: 66: SUB\\n" ++- "OO: 67: CALLER\\n" ++- "OO: 68: AND\\n" ++- "OO: 69: SWAP1\\n" ++- "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\\n" ++- "OO: 103: SWAP1\\n" ++- "OO: 104: PUSH [32]\\n" ++- "OO: 106: SWAP1\\n" ++- "OC: 107: LOG3 -> [L6]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 6 [label=\"CO: L6\\n" ++- "OO: 108: JUMPDEST\\n" ++- "OC: 109: JUMP -> []\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 7 [label=\"CO: L7\\n" ++- "OO: 110: JUMPDEST\\n" ++- "OO: 111: PUSH [213]\\n" ++- "OO: 113: PUSH [0]\\n" ++- "OO: 115: SLOAD\\n" ++- "OO: 116: PUSH [1]\\n" ++- "OO: 118: PUSH [160]\\n" ++- "OO: 120: PUSH [2]\\n" ++- "OO: 122: EXP\\n" ++- "OO: 123: SUB\\n" ++- "OO: 124: SWAP1\\n" ++- "OO: 125: DUP2\\n" ++- "OO: 126: AND\\n" ++- "OO: 127: CALLER\\n" ++- "OO: 128: SWAP2\\n" ++- "OO: 129: SWAP1\\n" ++- "OO: 130: SWAP2\\n" ++- "OO: 131: AND\\n" ++- "OO: 132: EQ\\n" ++- "OO: 133: ISZERO\\n" ++- "OO: 134: PUSH [108]\\n" ++- "OC: 136: JUMPI -> [L8]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 8 [label=\"CO: L8\\n" ++- "OO: 137: PUSH [0]\\n" ++- "OO: 139: SLOAD\\n" ++- "OO: 140: PUSH [1]\\n" ++- "OO: 142: PUSH [160]\\n" ++- "OO: 144: PUSH [2]\\n" ++- "OO: 146: EXP\\n" ++- "OO: 147: SUB\\n" ++- "OO: 148: AND\\n" ++- "OC: 149: SUICIDE -> []\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 9 [label=\"CO: L9\\n" ++- "OO: 150: JUMPDEST\\n" ++- "OO: 151: PUSH [213]\\n" ++- "OO: 153: PUSH [0]\\n" ++- "OO: 155: SLOAD\\n" ++- "OO: 156: PUSH [1]\\n" ++- "OO: 158: PUSH [160]\\n" ++- "OO: 160: PUSH [2]\\n" ++- "OO: 162: EXP\\n" ++- "OO: 163: SUB\\n" ++- "OO: 164: SWAP1\\n" ++- "OO: 165: DUP2\\n" ++- "OO: 166: AND\\n" ++- "OO: 167: CALLER\\n" ++- "OO: 168: SWAP2\\n" ++- "OO: 169: SWAP1\\n" ++- "OO: 170: SWAP2\\n" ++- "OO: 171: AND\\n" ++- "OO: 172: EQ\\n" ++- "OO: 173: ISZERO\\n" ++- "OO: 174: PUSH [108]\\n" ++- "OC: 176: JUMPI -> [L10]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 10 [label=\"CO: L10\\n" ++- "OO: 177: PUSH [0]\\n" ++- "OO: 179: DUP1\\n" ++- "OO: 180: SLOAD\\n" ++- "OO: 181: PUSH [1]\\n" ++- "OO: 183: PUSH [160]\\n" ++- "OO: 185: PUSH [2]\\n" ++- "OO: 187: EXP\\n" ++- "OO: 188: SUB\\n" ++- "OO: 189: SWAP1\\n" ++- "OO: 190: DUP2\\n" ++- "OO: 191: AND\\n" ++- "OO: 192: SWAP2\\n" ++- "OO: 193: SWAP1\\n" ++- "OO: 194: ADDRESS\\n" ++- "OO: 195: AND\\n" ++- "OO: 196: BALANCE\\n" ++- "OO: 197: PUSH [96]\\n" ++- "OO: 199: DUP3\\n" ++- "OO: 200: DUP2\\n" ++- "OO: 201: DUP2\\n" ++- "OO: 202: DUP2\\n" ++- "OO: 203: DUP6\\n" ++- "OO: 204: DUP9\\n" ++- "OO: 205: DUP4\\n" ++- "OC: 206: CALL -> [L11]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 11 [label=\"CO: L11\\n" ++- "OO: 207: POP\\n" ++- "OO: 208: POP\\n" ++- "OO: 209: POP\\n" ++- "OO: 210: POP\\n" ++- "OO: 211: POP\\n" ++- "OC: 212: JUMP -> []\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 12 [label=\"CO: L12\\n" ++- "OO: 213: JUMPDEST\\n" ++- "OC: 214: STOP -> []\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 1 -> 2;\n" ++- " 2 -> 3;\n" ++- " 3 -> 4;\n" ++- " 4 -> 5;\n" ++- " 5 -> 6;\n" ++- " 7 -> 8;\n" ++ " 9 -> 10;\n" ++ " 10 -> 11;\n" ++ "}"- it "shows HplBody after CfgAugmentPass" $- do let disasmd@((_, _):_) = disasm hexstring2- result =- unWordLabelMapM $- do contract <- evmOps2HplContract disasmd- unpack . toDotText . bodyOf . ctorOf <$> doCfgAugmentPass contract- result `shouldBe` "digraph {\n" ++- " 1 [label=\"CO: L1\\n" ++- "OO: 0: PUSH [96]\\n" ++- "OO: 2: PUSH [64]\\n" ++- "OO: 4: MSTORE\\n" ++- "OO: 5: CALLDATASIZE\\n" ++- "OO: 6: ISZERO\\n" ++- "OO: 7: PUSH [39]\\n" ++- "OC: 9: JUMPI -> [L2,L4]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 2 [label=\"CO: L2\\n" ++- "OO: 10: PUSH [224]\\n" ++- "OO: 12: PUSH [2]\\n" ++- "OO: 14: EXP\\n" ++- "OO: 15: PUSH [0]\\n" ++- "OO: 17: CALLDATALOAD\\n" ++- "OO: 18: DIV\\n" ++- "OO: 19: PUSH [65,192,225,181]\\n" ++- "OO: 24: DUP2\\n" ++- "OO: 25: EQ\\n" ++- "OO: 26: PUSH [110]\\n" ++- "OC: 28: JUMPI -> [L3,L7]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 3 [label=\"CO: L3\\n" ++- "OO: 29: DUP1\\n" ++- "OO: 30: PUSH [229,34,83,129]\\n" ++- "OO: 35: EQ\\n" ++- "OO: 36: PUSH [150]\\n" ++- "OC: 38: JUMPI -> [L4,L9]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 4 [label=\"CO: L4\\n" ++- "OO: 39: JUMPDEST\\n" ++- "OO: 40: PUSH [213]\\n" ++- "OO: 42: PUSH [0]\\n" ++- "OO: 44: CALLVALUE\\n" ++- "OO: 45: GT\\n" ++- "OO: 46: ISZERO\\n" ++- "OO: 47: PUSH [108]\\n" ++- "OC: 49: JUMPI -> [L5,L6]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 5 [label=\"CO: L5\\n" ++- "OO: 50: CALLVALUE\\n" ++- "OO: 51: PUSH [96]\\n" ++- "OO: 53: SWAP1\\n" ++- "OO: 54: DUP2\\n" ++- "OO: 55: MSTORE\\n" ++- "OO: 56: PUSH [88]\\n" ++- "OO: 58: SWAP1\\n" ++- "OO: 59: PUSH [1]\\n" ++- "OO: 61: PUSH [160]\\n" ++- "OO: 63: PUSH [2]\\n" ++- "OO: 65: EXP\\n" ++- "OO: 66: SUB\\n" ++- "OO: 67: CALLER\\n" ++- "OO: 68: AND\\n" ++- "OO: 69: SWAP1\\n" ++- "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\\n" ++- "OO: 103: SWAP1\\n" ++- "OO: 104: PUSH [32]\\n" ++- "OO: 106: SWAP1\\n" ++- "OC: 107: LOG3 -> [L6]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 6 [label=\"CO: L6\\n" ++- "OO: 108: JUMPDEST\\n" ++- "OC: 109: JUMP -> []\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 7 [label=\"CO: L7\\n" ++- "OO: 110: JUMPDEST\\n" ++- "OO: 111: PUSH [213]\\n" ++- "OO: 113: PUSH [0]\\n" ++- "OO: 115: SLOAD\\n" ++- "OO: 116: PUSH [1]\\n" ++- "OO: 118: PUSH [160]\\n" ++- "OO: 120: PUSH [2]\\n" ++- "OO: 122: EXP\\n" ++- "OO: 123: SUB\\n" ++- "OO: 124: SWAP1\\n" ++- "OO: 125: DUP2\\n" ++- "OO: 126: AND\\n" ++- "OO: 127: CALLER\\n" ++- "OO: 128: SWAP2\\n" ++- "OO: 129: SWAP1\\n" ++- "OO: 130: SWAP2\\n" ++- "OO: 131: AND\\n" ++- "OO: 132: EQ\\n" ++- "OO: 133: ISZERO\\n" ++- "OO: 134: PUSH [108]\\n" ++- "OC: 136: JUMPI -> [L6,L8]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 8 [label=\"CO: L8\\n" ++- "OO: 137: PUSH [0]\\n" ++- "OO: 139: SLOAD\\n" ++- "OO: 140: PUSH [1]\\n" ++- "OO: 142: PUSH [160]\\n" ++- "OO: 144: PUSH [2]\\n" ++- "OO: 146: EXP\\n" ++- "OO: 147: SUB\\n" ++- "OO: 148: AND\\n" ++- "OC: 149: SUICIDE -> []\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 9 [label=\"CO: L9\\n" ++- "OO: 150: JUMPDEST\\n" ++- "OO: 151: PUSH [213]\\n" ++- "OO: 153: PUSH [0]\\n" ++- "OO: 155: SLOAD\\n" ++- "OO: 156: PUSH [1]\\n" ++- "OO: 158: PUSH [160]\\n" ++- "OO: 160: PUSH [2]\\n" ++- "OO: 162: EXP\\n" ++- "OO: 163: SUB\\n" ++- "OO: 164: SWAP1\\n" ++- "OO: 165: DUP2\\n" ++- "OO: 166: AND\\n" ++- "OO: 167: CALLER\\n" ++- "OO: 168: SWAP2\\n" ++- "OO: 169: SWAP1\\n" ++- "OO: 170: SWAP2\\n" ++- "OO: 171: AND\\n" ++- "OO: 172: EQ\\n" ++- "OO: 173: ISZERO\\n" ++- "OO: 174: PUSH [108]\\n" ++- "OC: 176: JUMPI -> [L6,L10]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 10 [label=\"CO: L10\\n" ++- "OO: 177: PUSH [0]\\n" ++- "OO: 179: DUP1\\n" ++- "OO: 180: SLOAD\\n" ++- "OO: 181: PUSH [1]\\n" ++- "OO: 183: PUSH [160]\\n" ++- "OO: 185: PUSH [2]\\n" ++- "OO: 187: EXP\\n" ++- "OO: 188: SUB\\n" ++- "OO: 189: SWAP1\\n" ++- "OO: 190: DUP2\\n" ++- "OO: 191: AND\\n" ++- "OO: 192: SWAP2\\n" ++- "OO: 193: SWAP1\\n" ++- "OO: 194: ADDRESS\\n" ++- "OO: 195: AND\\n" ++- "OO: 196: BALANCE\\n" ++- "OO: 197: PUSH [96]\\n" ++- "OO: 199: DUP3\\n" ++- "OO: 200: DUP2\\n" ++- "OO: 201: DUP2\\n" ++- "OO: 202: DUP2\\n" ++- "OO: 203: DUP6\\n" ++- "OO: 204: DUP9\\n" ++- "OO: 205: DUP4\\n" ++- "OC: 206: CALL -> [L11]\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 11 [label=\"CO: L11\\n" ++- "OO: 207: POP\\n" ++- "OO: 208: POP\\n" ++- "OO: 209: POP\\n" ++- "OO: 210: POP\\n" ++- "OO: 211: POP\\n" ++- "OC: 212: JUMP -> []\\n" ++- "\"\n" ++- " ,shape=box];\n" ++- " 1 -> 2;\n" ++- " 1 -> 4;\n" ++- " 2 -> 3;\n" ++- " 2 -> 7;\n" ++- " 3 -> 4;\n" ++- " 3 -> 9;\n" ++- " 4 -> 5;\n" ++- " 4 -> 6;\n" ++- " 5 -> 6;\n" ++- " 7 -> 6;\n" ++- " 7 -> 8;\n" ++- " 9 -> 6;\n" ++ " 9 -> 10;\n" ++ " 10 -> 11;\n" ++ "}"+spec =+ describe "toDotText" $ do+ it "shows HplBody's dot graph" $ do+ let disasmd = disasm hexstring2+ (unpack . unWordLabelMapM)+ (toDotText . bodyOf . ctorOf <$> evmOps2HplContract disasmd) `shouldBe`+ toS expectedHexString2RawDot+ it "shows HplBody after CfgAugmentPass" $ do+ let disasmd@((_, _):_) = disasm hexstring2+ result =+ (unpack . unWordLabelMapM) $ do+ contract <- evmOps2HplContract disasmd+ toDotText . bodyOf . ctorOf <$> doCfgAugmentPass contract+ result `shouldBe` toS expectedHexString2AugDot++expectedHexString2RawDot :: Text+expectedHexString2RawDot =+ "digraph {\n" <> " 1 [label=\"CO: L1\\n" <> "OO: 0: PUSH [96]\\n" <>+ "OO: 2: PUSH [64]\\n" <>+ "OO: 4: MSTORE\\n" <>+ "OO: 5: CALLDATASIZE\\n" <>+ "OO: 6: ISZERO\\n" <>+ "OO: 7: PUSH [39]\\n" <>+ "OC: 9: JUMPI -> [L2]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 2 [label=\"CO: L2\\n" <>+ "OO: 10: PUSH [224]\\n" <>+ "OO: 12: PUSH [2]\\n" <>+ "OO: 14: EXP\\n" <>+ "OO: 15: PUSH [0]\\n" <>+ "OO: 17: CALLDATALOAD\\n" <>+ "OO: 18: DIV\\n" <>+ "OO: 19: PUSH [65,192,225,181]\\n" <>+ "OO: 24: DUP2\\n" <>+ "OO: 25: EQ\\n" <>+ "OO: 26: PUSH [110]\\n" <>+ "OC: 28: JUMPI -> [L3]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 3 [label=\"CO: L3\\n" <>+ "OO: 29: DUP1\\n" <>+ "OO: 30: PUSH [229,34,83,129]\\n" <>+ "OO: 35: EQ\\n" <>+ "OO: 36: PUSH [150]\\n" <>+ "OC: 38: JUMPI -> [L4]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 4 [label=\"CO: L4\\n" <>+ "OO: 39: JUMPDEST\\n" <>+ "OO: 40: PUSH [213]\\n" <>+ "OO: 42: PUSH [0]\\n" <>+ "OO: 44: CALLVALUE\\n" <>+ "OO: 45: GT\\n" <>+ "OO: 46: ISZERO\\n" <>+ "OO: 47: PUSH [108]\\n" <>+ "OC: 49: JUMPI -> [L5]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 5 [label=\"CO: L5\\n" <>+ "OO: 50: CALLVALUE\\n" <>+ "OO: 51: PUSH [96]\\n" <>+ "OO: 53: SWAP1\\n" <>+ "OO: 54: DUP2\\n" <>+ "OO: 55: MSTORE\\n" <>+ "OO: 56: PUSH [88]\\n" <>+ "OO: 58: SWAP1\\n" <>+ "OO: 59: PUSH [1]\\n" <>+ "OO: 61: PUSH [160]\\n" <>+ "OO: 63: PUSH [2]\\n" <>+ "OO: 65: EXP\\n" <>+ "OO: 66: SUB\\n" <>+ "OO: 67: CALLER\\n" <>+ "OO: 68: AND\\n" <>+ "OO: 69: SWAP1\\n" <>+ "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\\n" <>+ "OO: 103: SWAP1\\n" <>+ "OO: 104: PUSH [32]\\n" <>+ "OO: 106: SWAP1\\n" <>+ "OC: 107: LOG3 -> [L6]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 6 [label=\"CO: L6\\n" <>+ "OO: 108: JUMPDEST\\n" <>+ "OC: 109: JUMP -> []\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 7 [label=\"CO: L7\\n" <>+ "OO: 110: JUMPDEST\\n" <>+ "OO: 111: PUSH [213]\\n" <>+ "OO: 113: PUSH [0]\\n" <>+ "OO: 115: SLOAD\\n" <>+ "OO: 116: PUSH [1]\\n" <>+ "OO: 118: PUSH [160]\\n" <>+ "OO: 120: PUSH [2]\\n" <>+ "OO: 122: EXP\\n" <>+ "OO: 123: SUB\\n" <>+ "OO: 124: SWAP1\\n" <>+ "OO: 125: DUP2\\n" <>+ "OO: 126: AND\\n" <>+ "OO: 127: CALLER\\n" <>+ "OO: 128: SWAP2\\n" <>+ "OO: 129: SWAP1\\n" <>+ "OO: 130: SWAP2\\n" <>+ "OO: 131: AND\\n" <>+ "OO: 132: EQ\\n" <>+ "OO: 133: ISZERO\\n" <>+ "OO: 134: PUSH [108]\\n" <>+ "OC: 136: JUMPI -> [L8]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 8 [label=\"CO: L8\\n" <>+ "OO: 137: PUSH [0]\\n" <>+ "OO: 139: SLOAD\\n" <>+ "OO: 140: PUSH [1]\\n" <>+ "OO: 142: PUSH [160]\\n" <>+ "OO: 144: PUSH [2]\\n" <>+ "OO: 146: EXP\\n" <>+ "OO: 147: SUB\\n" <>+ "OO: 148: AND\\n" <>+ "OC: 149: SUICIDE -> []\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 9 [label=\"CO: L9\\n" <>+ "OO: 150: JUMPDEST\\n" <>+ "OO: 151: PUSH [213]\\n" <>+ "OO: 153: PUSH [0]\\n" <>+ "OO: 155: SLOAD\\n" <>+ "OO: 156: PUSH [1]\\n" <>+ "OO: 158: PUSH [160]\\n" <>+ "OO: 160: PUSH [2]\\n" <>+ "OO: 162: EXP\\n" <>+ "OO: 163: SUB\\n" <>+ "OO: 164: SWAP1\\n" <>+ "OO: 165: DUP2\\n" <>+ "OO: 166: AND\\n" <>+ "OO: 167: CALLER\\n" <>+ "OO: 168: SWAP2\\n" <>+ "OO: 169: SWAP1\\n" <>+ "OO: 170: SWAP2\\n" <>+ "OO: 171: AND\\n" <>+ "OO: 172: EQ\\n" <>+ "OO: 173: ISZERO\\n" <>+ "OO: 174: PUSH [108]\\n" <>+ "OC: 176: JUMPI -> [L10]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 10 [label=\"CO: L10\\n" <>+ "OO: 177: PUSH [0]\\n" <>+ "OO: 179: DUP1\\n" <>+ "OO: 180: SLOAD\\n" <>+ "OO: 181: PUSH [1]\\n" <>+ "OO: 183: PUSH [160]\\n" <>+ "OO: 185: PUSH [2]\\n" <>+ "OO: 187: EXP\\n" <>+ "OO: 188: SUB\\n" <>+ "OO: 189: SWAP1\\n" <>+ "OO: 190: DUP2\\n" <>+ "OO: 191: AND\\n" <>+ "OO: 192: SWAP2\\n" <>+ "OO: 193: SWAP1\\n" <>+ "OO: 194: ADDRESS\\n" <>+ "OO: 195: AND\\n" <>+ "OO: 196: BALANCE\\n" <>+ "OO: 197: PUSH [96]\\n" <>+ "OO: 199: DUP3\\n" <>+ "OO: 200: DUP2\\n" <>+ "OO: 201: DUP2\\n" <>+ "OO: 202: DUP2\\n" <>+ "OO: 203: DUP6\\n" <>+ "OO: 204: DUP9\\n" <>+ "OO: 205: DUP4\\n" <>+ "OC: 206: CALL -> [L11]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 11 [label=\"CO: L11\\n" <>+ "OO: 207: POP\\n" <>+ "OO: 208: POP\\n" <>+ "OO: 209: POP\\n" <>+ "OO: 210: POP\\n" <>+ "OO: 211: POP\\n" <>+ "OC: 212: JUMP -> []\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 12 [label=\"CO: L12\\n" <>+ "OO: 213: JUMPDEST\\n" <>+ "OC: 214: STOP -> []\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 1 -> 2;\n" <>+ " 2 -> 3;\n" <>+ " 3 -> 4;\n" <>+ " 4 -> 5;\n" <>+ " 5 -> 6;\n" <>+ " 7 -> 8;\n" <>+ " 9 -> 10;\n" <>+ " 10 -> 11;\n" <>+ "}"++expectedHexString2AugDot :: Text+expectedHexString2AugDot =+ "digraph {\n" <> " 1 [label=\"CO: L1\\n" <> "OO: 0: PUSH [96]\\n" <>+ "OO: 2: PUSH [64]\\n" <>+ "OO: 4: MSTORE\\n" <>+ "OO: 5: CALLDATASIZE\\n" <>+ "OO: 6: ISZERO\\n" <>+ "OO: 7: PUSH [39]\\n" <>+ "OC: 9: JUMPI -> [L2,L4]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 2 [label=\"CO: L2\\n" <>+ "OO: 10: PUSH [224]\\n" <>+ "OO: 12: PUSH [2]\\n" <>+ "OO: 14: EXP\\n" <>+ "OO: 15: PUSH [0]\\n" <>+ "OO: 17: CALLDATALOAD\\n" <>+ "OO: 18: DIV\\n" <>+ "OO: 19: PUSH [65,192,225,181]\\n" <>+ "OO: 24: DUP2\\n" <>+ "OO: 25: EQ\\n" <>+ "OO: 26: PUSH [110]\\n" <>+ "OC: 28: JUMPI -> [L3,L7]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 3 [label=\"CO: L3\\n" <>+ "OO: 29: DUP1\\n" <>+ "OO: 30: PUSH [229,34,83,129]\\n" <>+ "OO: 35: EQ\\n" <>+ "OO: 36: PUSH [150]\\n" <>+ "OC: 38: JUMPI -> [L4,L9]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 4 [label=\"CO: L4\\n" <>+ "OO: 39: JUMPDEST\\n" <>+ "OO: 40: PUSH [213]\\n" <>+ "OO: 42: PUSH [0]\\n" <>+ "OO: 44: CALLVALUE\\n" <>+ "OO: 45: GT\\n" <>+ "OO: 46: ISZERO\\n" <>+ "OO: 47: PUSH [108]\\n" <>+ "OC: 49: JUMPI -> [L5,L6]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 5 [label=\"CO: L5\\n" <>+ "OO: 50: CALLVALUE\\n" <>+ "OO: 51: PUSH [96]\\n" <>+ "OO: 53: SWAP1\\n" <>+ "OO: 54: DUP2\\n" <>+ "OO: 55: MSTORE\\n" <>+ "OO: 56: PUSH [88]\\n" <>+ "OO: 58: SWAP1\\n" <>+ "OO: 59: PUSH [1]\\n" <>+ "OO: 61: PUSH [160]\\n" <>+ "OO: 63: PUSH [2]\\n" <>+ "OO: 65: EXP\\n" <>+ "OO: 66: SUB\\n" <>+ "OO: 67: CALLER\\n" <>+ "OO: 68: AND\\n" <>+ "OO: 69: SWAP1\\n" <>+ "OO: 70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\\n" <>+ "OO: 103: SWAP1\\n" <>+ "OO: 104: PUSH [32]\\n" <>+ "OO: 106: SWAP1\\n" <>+ "OC: 107: LOG3 -> [L6]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 6 [label=\"CO: L6\\n" <>+ "OO: 108: JUMPDEST\\n" <>+ "OC: 109: JUMP -> []\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 7 [label=\"CO: L7\\n" <>+ "OO: 110: JUMPDEST\\n" <>+ "OO: 111: PUSH [213]\\n" <>+ "OO: 113: PUSH [0]\\n" <>+ "OO: 115: SLOAD\\n" <>+ "OO: 116: PUSH [1]\\n" <>+ "OO: 118: PUSH [160]\\n" <>+ "OO: 120: PUSH [2]\\n" <>+ "OO: 122: EXP\\n" <>+ "OO: 123: SUB\\n" <>+ "OO: 124: SWAP1\\n" <>+ "OO: 125: DUP2\\n" <>+ "OO: 126: AND\\n" <>+ "OO: 127: CALLER\\n" <>+ "OO: 128: SWAP2\\n" <>+ "OO: 129: SWAP1\\n" <>+ "OO: 130: SWAP2\\n" <>+ "OO: 131: AND\\n" <>+ "OO: 132: EQ\\n" <>+ "OO: 133: ISZERO\\n" <>+ "OO: 134: PUSH [108]\\n" <>+ "OC: 136: JUMPI -> [L6,L8]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 8 [label=\"CO: L8\\n" <>+ "OO: 137: PUSH [0]\\n" <>+ "OO: 139: SLOAD\\n" <>+ "OO: 140: PUSH [1]\\n" <>+ "OO: 142: PUSH [160]\\n" <>+ "OO: 144: PUSH [2]\\n" <>+ "OO: 146: EXP\\n" <>+ "OO: 147: SUB\\n" <>+ "OO: 148: AND\\n" <>+ "OC: 149: SUICIDE -> []\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 9 [label=\"CO: L9\\n" <>+ "OO: 150: JUMPDEST\\n" <>+ "OO: 151: PUSH [213]\\n" <>+ "OO: 153: PUSH [0]\\n" <>+ "OO: 155: SLOAD\\n" <>+ "OO: 156: PUSH [1]\\n" <>+ "OO: 158: PUSH [160]\\n" <>+ "OO: 160: PUSH [2]\\n" <>+ "OO: 162: EXP\\n" <>+ "OO: 163: SUB\\n" <>+ "OO: 164: SWAP1\\n" <>+ "OO: 165: DUP2\\n" <>+ "OO: 166: AND\\n" <>+ "OO: 167: CALLER\\n" <>+ "OO: 168: SWAP2\\n" <>+ "OO: 169: SWAP1\\n" <>+ "OO: 170: SWAP2\\n" <>+ "OO: 171: AND\\n" <>+ "OO: 172: EQ\\n" <>+ "OO: 173: ISZERO\\n" <>+ "OO: 174: PUSH [108]\\n" <>+ "OC: 176: JUMPI -> [L6,L10]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 10 [label=\"CO: L10\\n" <>+ "OO: 177: PUSH [0]\\n" <>+ "OO: 179: DUP1\\n" <>+ "OO: 180: SLOAD\\n" <>+ "OO: 181: PUSH [1]\\n" <>+ "OO: 183: PUSH [160]\\n" <>+ "OO: 185: PUSH [2]\\n" <>+ "OO: 187: EXP\\n" <>+ "OO: 188: SUB\\n" <>+ "OO: 189: SWAP1\\n" <>+ "OO: 190: DUP2\\n" <>+ "OO: 191: AND\\n" <>+ "OO: 192: SWAP2\\n" <>+ "OO: 193: SWAP1\\n" <>+ "OO: 194: ADDRESS\\n" <>+ "OO: 195: AND\\n" <>+ "OO: 196: BALANCE\\n" <>+ "OO: 197: PUSH [96]\\n" <>+ "OO: 199: DUP3\\n" <>+ "OO: 200: DUP2\\n" <>+ "OO: 201: DUP2\\n" <>+ "OO: 202: DUP2\\n" <>+ "OO: 203: DUP6\\n" <>+ "OO: 204: DUP9\\n" <>+ "OO: 205: DUP4\\n" <>+ "OC: 206: CALL -> [L11]\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 11 [label=\"CO: L11\\n" <>+ "OO: 207: POP\\n" <>+ "OO: 208: POP\\n" <>+ "OO: 209: POP\\n" <>+ "OO: 210: POP\\n" <>+ "OO: 211: POP\\n" <>+ "OC: 212: JUMP -> []\\n" <>+ "\"\n" <>+ " ,shape=box];\n" <>+ " 1 -> 2;\n" <>+ " 1 -> 4;\n" <>+ " 2 -> 3;\n" <>+ " 2 -> 7;\n" <>+ " 3 -> 4;\n" <>+ " 3 -> 9;\n" <>+ " 4 -> 5;\n" <>+ " 4 -> 6;\n" <>+ " 5 -> 6;\n" <>+ " 7 -> 6;\n" <>+ " 7 -> 8;\n" <>+ " 9 -> 6;\n" <>+ " 9 -> 10;\n" <>+ " 10 -> 11;\n" <>+ "}"
test/Ethereum/AnalyzerSpec.hs view
@@ -4,155 +4,158 @@ ( spec ) where -import Ethereum.Analyzer+import Protolude hiding (show)+ import Data.List as DL import Data.List.Extra as DLE-import SpecCommon+import Ethereum.Analyzer+import Ethereum.Analyzer.TestData.Basic+import GHC.Show import Test.Hspec spec :: Spec-spec = do- describe "disasm" $- do it "works for hexstring1" $- do let disasmd1 = show $ showOps $ disasm hexstring1- DL.take 60 disasmd1 `shouldBe`- "[\"0: PUSH [96]\",\"2: PUSH [64]\",\"4: MSTORE\",\"5: PUSH [2]\",\"7:"- DLE.takeEnd 60 disasmd1 `shouldBe`- "]\",\"6989: JUMP\",\"6990: JUMPDEST\",\"6991: SWAP1\",\"6992: JUMP\"]"- it "works for hexstring2" $- do let disasmd2 = show $ showOps $ disasm hexstring2- disasmd2 `shouldBe` "[\"0: PUSH [96]\"," ++- "\"2: PUSH [64]\"," ++- "\"4: MSTORE\"," ++- "\"5: CALLDATASIZE\"," ++- "\"6: ISZERO\"," ++- "\"7: PUSH [39]\"," ++- "\"9: JUMPI\"," ++- "\"10: PUSH [224]\"," ++- "\"12: PUSH [2]\"," ++- "\"14: EXP\"," ++- "\"15: PUSH [0]\"," ++- "\"17: CALLDATALOAD\"," ++- "\"18: DIV\"," ++- "\"19: PUSH [65,192,225,181]\"," ++- "\"24: DUP2\"," ++- "\"25: EQ\"," ++- "\"26: PUSH [110]\"," ++- "\"28: JUMPI\"," ++- "\"29: DUP1\"," ++- "\"30: PUSH [229,34,83,129]\"," ++- "\"35: EQ\"," ++- "\"36: PUSH [150]\"," ++- "\"38: JUMPI\"," ++- "\"39: JUMPDEST\"," ++- "\"40: PUSH [213]\"," ++- "\"42: PUSH [0]\"," ++- "\"44: CALLVALUE\"," ++- "\"45: GT\"," ++- "\"46: ISZERO\"," ++- "\"47: PUSH [108]\"," ++- "\"49: JUMPI\"," ++- "\"50: CALLVALUE\"," ++- "\"51: PUSH [96]\"," ++- "\"53: SWAP1\"," ++- "\"54: DUP2\"," ++- "\"55: MSTORE\"," ++- "\"56: PUSH [88]\"," ++- "\"58: SWAP1\"," ++- "\"59: PUSH [1]\"," ++- "\"61: PUSH [160]\"," ++- "\"63: PUSH [2]\"," ++- "\"65: EXP\"," ++- "\"66: SUB\"," ++- "\"67: CALLER\"," ++- "\"68: AND\"," ++- "\"69: SWAP1\"," ++- "\"70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\"," ++- "\"103: SWAP1\"," ++- "\"104: PUSH [32]\"," ++- "\"106: SWAP1\"," ++- "\"107: LOG3\"," ++- "\"108: JUMPDEST\"," ++- "\"109: JUMP\"," ++- "\"110: JUMPDEST\"," ++- "\"111: PUSH [213]\"," ++- "\"113: PUSH [0]\"," ++- "\"115: SLOAD\"," ++- "\"116: PUSH [1]\"," ++- "\"118: PUSH [160]\"," ++- "\"120: PUSH [2]\"," ++- "\"122: EXP\"," ++- "\"123: SUB\"," ++- "\"124: SWAP1\"," ++- "\"125: DUP2\"," ++- "\"126: AND\"," ++- "\"127: CALLER\"," ++- "\"128: SWAP2\"," ++- "\"129: SWAP1\"," ++- "\"130: SWAP2\"," ++- "\"131: AND\"," ++- "\"132: EQ\"," ++- "\"133: ISZERO\"," ++- "\"134: PUSH [108]\"," ++- "\"136: JUMPI\"," ++- "\"137: PUSH [0]\"," ++- "\"139: SLOAD\"," ++- "\"140: PUSH [1]\"," ++- "\"142: PUSH [160]\"," ++- "\"144: PUSH [2]\"," ++- "\"146: EXP\"," ++- "\"147: SUB\"," ++- "\"148: AND\"," ++- "\"149: SUICIDE\"," ++- "\"150: JUMPDEST\"," ++- "\"151: PUSH [213]\"," ++- "\"153: PUSH [0]\"," ++- "\"155: SLOAD\"," ++- "\"156: PUSH [1]\"," ++- "\"158: PUSH [160]\"," ++- "\"160: PUSH [2]\"," ++- "\"162: EXP\"," ++- "\"163: SUB\"," ++- "\"164: SWAP1\"," ++- "\"165: DUP2\"," ++- "\"166: AND\"," ++- "\"167: CALLER\"," ++- "\"168: SWAP2\"," ++- "\"169: SWAP1\"," ++- "\"170: SWAP2\"," ++- "\"171: AND\"," ++- "\"172: EQ\"," ++- "\"173: ISZERO\"," ++- "\"174: PUSH [108]\"," ++- "\"176: JUMPI\"," ++- "\"177: PUSH [0]\"," ++- "\"179: DUP1\"," ++- "\"180: SLOAD\"," ++- "\"181: PUSH [1]\"," ++- "\"183: PUSH [160]\"," ++- "\"185: PUSH [2]\"," ++- "\"187: EXP\"," ++- "\"188: SUB\"," ++- "\"189: SWAP1\"," ++- "\"190: DUP2\"," ++- "\"191: AND\"," ++- "\"192: SWAP2\"," ++- "\"193: SWAP1\"," ++- "\"194: ADDRESS\"," ++- "\"195: AND\"," ++- "\"196: BALANCE\"," ++- "\"197: PUSH [96]\"," ++- "\"199: DUP3\"," ++- "\"200: DUP2\"," ++- "\"201: DUP2\"," ++- "\"202: DUP2\"," ++- "\"203: DUP6\"," ++- "\"204: DUP9\"," ++- "\"205: DUP4\"," ++- "\"206: CALL\"," ++- "\"207: POP\"," ++- "\"208: POP\"," ++- "\"209: POP\"," ++- "\"210: POP\"," ++- "\"211: POP\"," ++- "\"212: JUMP\"," ++ "\"213: JUMPDEST\"," ++ "\"214: STOP\"]"+spec =+ describe "disasm" $ do+ it "works for hexstring1" $ do+ let disasmd1 = toS $ show $ showOps $ disasm hexstring1+ DL.take 60 disasmd1 `shouldBe`+ "[\"0: PUSH [96]\",\"2: PUSH [64]\",\"4: MSTORE\",\"5: PUSH [2]\",\"7:"+ DLE.takeEnd 60 disasmd1 `shouldBe`+ "]\",\"6989: JUMP\",\"6990: JUMPDEST\",\"6991: SWAP1\",\"6992: JUMP\"]"+ it "works for hexstring2" $ do+ let disasmd2 = toS $ show $ showOps $ disasm hexstring2+ disasmd2 `shouldBe` "[\"0: PUSH [96]\"," +++ "\"2: PUSH [64]\"," +++ "\"4: MSTORE\"," +++ "\"5: CALLDATASIZE\"," +++ "\"6: ISZERO\"," +++ "\"7: PUSH [39]\"," +++ "\"9: JUMPI\"," +++ "\"10: PUSH [224]\"," +++ "\"12: PUSH [2]\"," +++ "\"14: EXP\"," +++ "\"15: PUSH [0]\"," +++ "\"17: CALLDATALOAD\"," +++ "\"18: DIV\"," +++ "\"19: PUSH [65,192,225,181]\"," +++ "\"24: DUP2\"," +++ "\"25: EQ\"," +++ "\"26: PUSH [110]\"," +++ "\"28: JUMPI\"," +++ "\"29: DUP1\"," +++ "\"30: PUSH [229,34,83,129]\"," +++ "\"35: EQ\"," +++ "\"36: PUSH [150]\"," +++ "\"38: JUMPI\"," +++ "\"39: JUMPDEST\"," +++ "\"40: PUSH [213]\"," +++ "\"42: PUSH [0]\"," +++ "\"44: CALLVALUE\"," +++ "\"45: GT\"," +++ "\"46: ISZERO\"," +++ "\"47: PUSH [108]\"," +++ "\"49: JUMPI\"," +++ "\"50: CALLVALUE\"," +++ "\"51: PUSH [96]\"," +++ "\"53: SWAP1\"," +++ "\"54: DUP2\"," +++ "\"55: MSTORE\"," +++ "\"56: PUSH [88]\"," +++ "\"58: SWAP1\"," +++ "\"59: PUSH [1]\"," +++ "\"61: PUSH [160]\"," +++ "\"63: PUSH [2]\"," +++ "\"65: EXP\"," +++ "\"66: SUB\"," +++ "\"67: CALLER\"," +++ "\"68: AND\"," +++ "\"69: SWAP1\"," +++ "\"70: PUSH [144,137,8,9,198,84,241,29,110,114,162,143,166,1,73,119,10,13,17,236,108,146,49,157,108,235,43,176,164,234,26,21]\"," +++ "\"103: SWAP1\"," +++ "\"104: PUSH [32]\"," +++ "\"106: SWAP1\"," +++ "\"107: LOG3\"," +++ "\"108: JUMPDEST\"," +++ "\"109: JUMP\"," +++ "\"110: JUMPDEST\"," +++ "\"111: PUSH [213]\"," +++ "\"113: PUSH [0]\"," +++ "\"115: SLOAD\"," +++ "\"116: PUSH [1]\"," +++ "\"118: PUSH [160]\"," +++ "\"120: PUSH [2]\"," +++ "\"122: EXP\"," +++ "\"123: SUB\"," +++ "\"124: SWAP1\"," +++ "\"125: DUP2\"," +++ "\"126: AND\"," +++ "\"127: CALLER\"," +++ "\"128: SWAP2\"," +++ "\"129: SWAP1\"," +++ "\"130: SWAP2\"," +++ "\"131: AND\"," +++ "\"132: EQ\"," +++ "\"133: ISZERO\"," +++ "\"134: PUSH [108]\"," +++ "\"136: JUMPI\"," +++ "\"137: PUSH [0]\"," +++ "\"139: SLOAD\"," +++ "\"140: PUSH [1]\"," +++ "\"142: PUSH [160]\"," +++ "\"144: PUSH [2]\"," +++ "\"146: EXP\"," +++ "\"147: SUB\"," +++ "\"148: AND\"," +++ "\"149: SUICIDE\"," +++ "\"150: JUMPDEST\"," +++ "\"151: PUSH [213]\"," +++ "\"153: PUSH [0]\"," +++ "\"155: SLOAD\"," +++ "\"156: PUSH [1]\"," +++ "\"158: PUSH [160]\"," +++ "\"160: PUSH [2]\"," +++ "\"162: EXP\"," +++ "\"163: SUB\"," +++ "\"164: SWAP1\"," +++ "\"165: DUP2\"," +++ "\"166: AND\"," +++ "\"167: CALLER\"," +++ "\"168: SWAP2\"," +++ "\"169: SWAP1\"," +++ "\"170: SWAP2\"," +++ "\"171: AND\"," +++ "\"172: EQ\"," +++ "\"173: ISZERO\"," +++ "\"174: PUSH [108]\"," +++ "\"176: JUMPI\"," +++ "\"177: PUSH [0]\"," +++ "\"179: DUP1\"," +++ "\"180: SLOAD\"," +++ "\"181: PUSH [1]\"," +++ "\"183: PUSH [160]\"," +++ "\"185: PUSH [2]\"," +++ "\"187: EXP\"," +++ "\"188: SUB\"," +++ "\"189: SWAP1\"," +++ "\"190: DUP2\"," +++ "\"191: AND\"," +++ "\"192: SWAP2\"," +++ "\"193: SWAP1\"," +++ "\"194: ADDRESS\"," +++ "\"195: AND\"," +++ "\"196: BALANCE\"," +++ "\"197: PUSH [96]\"," +++ "\"199: DUP3\"," +++ "\"200: DUP2\"," +++ "\"201: DUP2\"," +++ "\"202: DUP2\"," +++ "\"203: DUP6\"," +++ "\"204: DUP9\"," +++ "\"205: DUP4\"," +++ "\"206: CALL\"," +++ "\"207: POP\"," +++ "\"208: POP\"," +++ "\"209: POP\"," +++ "\"210: POP\"," +++ "\"211: POP\"," +++ "\"212: JUMP\"," ++ "\"213: JUMPDEST\"," ++ "\"214: STOP\"]"
− test/SpecCommon.hs
@@ -1,25 +0,0 @@-{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}--module SpecCommon- ( hexstring1- , hexstring2- , voteHexstring- ) where--import Ethereum.Analyzer.Disasm--hexstring1 :: EvmHexString-hexstring1 =- EvmHexString- "6060604052600261010860005055604051611b51380380611b51833981016040528080518201919060200180519060200190919080519060200190919050505b805b83835b600060018351016001600050819055503373ffffffffffffffffffffffffffffffffffffffff16600260005060016101008110156100025790900160005b5081905550600161010260005060003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005081905550600090505b825181101561016e5782818151811015610002579060200190602002015173ffffffffffffffffffffffffffffffffffffffff166002600050826002016101008110156100025790900160005b508190555080600201610102600050600085848151811015610002579060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b80600101905080506100c2565b816000600050819055505b505050806101056000508190555061018f6101ad565b610107600050819055505b505b505050611992806101bf6000396000f35b600062015180420490506101bc565b9056606060405236156100f8576000357c010000000000000000000000000000000000000000000000000000000090048063173825d9146101605780632f54bf6e146101785780634123cb6b146101a457806352375093146101c757806354fd4d50146101ea5780635c52c2f51461020d578063659010e71461021c5780637065cb481461023f578063746c917114610257578063797af6271461027a578063b20d30a9146102a6578063b61d27f6146102be578063b75c7dc614610307578063ba51a6df1461031f578063c2cf732614610337578063cbf0b0c01461036c578063f00d4b5d14610384578063f1736d86146103a5576100f8565b61015e5b600034111561015b577fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3334604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b565b005b61017660048080359060200190919050506107c4565b005b61018e60048080359060200190919050506109a5565b6040518082815260200191505060405180910390f35b6101b16004805050610a91565b6040518082815260200191505060405180910390f35b6101d46004805050610b38565b6040518082815260200191505060405180910390f35b6101f76004805050610b42565b6040518082815260200191505060405180910390f35b61021a6004805050610adf565b005b6102296004805050610b2e565b6040518082815260200191505060405180910390f35b610255600480803590602001909190505061066e565b005b6102646004805050610a88565b6040518082815260200191505060405180910390f35b6102906004808035906020019091905050610f0e565b6040518082815260200191505060405180910390f35b6102bc6004808035906020019091905050610a9a565b005b6102f160048080359060200190919080359060200190919080359060200190820180359060200191909192905050610b9e565b6040518082815260200191505060405180910390f35b61031d60048080359060200190919050506103c8565b005b610335600480803590602001909190505061090f565b005b61035660048080359060200190919080359060200190919050506109e7565b6040518082815260200191505060405180910390f35b6103826004808035906020019091905050610b4c565b005b6103a360048080359060200190919080359060200190919050506104ca565b005b6103b26004805050610b24565b6040518082815260200191505060405180910390f35b60006000600061010260005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549250600083141561040f576104c4565b8260020a91506101036000506000858152602001908152602001600020600050905060008282600101600050541611156104c3578060000160008181505480929190600101919050555081816001016000828282505403925050819055507fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b3385604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b50505050565b600060003643604051808484808284378201915050828152602001935050505060405180910390206104fb816112db565b1561066757610509836109a5565b156105145750610669565b61010260005060008573ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054915060008214156105565750610669565b61055e611777565b8273ffffffffffffffffffffffffffffffffffffffff166002600050836101008110156100025790900160005b5081905550600061010260005060008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055508161010260005060008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c8484604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b505b505050565b600036436040518084848082843782019150508281526020019350505050604051809103902061069d816112db565b156107bf576106ab826109a5565b156106b657506107c1565b6106be611777565b60fa6001600050541015156106d7576106d561153d565b505b60fa6001600050541015156106ec57506107c1565b60016000818150548092919060010191905055508173ffffffffffffffffffffffffffffffffffffffff1660026000506001600050546101008110156100025790900160005b508190555060016000505461010260005060008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c382604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b505b50565b600060003643604051808484808284378201915050828152602001935050505060405180910390206107f5816112db565b156109095761010260005060008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549150600082141561083c575061090b565b6001600160005054036000600050541115610857575061090b565b60006002600050836101008110156100025790900160005b5081905550600061010260005060008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055506108b2611777565b6108ba61153d565b507f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da83604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b505b5050565b600036436040518084848082843782019150508281526020019350505050604051809103902061093e816112db565b156109a05760016000505482111561095657506109a2565b81600060005081905550610968611777565b7facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da826040518082815260200191505060405180910390a15b505b50565b6000600061010260005060008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050541190506109e2565b919050565b60006000600060006101036000506000878152602001908152602001600020600050925061010260005060008673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505491506000821415610a505760009350610a7f565b8160020a90506000818460010160005054161415610a755760009350610a7f56610a7e565b60019350610a7f565b5b50505092915050565b60006000505481565b60016000505481565b6000364360405180848480828437820191505082815260200193505050506040518091039020610ac9816112db565b15610ada5781610105600050819055505b505b50565b6000364360405180848480828437820191505082815260200193505050506040518091039020610b0e816112db565b15610b20576000610106600050819055505b505b565b6101056000505481565b6101066000505481565b6101076000505481565b6101086000505481565b6000364360405180848480828437820191505082815260200193505050506040518091039020610b7b816112db565b15610b99578173ffffffffffffffffffffffffffffffffffffffff16ff5b505b50565b6000610ba9336109a5565b15610f0557610bb7846116d7565b15610ca0577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd0043385878686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a18473ffffffffffffffffffffffffffffffffffffffff168484846040518083838082843782019150509250505060006040518083038185876185025a03f1925050505060006001029050610f06565b600036436040518084848082843782019150508281526020019350505050604051809103902090508050610cd381610f0e565b158015610d3357506000610109600050600083815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15610f045784610109600050600083815260200190815260200160002060005060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff0219169083021790555083610109600050600083815260200190815260200160002060005060010160005081905550828261010960005060008481526020019081526020016000206000506002016000509190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610e0857803560ff1916838001178555610e39565b82800160010185558215610e39579182015b82811115610e38578235826000505591602001919060010190610e1a565b5b509050610e649190610e46565b80821115610e605760008181506000905550600101610e46565b5090565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32813386888787604051808781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b5b5b949350505050565b600081610f1a816112db565b156112d4576000610109600050600085815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156112d357610109600050600084815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16610109600050600085815260200190815260200160002060005060010160005054610109600050600086815260200190815260200160002060005060020160005060405180828054600181600116156101000203166002900480156110765780601f1061104b57610100808354040283529160200191611076565b820191906000526020600020905b81548152906001019060200180831161105957829003601f168201915b505091505060006040518083038185876185025a03f192505050507fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a3384610109600050600087815260200190815260200160002060005060010160005054610109600050600088815260200190815260200160002060005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166101096000506000898152602001908152602001600020600050600201600050604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156112005780601f106111d557610100808354040283529160200191611200565b820191906000526020600020905b8154815290600101906020018083116111e357829003601f168201915b5050965050505050505060405180910390a1610109600050600084815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000506000905560028201600050805460018160011615610100020316600290046000825580601f1061128957506112c6565b601f0160209004906000526020600020908101906112c591906112a7565b808211156112c157600081815060009055506001016112a7565b5090565b5b50505060019150506112d6565b5b505b919050565b600060006000600061010260005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050549250600083141561132457611535565b610103600050600086815260200190815260200160002060005091506000826000016000505414156113fd57600060005054826000016000508190555060008260010160005081905550610104600050805480919060010190908154818355818115116113c3578183600052602060002091820191016113c291906113a4565b808211156113be57600081815060009055506001016113a4565b5090565b5b5050508260020160005081905550846101046000508360020160005054815481101561000257906000526020600020900160005b50819055505b8260020a90506000818360010160005054161415611534577fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda3386604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a16001826000016000505411151561150757610104600050610103600050600087815260200190815260200160002060005060020160005054815481101561000257906000526020600020900160005b50600090556101036000506000868152602001908152602001600020600060008201600050600090556001820160005060009055600282016000506000905550506001935061153556611533565b816000016000818150548092919060019003919050555080826001016000828282505417925050819055505b5b5b505050919050565b60006000600190505b6001600050548110156116d2575b60016000505481108015611580575060006002600050826101008110156100025790900160005b505414155b15611592578080600101915050611554565b5b60016001600050541180156115c45750600060026000506001600050546101008110156100025790900160005b5054145b156115e357600160008181505480929190600190039190505550611593565b600160005054811080156116145750600060026000506001600050546101008110156100025790900160005b505414155b8015611637575060006002600050826101008110156100025790900160005b5054145b156116cd5760026000506001600050546101008110156100025790900160005b50546002600050826101008110156100025790900160005b50819055508061010260005060006002600050846101008110156100025790900160005b5054815260200190815260200160002060005081905550600060026000506001600050546101008110156100025790900160005b50819055505b611546565b5b5090565b60006116e2336109a5565b1561177157610107600050546116f6611980565b111561171b57600061010660005081905550611710611980565b610107600050819055505b610106600050548261010660005054011015801561174757506101056000505482610106600050540111155b15611768578161010660008282825054019250508190555060019050611772565b60009050611772565b5b919050565b60006000610104600050805490509150600090505b8181101561187857610109600050600061010460005083815481101561000257906000526020600020900160005b5054815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000506000905560028201600050805460018160011615610100020316600290046000825580601f1061182a5750611867565b601f0160209004906000526020600020908101906118669190611848565b808211156118625760008181506000905550600101611848565b5090565b5b5050505b806001019050805061178c565b611880611885565b5b5050565b60006000610104600050805490509150600090505b8181101561193857600060010261010460005082815481101561000257906000526020600020900160005b505414151561192a57610103600050600061010460005083815481101561000257906000526020600020900160005b50548152602001908152602001600020600060008201600050600090556001820160005060009055600282016000506000905550505b5b806001019050805061189a565b61010460005080546000825590600052602060002090810190611979919061195b565b80821115611975576000818150600090555060010161195b565b5090565b5b505b5050565b6000620151804204905061198f565b9056"--hexstring2 :: EvmHexString-hexstring2 =- EvmHexString- "6060604052361560275760e060020a600035046341c0e1b58114606e578063e5225381146096575b60d56000341115606c57346060908152605890600160a060020a033316907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1590602090a35b565b60d5600054600160a060020a0390811633919091161415606c57600054600160a060020a0316ff5b60d5600054600160a060020a0390811633919091161415606c5760008054600160a060020a039081169190301631606082818181858883f15050505050565b00"---- http://solidity.readthedocs.io/en/develop/solidity-by-example.html-voteHexstring :: EvmHexString-voteHexstring =- EvmHexString- "6060604052341561000c57fe5b604051610abd380380610abd833981016040528080518201919050505b600033600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160016000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550600090505b815181101561016b57600280548060010182816100f89190610173565b916000526020600020906002020160005b604060405190810160405280868681518110151561012357fe5b906020019060200201516000191681526020016000815250909190915060008201518160000190600019169055602082015181600101555050505b80806001019150506100db565b5b50506101d5565b8154818355818115116101a05760020281600202836000526020600020918201910161019f91906101a5565b5b505050565b6101d291905b808211156101ce57600060008201600090556001820160009055506002016101ab565b5090565b90565b6108d9806101e46000396000f3006060604052361561008c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630121b93f1461008e578063013cf08b146100ae5780632e4176cf146100f15780635c19a95c14610143578063609ff1bd146101795780639e7b8d611461019f578063a3ec138d146101d5578063e2ba53f014610264575bfe5b341561009657fe5b6100ac6004808035906020019091905050610292565b005b34156100b657fe5b6100cc6004808035906020019091905050610352565b6040518083600019166000191681526020018281526020019250505060405180910390f35b34156100f957fe5b610101610386565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561014b57fe5b610177600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506103ac565b005b341561018157fe5b610189610696565b6040518082815260200191505060405180910390f35b34156101a757fe5b6101d3600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061071d565b005b34156101dd57fe5b610209600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061081c565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b341561026c57fe5b610274610879565b60405180826000191660001916815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156102f157610000565b60018160010160006101000a81548160ff021916908315150217905550818160020181905550806000015460028381548110151561032b57fe5b906000526020600020906002020160005b50600101600082825401925050819055505b5050565b60028181548110151561036157fe5b906000526020600020906002020160005b915090508060000154908060010154905082565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091508160010160009054906101000a900460ff161561040d57610000565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561044657610000565b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561058257600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1692503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561057d57610000565b610447565b60018260010160006101000a81548160ff021916908315150217905550828260010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156106795781600001546002826002015481548110151561065257fe5b906000526020600020906002020160005b5060010160008282540192505081905550610690565b816000015481600001600082825401925050819055505b5b505050565b60006000600060009150600090505b60028054905081101561071757816002828154811015156106c257fe5b906000526020600020906002020160005b50600101541115610709576002818154811015156106ed57fe5b906000526020600020906002020160005b506001015491508092505b5b80806001019150506106a5565b5b505090565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415806107c65750600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff165b156107d057610000565b6001600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055505b50565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610885610696565b81548110151561089157fe5b906000526020600020906002020160005b506000015490505b905600a165627a7a7230582083216429ab08775d8e6d7b7643b8ab38785e52186a5dca7d37aefaf2103eabcb0029"