Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow disabling Slither #1327

Merged
merged 3 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/Echidna/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ instance FromJSON EConfigWithUsage where
<*> v ..:? "balanceContract" ..!= 0
<*> v ..:? "codeSize" ..!= 0xffffffff
<*> v ..:? "prefix" ..!= "echidna_"
<*> v ..:? "disableSlither" ..!= False
<*> v ..:? "cryticArgs" ..!= []
<*> v ..:? "solcArgs" ..!= ""
<*> v ..:? "solcLibs" ..!= []
Expand Down
14 changes: 12 additions & 2 deletions lib/Echidna/SourceAnalysis/Slither.hs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,13 @@ instance FromJSON SlitherInfo where

-- Slither processing
runSlither :: FilePath -> SolConf -> IO SlitherInfo
runSlither fp solConf = do
findExecutable "slither" >>= \case
runSlither fp solConf = if solConf.disableSlither
then do
hPutStrLn stderr $
"WARNING: slither was expliticly disabled. Echidna uses Slither (https://github.com/crytic/slither)"
elopez marked this conversation as resolved.
Show resolved Hide resolved
<> " to perform source analysis, which makes fuzzing more effective. You should enable it."
pure emptySlitherInfo
else findExecutable "slither" >>= \case
Nothing -> do
hPutStrLn stderr $
"WARNING: slither not found. Echidna uses Slither (https://github.com/crytic/slither)"
Expand Down Expand Up @@ -177,3 +182,8 @@ runSlither fp solConf = do

emptySlitherInfo :: SlitherInfo
emptySlitherInfo = SlitherInfo mempty mempty mempty mempty mempty [] [] []

isEmptySlitherInfo :: Maybe SlitherInfo -> Bool
isEmptySlitherInfo (Just (SlitherInfo _ _ _ _ _ [] [] [])) = True
elopez marked this conversation as resolved.
Show resolved Hide resolved
isEmptySlitherInfo Nothing = True
isEmptySlitherInfo _ = False
1 change: 1 addition & 0 deletions lib/Echidna/Types/Solidity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ data SolConf = SolConf
, balanceContract :: Integer -- ^ Initial balance of contract to test
, codeSize :: Integer -- ^ Max code size for deployed contratcs (default 0xffffffff)
, prefix :: Text -- ^ Function name prefix used to denote tests
, disableSlither :: Bool -- ^ Whether or not to skip running Slither
, cryticArgs :: [String] -- ^ Args to pass to crytic
, solcArgs :: String -- ^ Args to pass to @solc@
, solcLibs :: [String] -- ^ List of libraries to load, in order.
Expand Down
2 changes: 2 additions & 0 deletions lib/Echidna/UI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Echidna.Campaign (runWorker, spawnListener)
import Echidna.Output.Corpus (saveCorpusEvent)
import Echidna.Output.JSON qualified
import Echidna.Server (runSSEServer)
import Echidna.SourceAnalysis.Slither (isEmptySlitherInfo)
import Echidna.Types.Campaign
import Echidna.Types.Config
import Echidna.Types.Corpus qualified as Corpus
Expand Down Expand Up @@ -126,6 +127,7 @@ ui vm dict initialCorpus cliSelectedContract = do
, timeStarted = now
, timeStopped = Nothing
, now = now
, slitherSucceeded = not $ isEmptySlitherInfo env.slitherInfo
, fetchedContracts = mempty
, fetchedSlots = mempty
, fetchedDialog = B.dialog (Just $ str " Fetched contracts/slots ") Nothing 80
Expand Down
16 changes: 15 additions & 1 deletion lib/Echidna/UI/Widgets.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ data UIState = UIState
, timeStarted :: LocalTime
, timeStopped :: Maybe LocalTime
, now :: LocalTime
, slitherSucceeded :: Bool
, fetchedContracts :: Map Addr (Maybe Contract)
, fetchedSlots :: Map Addr (Map W256 (Maybe W256))
, fetchedDialog :: B.Dialog () Name
Expand All @@ -65,7 +66,8 @@ data UIStateStatus = Uninitialized | Running

attrs :: A.AttrMap
attrs = A.attrMap (V.white `on` V.black)
[ (attrName "failure", fg V.brightRed)
[ (attrName "alert", fg V.brightRed `V.withStyle` V.blink `V.withStyle` V.bold)
, (attrName "failure", fg V.brightRed)
, (attrName "maximum", fg V.brightBlue)
, (attrName "bold", fg V.white `V.withStyle` V.bold)
, (attrName "tx", fg V.brightWhite)
Expand All @@ -79,6 +81,9 @@ attrs = A.attrMap (V.white `on` V.black)
bold :: Widget n -> Widget n
bold = withAttr (attrName "bold")

alert :: Widget n -> Widget n
alert = withAttr (attrName "alert")

failure :: Widget n -> Widget n
failure = withAttr (attrName "failure")

Expand Down Expand Up @@ -184,6 +189,8 @@ summaryWidget env uiState =
str ("Corpus size: " <> show uiState.corpusSize <> " seqs")
<=>
str ("New coverage: " <> timeElapsed uiState uiState.lastNewCov <> " ago") <+> fill ' '
<=>
slitherWidget uiState.slitherSucceeded
rightSide =
padLeft (Pad 1)
(rpcInfoWidget uiState.fetchedContracts uiState.fetchedSlots env.chainId)
Expand Down Expand Up @@ -217,6 +224,13 @@ rpcInfoWidget contracts slots chainId =
let successful = filter isJust fetches
in outOf (length successful) (length fetches)

slitherWidget
:: Bool
-> Widget Name
slitherWidget slitherSucceeded = if slitherSucceeded
then success (str "Slither succeeded")
else alert (str "No Slither in use!")

outOf :: Int -> Int -> Widget n
outOf n m =
let style = if n == m then success else failure
Expand Down
6 changes: 5 additions & 1 deletion src/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ data Options = Options
, cliDeployer :: Maybe Addr
, cliSender :: [Addr]
, cliSeed :: Maybe Int
, cliDisableSlither :: Bool
, cliCryticArgs :: Maybe String
, cliSolcArgs :: Maybe String
, cliSymExec :: Maybe Bool
Expand Down Expand Up @@ -210,6 +211,8 @@ options = Options
<*> optional (option auto $ long "seed"
<> metavar "SEED"
<> help "Run with a specific seed.")
<*> switch (long "disable-slither"
<> help "Disable running Slither.")
<*> optional (option str $ long "crytic-args"
<> metavar "ARGS"
<> help "Additional arguments to use in crytic-compile for the compilation of the contract to test.")
Expand Down Expand Up @@ -276,7 +279,8 @@ overrideConfig config Options{..} = do
}

overrideSolConf solConf = solConf
{ solcArgs = fromMaybe solConf.solcArgs cliSolcArgs
{ disableSlither = cliDisableSlither || solConf.disableSlither
, solcArgs = fromMaybe solConf.solcArgs cliSolcArgs
, cryticArgs = maybe solConf.cryticArgs words cliCryticArgs
, sender = if null cliSender then solConf.sender else Set.fromList cliSender
, deployer = fromMaybe solConf.deployer cliDeployer
Expand Down
2 changes: 2 additions & 0 deletions tests/solidity/basic/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ balanceAddr: 0xffffffff
balanceContract: 0
#codeSize max code size for deployed contratcs (default 0xffffffff)
codeSize: 0xffffffff
#whether or not to disable running slither (default false, uses slither)
disableSlither: false
#solcArgs allows special args to solc
solcArgs: ""
#solcLibs is solc libraries
Expand Down
Loading