@@ -4,6 +4,7 @@ module Echidna.Output.Source where
44
55import Prelude hiding (writeFile )
66
7+ import Control.Monad (unless )
78import Data.ByteString qualified as BS
89import Data.Foldable
910import Data.IORef (readIORef )
@@ -31,6 +32,7 @@ import Echidna.Types.Campaign (CampaignConf(..))
3132import Echidna.Types.Config (Env (.. ), EConfig (.. ))
3233import Echidna.Types.Coverage (OpIx , unpackTxResults , CoverageMap , CoverageFileType (.. ))
3334import Echidna.Types.Tx (TxResult (.. ))
35+ import Echidna.SourceAnalysis.Slither (AssertMappingByContract , AssertLocation (.. ))
3436
3537saveCoverages
3638 :: Env
@@ -188,3 +190,26 @@ buildRuntimeLinesMap sc contracts =
188190 where
189191 srcMaps = concatMap
190192 (\ c -> toList $ c. runtimeSrcmap <> c. creationSrcmap) contracts
193+
194+ checkAssertionsCoverage
195+ :: SourceCache
196+ -> [SolcContract ]
197+ -> CoverageMap
198+ -> AssertMappingByContract
199+ -> IO ()
200+ checkAssertionsCoverage sc cs covMap assertMap = do
201+ covLines <- srcMapCov sc covMap cs
202+ let asserts = concat $ concatMap Map. elems $ Map. elems assertMap
203+ mapM_ (checkAssertionReached covLines) asserts
204+
205+ checkAssertionReached :: Map String (Map Int [TxResult ]) -> AssertLocation -> IO ()
206+ checkAssertionReached covLines assert =
207+ maybe
208+ warnAssertNotReached checkCoverage
209+ (Map. lookup assert. filenameAbsolute covLines)
210+ where
211+ checkCoverage coverage = let lineNumbers = Map. keys coverage in
212+ unless ((head assert. assertLines) `elem` lineNumbers) warnAssertNotReached
213+ warnAssertNotReached =
214+ putStrLn $ " WARNING: assertion at file: " ++ assert. filenameRelative
215+ ++ " starting at line: " ++ show (head assert. assertLines) ++ " was never reached"
0 commit comments