Allow disabling Slither (#1327)

This allows explicitly disabling Slither with a new `--disable-slither` command-line flag
or `disableSlither` configuration option. A blinking, red warning will be shown in the UI
when Slither is disabled or otherwise failed, to disuade people from fuzzing without it.

Closes #1318
master
Emilio López 1 day ago committed by GitHub
parent 0db6f4c631
commit 740e950e76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      lib/Echidna/Config.hs
  2. 14
      lib/Echidna/SourceAnalysis/Slither.hs
  3. 1
      lib/Echidna/Types/Solidity.hs
  4. 2
      lib/Echidna/UI.hs
  5. 16
      lib/Echidna/UI/Widgets.hs
  6. 6
      src/Main.hs
  7. 2
      tests/solidity/basic/default.yaml

@ -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" ..!= []

@ -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 explicitly disabled. Echidna uses Slither (https://github.com/crytic/slither)"
<> " 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)"
@ -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
isEmptySlitherInfo Nothing = True
isEmptySlitherInfo _ = False

@ -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.

@ -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
@ -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

@ -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
@ -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)
@ -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")
@ -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)
@ -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

@ -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
@ -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.")
@ -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

@ -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

Loading…
Cancel
Save