@@ -7,23 +7,24 @@ import Control.Concurrent (forkIO)
77import Control.Monad (forever , unless )
88import Control.Concurrent.STM
99import Data.IORef (readIORef , modifyIORef' , newIORef , IORef , atomicModifyIORef' )
10- import Data.List (find , isPrefixOf , sort , intercalate )
10+ import Data.List (find , isPrefixOf , isSuffixOf , sort , intercalate )
1111import qualified Data.Maybe
1212import qualified Data.Set as Set
13+ import qualified Data.Vector as Vector
1314import Data.Text (Text , pack , unpack )
1415import qualified Data.Text as T
1516import Data.Time (UTCTime , getCurrentTime , diffUTCTime )
1617import Text.Printf (printf )
1718import qualified Data.Map as Map
1819import Text.Read (readMaybe )
1920import System.Directory (getCurrentDirectory )
20- import Data.Char (isSpace )
21+ import Data.Char (isSpace , toLower )
2122
2223import MCP.Server
2324import EVM.Dapp (DappInfo (.. ))
2425import EVM.Solidity (SolcContract (.. ), Method (.. ))
2526import EVM.Types (Addr )
26- import EVM.ABI (AbiValue (.. ))
27+ import EVM.ABI (AbiValue (.. ), AbiType ( .. ), abiValueType )
2728import Echidna.Types.Test (EchidnaTest (.. ), didFail , isOptimizationTest )
2829import Echidna.Types.Tx (Tx (.. ), TxCall (.. ))
2930import Echidna.Types.Coverage (CoverageFileType (.. ), mergeCoverageMaps , coverageStats )
@@ -105,12 +106,49 @@ splitOn c s = case break (== c) s of
105106 [] -> []
106107 (_: r) -> splitOn c r
107108
109+ splitArgs :: String -> [String ]
110+ splitArgs s = go s 0 " "
111+ where
112+ go :: String -> Int -> String -> [String ]
113+ go [] _ current = [reverse current]
114+ go (c: cs) level current
115+ | c == ' [' = go cs (level + 1 ) (c: current)
116+ | c == ' ]' = go cs (level - 1 ) (c: current)
117+ | c == ' ,' && level == 0 = reverse current : go cs level " "
118+ | otherwise = go cs level (c: current)
119+
120+ parsePrimitive :: String -> Maybe AbiValue
121+ parsePrimitive s =
122+ let s' = trim s
123+ lowerS = map toLower s'
124+ in if lowerS == " true"
125+ then Just (AbiBool True )
126+ else if lowerS == " false"
127+ then Just (AbiBool False )
128+ else if " 0x" `isPrefixOf` s'
129+ then AbiAddress . fromIntegral <$> (readMaybe s' :: Maybe Integer )
130+ else AbiUInt 256 . fromIntegral <$> (readMaybe s' :: Maybe Integer )
131+
132+ parseArray :: String -> Maybe AbiValue
133+ parseArray s = do
134+ let content = trim (drop 1 (take (length s - 1 ) s))
135+ let parts = if null content then [] else splitOn ' ,' content
136+ vals <- mapM parsePrimitive parts
137+ let vec = Vector. fromList vals
138+ if Vector. null vec
139+ then return $ AbiArrayDynamic (AbiUIntType 256 ) vec
140+ else do
141+ let t = abiValueType (Vector. head vec)
142+ if all (\ v -> abiValueType v == t) vals
143+ then return $ AbiArrayDynamic t vec
144+ else Nothing
145+
108146parseArg :: String -> Maybe AbiValue
109147parseArg s =
110148 let s' = trim s
111- in if " 0x " `isPrefixOf` s'
112- then AbiAddress . fromIntegral <$> (readMaybe s' :: Maybe Integer )
113- else AbiUInt 256 . fromIntegral <$> (readMaybe s' :: Maybe Integer )
149+ in if " [ " `isPrefixOf` s' && " ] " `isSuffixOf ` s'
150+ then parseArray s'
151+ else parsePrimitive s'
114152
115153parseFuzzArg :: String -> Maybe (Maybe AbiValue )
116154parseFuzzArg s =
@@ -124,7 +162,7 @@ parseFuzzCall s = do
124162 let (fname, rest) = break (== ' (' ) s
125163 if null rest then Nothing else do
126164 let argsS = take (length rest - 2 ) (drop 1 rest) -- remove parens
127- let argParts = if all isSpace argsS then [] else splitOn ' , ' argsS
165+ let argParts = if all isSpace argsS then [] else splitArgs argsS
128166 args <- mapM parseFuzzArg argParts
129167 return (pack fname, args)
130168
@@ -136,7 +174,7 @@ parseCall s = do
136174 let (fname, rest) = break (== ' (' ) s
137175 if null rest then Nothing else do
138176 let argsS = take (length rest - 2 ) (drop 1 rest) -- remove parens
139- let argParts = if all isSpace argsS then [] else splitOn ' , ' argsS
177+ let argParts = if all isSpace argsS then [] else splitArgs argsS
140178 args <- mapM parseArg argParts
141179 return (fname, args)
142180
0 commit comments