Skip to content

Commit

Permalink
Cleanup imports and extensions (#828)
Browse files Browse the repository at this point in the history
* Cleanup imports and extensions

* Update hlint action

* Fix hlint suggestions
  • Loading branch information
arcz authored Nov 10, 2022
1 parent aedd24b commit ce64385
Show file tree
Hide file tree
Showing 35 changed files with 270 additions and 358 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/hlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ jobs:
hlint:
runs-on: ubuntu-latest
steps:
- name: Get Packages
uses: mstksg/get-package@v1
with:
apt-get: hlint

- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Install Nix
uses: cachix/install-nix-action@v17
with:
nix_path: nixpkgs=channel:nixos-unstable

- name: HLint
run: |
hlint lib src
nix-shell -p hlint --command 'hlint lib src'
7 changes: 2 additions & 5 deletions lib/Echidna.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
{-# LANGUAGE FlexibleContexts #-}

module Echidna where

import Control.Lens (view, (^.), to)
import Data.Has (Has(..))
import Control.Monad.Catch (MonadCatch(..), MonadThrow(..))
import Control.Monad.Reader (MonadReader, MonadIO, liftIO)
import Control.Monad.Random (MonadRandom)
import Data.Map.Strict (keys)
import Data.HashMap.Strict (toList)
import Data.Map.Strict (keys)
import Data.List (nub, find)
import Data.List.NonEmpty qualified as NE

import EVM (env, contracts, VM)
import EVM.ABI (AbiValue(AbiAddress))
Expand All @@ -29,8 +28,6 @@ import Echidna.Processor
import Echidna.Output.Corpus
import Echidna.RPC (loadEtheno, extractFromEtheno)

import qualified Data.List.NonEmpty as NE

-- | This function is used to prepare, process, compile and initialize smart contracts for testing.
-- It takes:
-- * A config record
Expand Down
24 changes: 9 additions & 15 deletions lib/Echidna/ABI.hs
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}

module Echidna.ABI where

import Control.Lens
import Control.Monad (join, liftM2, liftM3, foldM, replicateM)
import Control.Monad.Random.Strict (MonadRandom, getRandom, getRandoms, getRandomR, uniformMay)
import Control.Monad.Random.Strict qualified as R
import Data.Binary.Put (runPut, putWord32be)
import Data.Bool (bool)
import Data.ByteString.Lazy as BSLazy (toStrict)
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.DoubleWord (Int256, Word256)
import Data.Foldable (toList)
import Data.Hashable (Hashable(..))
import Data.HashMap.Strict (HashMap)
import Data.HashMap.Strict qualified as M
import Data.HashSet (HashSet, fromList, union)
import Data.HashSet qualified as H
import Data.List (intercalate)
import Data.List.NonEmpty qualified as NE
import Data.Maybe (fromMaybe, catMaybes)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.Encoding (encodeUtf8)
import Data.Text.Encoding qualified as TE
import Data.Vector (Vector)
import Data.Vector qualified as V
import Data.Vector.Instances ()
import Data.Word8 (Word8)
import Data.DoubleWord (Int256, Word256)
import Numeric (showHex)

import EVM.ABI hiding (genAbiValue)
import EVM.Types (Addr, abiKeccak)

import qualified Control.Monad.Random.Strict as R
import qualified Data.ByteString as BS
import qualified Data.HashMap.Strict as M
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import qualified Data.Vector as V
import qualified Data.HashSet as H

import Echidna.Mutator.Array (mutateLL, replaceAt)
import Echidna.Types.Random
import Echidna.Types.Signature
Expand Down
25 changes: 9 additions & 16 deletions lib/Echidna/Campaign.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}

module Echidna.Campaign where
Expand All @@ -22,20 +15,20 @@ import Control.Monad.Trans (lift)
import Control.Monad.Trans.Random.Strict (liftCatch)
import Data.Binary.Get (runGetOrFail)
import Data.Bool (bool)
import Data.Has (Has(..))
import Data.HashMap.Strict qualified as H
import Data.HashSet qualified as S
import Data.Map (Map, unionWith, (\\), elems, keys, lookup, insert, mapWithKey)
import Data.Maybe (fromMaybe, isJust, mapMaybe)
import Data.Ord (comparing)
import Data.Has (Has(..))
import Data.Set qualified as DS
import Data.Text (Text)
import System.Random (mkStdGen)

import EVM
import EVM.Dapp (DappInfo)
import EVM.ABI (getAbi, AbiType(AbiAddressType), AbiValue(AbiAddress))
import EVM.Types (Addr, Buffer(..))
import System.Random (mkStdGen)

import qualified Data.HashMap.Strict as H
import qualified Data.HashSet as S
import qualified Data.Set as DS

import Echidna.ABI
import Echidna.Exec
Expand Down Expand Up @@ -97,8 +90,8 @@ updateTest w vm (Just (vm', xs)) test = do
Open i | i >= tl -> case test ^. testType of
OptimizationTest _ _ -> pure $ test { _testState = Large (-1) }
_ -> pure $ test { _testState = Passed }
Open i -> do r <- evalStateT (checkETest test) vm'
pure $ updateOpenTest test xs i r
Open i -> do r <- evalStateT (checkETest test) vm'
pure $ updateOpenTest test xs i r
_ -> updateTest w vm Nothing test

updateTest _ vm Nothing test = do
Expand All @@ -111,7 +104,7 @@ updateTest _ vm Nothing test = do
Large i | i >= sl -> pure $ test { _testState = Solved, _testReproducer = x }
Large i -> if length x > 1 || any canShrinkTx x
then do (txs, val, evs, r) <- evalStateT (shrinkSeq (checkETest test) (v, es, res) x) vm
pure $ test { _testState = Large (i + 1), _testReproducer = txs, _testEvents = evs, _testResult = r, _testValue = val}
pure $ test { _testState = Large (i + 1), _testReproducer = txs, _testEvents = evs, _testResult = r, _testValue = val}
else pure $ test { _testState = Solved, _testReproducer = x}
_ -> pure test

Expand Down
23 changes: 9 additions & 14 deletions lib/Echidna/Config.hs
Original file line number Diff line number Diff line change
@@ -1,38 +1,33 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Echidna.Config where

import Control.Lens
import Control.Monad.Catch (MonadThrow)
import Control.Monad.Fail qualified as M (MonadFail(..))
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Reader (Reader, ReaderT(..), runReader)
import Control.Monad.State (StateT(..), runStateT)
import Control.Monad.Trans (lift)
import Data.Bool (bool)
import Data.Aeson
import Data.Bool (bool)
import Data.ByteString qualified as BS
import Data.List.NonEmpty qualified as NE
import Data.Has (Has(..))
import Data.HashMap.Strict (keys)
import Data.HashSet (fromList, insert, difference)
import Data.Maybe (fromMaybe)
import Data.Text (isPrefixOf)
import Data.Yaml qualified as Y

import EVM (result)
import EVM.Types (w256)

import qualified Control.Monad.Fail as M (MonadFail(..))
import qualified Data.ByteString as BS
import qualified Data.List.NonEmpty as NE
import qualified Data.Yaml as Y

import Echidna.Test
import Echidna.Types.Campaign
import Echidna.Types.Campaign
import Echidna.Mutator.Corpus (defaultMutationConsts)
import Echidna.Types.Config (EConfigWithUsage(..), EConfig(..))
import Echidna.Types.Solidity
import Echidna.Types.Tx (TxConf(TxConf), maxGasPerBlock, defaultTimeDelay, defaultBlockDelay)
import Echidna.Types.Test (TestConf(..))
import Echidna.Types.Tx (TxConf(TxConf), maxGasPerBlock, defaultTimeDelay, defaultBlockDelay)
import Echidna.Types.Test (TestConf(..))
import Echidna.UI
import Echidna.UI.Report

Expand Down
26 changes: 13 additions & 13 deletions lib/Echidna/Events.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

module Echidna.Events where

import Data.ByteString qualified as BS
import Data.ByteString.Lazy (fromStrict)
import Data.Tree (flatten)
import Data.Tree (flatten)
import Data.Tree.Zipper (fromForest, TreePos, Empty)
import Data.Text (pack, Text)
import Data.Maybe (listToMaybe)
import Data.Text (pack, Text)
import Data.Map qualified as M
import Data.Maybe (listToMaybe)
import Control.Lens

import EVM
import EVM.ABI (Event(..), Indexed(..), decodeAbiValue, AbiType(AbiUIntType))
import EVM.ABI (Event(..), Indexed(..), decodeAbiValue, AbiType(AbiUIntType))
import EVM.Concrete (wordValue)
import EVM.Dapp
import EVM.Format (showValues, showError, contractNamePart)
import EVM.Types (W256, maybeLitWord)
import EVM.Format (showValues, showError, contractNamePart)
import EVM.Types (W256, maybeLitWord)
import EVM.Solidity (contractName)

import qualified Data.Map as M
import qualified Data.ByteString as BS

type EventMap = M.Map W256 Event
type Events = [Text]

Expand Down Expand Up @@ -58,18 +58,18 @@ extractEvents dappInfo' vm =
case e of
Revert out -> ["merror " <> "Revert " <> showError out <> maybe mempty (\ x -> pack " from: " <> x) maybeContractName]
_ -> ["merror " <> pack (show e)]

_ -> []
in decodeRevert vm ++ concat (concatMap flatten $ fmap (fmap showTrace) forest)


decodeRevert :: VM -> Events
decodeRevert vm =
decodeRevert vm =
case vm ^. result of
Just (VMFailure (Revert bs)) -> decodeRevertMsg bs
_ -> []
_ -> []

decodeRevertMsg :: BS.ByteString -> Events
decodeRevertMsg :: BS.ByteString -> Events
decodeRevertMsg bs = case BS.splitAt 4 bs of
--"\x08\xc3\x79\xa0" -> Just $ "Error(" ++ (show $ decodeAbiValue AbiStringType (fromStrict $ BS.drop 4 bs)) ++ ")"
("\x4e\x48\x7b\x71",d) -> ["Panic(" <> (pack . show $ decodeAbiValue (AbiUIntType 256) (fromStrict d)) <> ")"]
Expand Down
17 changes: 6 additions & 11 deletions lib/Echidna/Exec.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}

module Echidna.Exec where
Expand All @@ -11,22 +7,21 @@ import Control.Lens
import Control.Monad.Catch (Exception, MonadThrow(..))
import Control.Monad.State.Strict (MonadState, execState, execState)
import Data.Has (Has(..))
import Data.Map qualified as M
import Data.Maybe (fromMaybe)
import Data.Set qualified as S

import EVM
import EVM.Exec (exec, vmForEthrunCreation)
import EVM.Types (Buffer(..), Word)
import EVM.Symbolic (litWord)

import qualified Data.Map as M
import qualified Data.Set as S

import Echidna.Events (emptyEvents)
import Echidna.Transaction
import Echidna.Types.Buffer (viewBuffer)
import Echidna.Types.Coverage (CoverageMap)
import Echidna.Types.Tx (TxCall(..), Tx, TxResult(..), call, dst, initialTimestamp, initialBlockNumber)

import Echidna.Types.Signature (BytecodeMemo, lookupBytecodeMetadata)
import Echidna.Events (emptyEvents)
import Echidna.Types.Tx (TxCall(..), Tx, TxResult(..), call, dst, initialTimestamp, initialBlockNumber)

-- | Broad categories of execution failures: reversions, illegal operations, and ???.
data ErrorClass = RevertE | IllegalE | UnknownE
Expand Down Expand Up @@ -136,7 +131,7 @@ handleErrorsAndConstruction onErr vmResult' vmBeforeTx tx' = case (vmResult', tx
-- contract address, calldata, result and traces.
hasLens . result ?= vmResult'
hasLens . state . calldata .= calldataBeforeVMReset
hasLens . state . callvalue .= callvalueBeforeVMReset
hasLens . state . callvalue .= callvalueBeforeVMReset
hasLens . traces .= tracesBeforeVMReset
hasLens . state . codeContract .= codeContractBeforeVMReset
(VMFailure x, _) -> onErr x
Expand Down
29 changes: 13 additions & 16 deletions lib/Echidna/Fetch.hs
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
{-# LANGUAGE FlexibleContexts #-}

module Echidna.Fetch where

import Control.Lens
import Control.Monad.Reader (MonadReader)
import Control.Monad.Catch (MonadThrow(..), throwM)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Reader (MonadReader)
import Control.Monad.State.Strict (execStateT)
import Control.Monad.Catch (MonadThrow(..), throwM)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Either (fromRight)
import Data.Has (Has(..))
import Data.ByteString (ByteString, pack, append)
import Data.ByteString.Base16 qualified as BS16 (decode)
import Data.Either (fromRight)
import Data.Has (Has(..))
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8)

import EVM
import EVM.Solidity
import EVM.Types (Addr)
import EVM.Types (Addr)

import Echidna.Types.Solidity (SolConf(..), SolException(..))
import Echidna.Types.Tx (createTx, unlimitedGasPerBlock)
import Echidna.Exec (execTx)

import Data.ByteString (ByteString, pack, append)
import qualified Data.ByteString.Base16 as BS16 (decode)
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8)
import Echidna.Types.Solidity (SolConf(..), SolException(..))
import Echidna.Types.Tx (createTx, unlimitedGasPerBlock)
import Echidna.Exec (execTx)

-- | Deploy a list of solidity contracts in certain addresses
deployBytecodes' :: (MonadIO m, MonadThrow m, MonadReader x m, Has SolConf x)
Expand Down
5 changes: 1 addition & 4 deletions lib/Echidna/Mutator/Array.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
{-# LANGUAGE FlexibleContexts #-}

module Echidna.Mutator.Array where

import Control.Monad.Random.Strict (fromList, MonadRandom, getRandomR)

import qualified Data.ListLike as LL
import Data.ListLike qualified as LL

-- | A list of mutators to randomly select to perform a mutation of list-like values
listMutators :: (LL.ListLike f i, MonadRandom m) => m (f -> m f)
Expand Down
13 changes: 5 additions & 8 deletions lib/Echidna/Mutator/Corpus.hs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
{-# LANGUAGE FlexibleContexts #-}

module Echidna.Mutator.Corpus where

import Control.Monad.Random.Strict (MonadRandom, getRandomR, weighted)
import Control.Monad.State.Strict (MonadState(..))
import Control.Monad.Random.Strict (MonadRandom, getRandomR, weighted)
import Data.Has (Has(..))
import Data.Set qualified as DS

import qualified Data.Set as DS

import Echidna.Types.Tx (Tx)
import Echidna.Types.Corpus
import Echidna.Transaction (mutateTx, shrinkTx)
import Echidna.ABI (GenDict)
import Echidna.Mutator.Array
import Echidna.Transaction (mutateTx, shrinkTx)
import Echidna.Types.Tx (Tx)
import Echidna.Types.Corpus

type MutationConsts a = (a, a, a, a)
defaultMutationConsts :: Num a => MutationConsts a
Expand Down
Loading

0 comments on commit ce64385

Please sign in to comment.