diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 5f73d44b6..624a7e703 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -61,7 +61,7 @@ jobs:
           password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}
 
       - name: Docker Build and Push (Ubuntu & NVM variant)
-        uses: docker/build-push-action@v3
+        uses: docker/build-push-action@v4
         with:
           platforms: linux/amd64
           target: final-ubuntu
@@ -74,7 +74,7 @@ jobs:
           cache-to: type=gha,mode=max
 
       - name: Docker Build and Push (Distroless variant)
-        uses: docker/build-push-action@v3
+        uses: docker/build-push-action@v4
         if: ${{ env.WORKFLOW_BUILD_DISTROLESS == true }}
         with:
           platforms: linux/amd64
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f42c9559a..b6d7fd0ca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,6 @@
-## TODO
+## 2.1.0 (Unreleased)
+
+* Rename multi-abi mode to allContracts
 
 ## 2.0.5
 
@@ -7,26 +9,26 @@
 * Update hevm to 0.50 (#884, #894, #896, #897, #901)
 * Added saving and loading of reproducers for every test (#858)
 * Added events and revert reasons for any failure in the constructor (#871)
-* Fixed uninitialized sender addresses from etheno transactions (#823) 
-* Fixed crash when minimizing inputs during optimization tests (#837) 
+* Fixed uninitialized sender addresses from etheno transactions (#823)
+* Fixed crash when minimizing inputs during optimization tests (#837)
 * Refactored code and removed useless dependencies (#856, #857, #874, #878, #895, #903)
 
 ## 2.0.4
 
 * Added colored html for coverage output code (#816)
-* Fixed crash when parsing solc versions (#835) 
+* Fixed crash when parsing solc versions (#835)
 * Fixed long transactions and event lines in UI (#832)
-* Added Homebrew installation instructions (#848) 
+* Added Homebrew installation instructions (#848)
 * Moved all nix stuff to flake and use nix-bundle-exe for macOS release (#851)
-* Updated codebase to GHC 9.0.2 (#846) 
+* Updated codebase to GHC 9.0.2 (#846)
 * Refactored code and removed useless dependencies (#854, #853, #829, #827, #828)
 
 ## 2.0.3
 
 * Clean up Docker containers (#706)
 * Avoid resetting accounts if there is a deployed contract (#795)
-* Fixed decoding non-utf8 strings from slither printer (#799) 
-* Fixed generation and mutation of extreme signed integers (#791) 
+* Fixed decoding non-utf8 strings from slither printer (#799)
+* Fixed generation and mutation of extreme signed integers (#791)
 * Removed fallback from signature map when it is not defined (#772)
 
 ## 2.0.2
@@ -37,13 +39,13 @@
 * Fixed crash when the EVM execution triggers more than one query (#760)
 * Added support for detection and handling of ancient solc versions (#675)
 * Added explicit static flag and removed pthread one from ghc options (#768)
- 
+
 ## 2.0.1
 
 * Optimized stateless mutators (#747)
 * Expanded and improved command-line help (#741)
 * Added dapptest support: compatibility mode to run foundry and dapptool fuzz tests (#733, #745)
-* Generate more values closer to the maximum (#736) 
+* Generate more values closer to the maximum (#736)
 * Fix TERMINFO path for Nix release builds (#731)
 * Mitigate large memory consumption when replaying corpus (#725)
 * Fix --shrink-limit to change shrink limit instead of test limit (#728)
@@ -54,14 +56,14 @@
 
 * Refactored test internal data structures and code
 * Refactored unit test code and moved the related files to the `tests` directory
-* Added support to show events and custom errors when a property/assertion fails 
+* Added support to show events and custom errors when a property/assertion fails
 * Added support for catching assertion failure in Solidity 0.8.x
 * Added two new testing mode: optimization and overflow (only in Solidity 0.8.x)
 * Added optional checks for contract destruction
 * Added `testMode` option and removed related flags
 * Simplified contract deployer and property sender addresses to be easier to read
 * Updated hevm to 0.49.0
- 
+
 ## 1.7.3
 
 * Removed old compilation artifacts before starting a new fuzzing campaign (#697)
@@ -92,17 +94,17 @@
 * Refactor coverage types and added corpus size in UI (#627)
 * Fixed link to macOS binary in binaries.soliditylang.org (#629)
 * Fixed default.nix to use 1.7.0 as version (#623)
-* Refactored Test type (#622) 
+* Refactored Test type (#622)
 
 ## 1.7.0
 
-* Refactored and improved etheno support to be more useful (#615) 
+* Refactored and improved etheno support to be more useful (#615)
 * Coverage filenames are not overwritten (#620)
 * Refactored the mutator code (#618)
 * More corpus and array mutations implemented (#372)
 * Source coverage is printed after fuzzing campaign (#516)
 * Nix improvements and fixes (#603, #604, #608, #612)
-* Simplified slither information parsing (#543) 
+* Simplified slither information parsing (#543)
 * Enabled use of coverage by default (#605)
 * Run echidna tests in parallel (#571)
 
@@ -112,10 +114,10 @@
 * Use metadata to detect deployed contracts (#593)
 * Semver integration for improving testing with different solc versions (#594)
 * Added some performance improvement in property execution (#576)
-* Fixed wait bug when shrinking (#584) 
+* Fixed wait bug when shrinking (#584)
 * Added funwithnumber example from Sabre (#565)
 * Improved function filtering to be more precise (#570)
-* Small fixes in the macOS CI (#597), the README (#590) and Nix (#581) 
+* Small fixes in the macOS CI (#597), the README (#590) and Nix (#581)
 
 ## 1.6.0
 * Slither is now a required dependency.
@@ -134,7 +136,7 @@
 * Fix negative address bug (#552)
 * Various Github Actions improvements (#527, #554)
 * Allow to bypass EIP-170 and set up a custom max code size (#544)
- 
+
 ## 1.5.1
 
 * Fix timestamp and block delays having the initial timestamp/block added to them (#460, #469)
diff --git a/README.md b/README.md
index 55cc0f882..6ed47ce4e 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ Our tool signals each execution trace in the corpus with the following "line mar
 
 Echidna can test contracts compiled with different smart contract build systems, including [Truffle](https://truffleframework.com/) or [hardhat](https://hardhat.org/) using [crytic-compile](https://github.com/crytic/crytic-compile). To invoke echidna with the current compilation framework, use `echidna .`.
 
-On top of that, Echidna supports two modes of testing complex contracts. Firstly, one can [describe an initialization procedure with Truffle and Etheno](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/end-to-end-testing.md) and use that as the base state for Echidna. Secondly, echidna can call into any contract with a known ABI by passing in the corresponding solidity source in the CLI. Use `multi-abi: true` in your config to turn this on.
+On top of that, Echidna supports two modes of testing complex contracts. Firstly, one can [describe an initialization procedure with Truffle and Etheno](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/end-to-end-testing.md) and use that as the base state for Echidna. Secondly, Echidna can call into any contract with a known ABI by passing in the corresponding Solidity source in the CLI. Use `allContracts: true` in your config to turn this on.
 
 ### Crash course on Echidna
 
diff --git a/flake.lock b/flake.lock
index 82dd32a36..4165ccfaf 100644
--- a/flake.lock
+++ b/flake.lock
@@ -49,11 +49,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1676652184,
-        "narHash": "sha256-kV2mBquEaEuJyHwzO1dac5b/FFMwvqMrD7XmHS1Kwck=",
+        "lastModified": 1676994339,
+        "narHash": "sha256-Jnx9EhUtZVZjGe0weRc+OzYvNimq24Mi6JXUiaqW8wc=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "223092f727b251eecf5e884fbaee4a660caec8fd",
+        "rev": "4c5c82e9cdb35494ae243ffe42f156269904d457",
         "type": "github"
       },
       "original": {
diff --git a/lib/Echidna/ABI.hs b/lib/Echidna/ABI.hs
index d57f9b9ec..f22463d1f 100644
--- a/lib/Echidna/ABI.hs
+++ b/lib/Echidna/ABI.hs
@@ -1,10 +1,8 @@
 {-# LANGUAGE DeriveAnyClass #-}
 {-# LANGUAGE DerivingStrategies #-}
-{-# 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)
 import Control.Monad.Random.Strict qualified as R
@@ -101,27 +99,27 @@ hashSig :: Text -> FunctionHash
 hashSig = abiKeccak . TE.encodeUtf8
 
 -- | Configuration necessary for generating new 'SolCalls'. Don't construct this by hand! Use 'mkConf'.
-data GenDict = GenDict { _pSynthA    :: Float
-                         -- ^ Fraction of time to use dictionary vs. synthesize
-                       , _constants  :: HashMap AbiType (Set AbiValue)
-                         -- ^ Constants to use, sorted by type
-                       , _wholeCalls :: HashMap SolSignature (Set SolCall)
-                         -- ^ Whole calls to use, sorted by type
-                       , _defSeed    :: Int
-                         -- ^ Default seed to use if one is not provided in EConfig
-                       , _rTypes     :: Text -> Maybe AbiType
-                         -- ^ Return types of any methods we scrape return values from
-                       , _dictValues :: Set W256
-                         -- ^ A set of int/uint constants for better performance
-                       }
-
-makeLenses 'GenDict
+data GenDict = GenDict
+  { pSynthA    :: Float
+    -- ^ Fraction of time to use dictionary vs. synthesize
+  , constants  :: HashMap AbiType (Set AbiValue)
+    -- ^ Constants to use, sorted by type
+  , wholeCalls :: HashMap SolSignature (Set SolCall)
+    -- ^ Whole calls to use, sorted by type
+  , defSeed    :: Int
+    -- ^ Default seed to use if one is not provided in EConfig
+  , rTypes     :: Text -> Maybe AbiType
+    -- ^ Return types of any methods we scrape return values from
+  , dictValues :: Set W256
+    -- ^ A set of int/uint constants for better performance
+  }
 
 hashMapBy :: (Hashable k, Hashable a, Eq k, Ord a) => (a -> k) -> Set a -> HashMap k (Set a)
 hashMapBy f = M.fromListWith Set.union . fmap (\v -> (f v, Set.singleton v)) . Set.toList
 
 gaddCalls :: Set SolCall -> GenDict -> GenDict
-gaddCalls c = wholeCalls <>~ hashMapBy (fmap $ fmap abiValueType) c
+gaddCalls calls dict =
+  dict { wholeCalls = dict.wholeCalls <> hashMapBy (fmap $ fmap abiValueType) calls }
 
 defaultDict :: GenDict
 defaultDict = mkGenDict 0 Set.empty Set.empty 0 (const Nothing)
@@ -307,7 +305,7 @@ genWithDict :: (Eq a, Hashable a, MonadRandom m)
             => GenDict -> HashMap a (Set b) -> (a -> m b) -> a -> m b
 genWithDict genDict m g t = do
   r <- getRandom
-  let maybeValM = if genDict._pSynthA >= r then fromDict else pure Nothing
+  let maybeValM = if genDict.pSynthA >= r then fromDict else pure Nothing
       fromDict = case M.lookup t m of
                    Nothing -> pure Nothing
                    Just cs -> Just <$> rElem' cs
@@ -315,7 +313,7 @@ genWithDict genDict m g t = do
 
 -- | Synthesize a random 'AbiValue' given its 'AbiType'. Requires a dictionary.
 genAbiValueM :: MonadRandom m => GenDict -> AbiType -> m AbiValue
-genAbiValueM genDict = genWithDict genDict genDict._constants $ \case
+genAbiValueM genDict = genWithDict genDict genDict.constants $ \case
   (AbiUIntType n)         -> fixAbiUInt n . fromInteger <$> getRandomUint n
   (AbiIntType n)          -> fixAbiInt n . fromInteger <$> getRandomInt n
   AbiAddressType          -> AbiAddress . fromInteger <$> getRandomR (0, 2 ^ (160 :: Integer) - 1)
@@ -334,7 +332,7 @@ genAbiValueM genDict = genWithDict genDict genDict._constants $ \case
 genAbiCallM :: MonadRandom m => GenDict -> SolSignature -> m SolCall
 genAbiCallM genDict abi = do
   solCall <- genWithDict genDict
-                         genDict._wholeCalls
+                         genDict.wholeCalls
                          (traverse $ traverse (genAbiValueM genDict))
                          abi
   mutateAbiCall solCall
diff --git a/lib/Echidna/Campaign.hs b/lib/Echidna/Campaign.hs
index 9c4de7ee3..762e4e60e 100644
--- a/lib/Echidna/Campaign.hs
+++ b/lib/Echidna/Campaign.hs
@@ -221,13 +221,16 @@ callseq ic v w ql = do
   -- Keep track of the number of calls to `callseq`
   ncallseqs += 1
   -- Now we try to parse the return values as solidity constants, and add then to the 'GenDict'
-  types <- gets (._genDict._rTypes)
+  types <- gets (._genDict.rTypes)
   let results = parse (map (\(t, (vr, _)) -> (t, vr)) res) types
       -- union the return results with the new addresses
       additions = H.unionWith Set.union diffs results
   -- append to the constants dictionary
-  modifying (genDict . constants) . H.unionWith Set.union $ additions
-  modifying (genDict . dictValues) . Set.union $ mkDictValues $ Set.unions $ H.elems additions
+  let dict = camp._genDict
+  genDict .= dict
+    { constants = H.unionWith Set.union additions dict.constants
+    , dictValues = Set.union (mkDictValues $ Set.unions $ H.elems additions) dict.dictValues
+    }
   where
     -- Given a list of transactions and a return typing rule, this checks whether we know the return
     -- type for each function called, and if we do, tries to parse the return value as a value of that
@@ -258,8 +261,8 @@ campaign
 campaign u vm w ts d txs = do
   conf <- asks (.cfg.campaignConf)
   let c = fromMaybe mempty conf.knownCoverage
-  let effectiveSeed = fromMaybe d'._defSeed conf.seed
-      effectiveGenDict = d' { _defSeed = effectiveSeed }
+  let effectiveSeed = fromMaybe d'.defSeed conf.seed
+      effectiveGenDict = d' { defSeed = effectiveSeed }
       d' = fromMaybe defaultDict d
   execStateT
     (evalRandT runCampaign (mkStdGen effectiveSeed))
diff --git a/lib/Echidna/Config.hs b/lib/Echidna/Config.hs
index 91bafd4fd..076a88cc1 100644
--- a/lib/Echidna/Config.hs
+++ b/lib/Echidna/Config.hs
@@ -16,6 +16,7 @@ import Data.Text (isPrefixOf)
 import Data.Yaml qualified as Y
 
 import EVM (VM(..))
+import EVM.Types (W256)
 
 import Echidna.Test
 import Echidna.Types.Campaign
@@ -51,15 +52,21 @@ instance FromJSON EConfigWithUsage where
             let useKey k = modify' $ insert k
                 x ..:? k = useKey k >> lift (x .:? k)
                 x ..!= y = fromMaybe y <$> x
-                getWord s d = fromIntegral <$> v ..:? s ..!= (d :: Integer)
+                -- Parse as unbounded Integer and see if it fits into W256
+                getWord256 k def = do
+                  value :: Integer <- fromMaybe (fromIntegral (def :: W256)) <$> v ..:? k
+                  if value > fromIntegral (maxBound :: W256) then
+                    fail $ show k <> ": value does not fit in 256 bits"
+                  else
+                    pure $ fromIntegral value
 
                 -- TxConf
-                xc = TxConf <$> getWord "propMaxGas" maxGasPerBlock
-                            <*> getWord "testMaxGas" maxGasPerBlock
-                            <*> getWord "maxGasprice" 0
-                            <*> getWord "maxTimeDelay" defaultTimeDelay
-                            <*> getWord "maxBlockDelay" defaultBlockDelay
-                            <*> getWord "maxValue" 100000000000000000000 -- 100 eth
+                xc = TxConf <$> v ..:? "propMaxGas" ..!= maxGasPerBlock
+                            <*> v ..:? "testMaxGas" ..!= maxGasPerBlock
+                            <*> getWord256 "maxGasprice" 0
+                            <*> getWord256 "maxTimeDelay" defaultTimeDelay
+                            <*> getWord256 "maxBlockDelay" defaultBlockDelay
+                            <*> getWord256 "maxValue" 100000000000000000000 -- 100 eth
 
                 -- TestConf
                 tc = do
@@ -103,7 +110,7 @@ instance FromJSON EConfigWithUsage where
                              <*> v ..:? "initialize"      ..!= Nothing
                              <*> v ..:? "deployContracts" ..!= []
                              <*> v ..:? "deployBytecodes" ..!= []
-                             <*> v ..:? "multi-abi"       ..!= False
+                             <*> v ..:? "allContracts"    ..!= False
                              <*> mode
                              <*> v ..:? "testDestruction" ..!= False
                              <*> v ..:? "allowFFI"        ..!= False
diff --git a/lib/Echidna/Fetch.hs b/lib/Echidna/Fetch.hs
index 38f894c60..da6251374 100644
--- a/lib/Echidna/Fetch.hs
+++ b/lib/Echidna/Fetch.hs
@@ -33,7 +33,7 @@ deployBytecodes' di ((a, bc):cs) d vm =
   where
     zeros = pack $ replicate 320 0 -- This will initialize with zero a large number of possible constructor parameters
     loadRest = do
-      vm' <- execStateT (execTx $ createTx (bc `append` zeros) d a (fromInteger unlimitedGasPerBlock) (0, 0)) vm
+      vm' <- execStateT (execTx $ createTx (bc `append` zeros) d a unlimitedGasPerBlock (0, 0)) vm
       case vm'._result of
         (Just (VMSuccess _)) -> return vm'
         _ -> throwM $ DeploymentFailed a (Data.Text.unlines $ extractEvents True di vm')
diff --git a/lib/Echidna/Output/JSON.hs b/lib/Echidna/Output/JSON.hs
index 1e0bd5259..6103eea4d 100644
--- a/lib/Echidna/Output/JSON.hs
+++ b/lib/Echidna/Output/JSON.hs
@@ -97,7 +97,7 @@ encodeCampaign C.Campaign{..} = encode
   Campaign { _success = True
            , _error = Nothing
            , _tests = mapTest <$> _tests
-           , seed = _genDict._defSeed
+           , seed = _genDict.defSeed
            , coverage = mapKeys (("0x" ++) . (`showHex` "") . keccak') $ DF.toList <$>_coverage
            , gasInfo = toList _gasInfo
            }
diff --git a/lib/Echidna/RPC.hs b/lib/Echidna/RPC.hs
index 797c22284..c824cd776 100644
--- a/lib/Echidna/RPC.hs
+++ b/lib/Echidna/RPC.hs
@@ -160,6 +160,6 @@ execEthenoTxs et = do
 -- | For an etheno txn, set up VM to execute txn
 setupEthenoTx :: MonadState VM m => Etheno -> m ()
 setupEthenoTx (AccountCreated f) = initAddress f -- TODO: improve etheno to include initial balance
-setupEthenoTx (ContractCreated f c _ _ d v) = setupTx $ createTxWithValue d f c (fromInteger unlimitedGasPerBlock) v (1, 1)
-setupEthenoTx (FunctionCall f t _ _ d v) = setupTx $ Tx (SolCalldata d) f t (fromInteger unlimitedGasPerBlock) 0 v (1, 1)
+setupEthenoTx (ContractCreated f c _ _ d v) = setupTx $ createTxWithValue d f c unlimitedGasPerBlock v (1, 1)
+setupEthenoTx (FunctionCall f t _ _ d v) = setupTx $ Tx (SolCalldata d) f t unlimitedGasPerBlock 0 v (1, 1)
 setupEthenoTx (BlockMined n t) = setupTx $ Tx NoCall 0 0 0 0 0 (fromInteger t, fromInteger n)
diff --git a/lib/Echidna/Solidity.hs b/lib/Echidna/Solidity.hs
index f0fc8aaef..deaa4e9be 100644
--- a/lib/Echidna/Solidity.hs
+++ b/lib/Echidna/Solidity.hs
@@ -184,7 +184,7 @@ loadSpecified solConf name cs = do
 
   -- Set up initial VM, either with chosen contract or Etheno initialization file
   -- need to use snd to add to ABI dict
-  let vm = initialVM ffi & block . gaslimit .~ fromInteger unlimitedGasPerBlock
+  let vm = initialVM ffi & block . gaslimit .~ unlimitedGasPerBlock
                          & block . maxCodeSize .~ fromInteger mcs
   blank' <- maybe (pure vm) (loadEthenoBatch ffi) fp
   let blank = populateAddresses (Set.insert d ads) bala blank'
@@ -218,12 +218,12 @@ loadSpecified solConf name cs = do
       vm2 <- deployBytecodes di dpb d vm1
 
       -- main contract deployment
-      let deployment = execTx $ createTxWithValue bc d ca (fromInteger unlimitedGasPerBlock) (fromInteger balc) (0, 0)
+      let deployment = execTx $ createTxWithValue bc d ca unlimitedGasPerBlock (fromInteger balc) (0, 0)
       vm3 <- execStateT deployment vm2
       when (isNothing $ currentContract vm3) (throwM $ DeploymentFailed ca $ T.unlines $ extractEvents True di vm3)
 
       -- Run
-      let transaction = execTx $ uncurry basicTx setUpFunction d ca (fromInteger unlimitedGasPerBlock) (0, 0)
+      let transaction = execTx $ uncurry basicTx setUpFunction d ca unlimitedGasPerBlock (0, 0)
       vm4 <- if isDapptestMode tm && setUpFunction `elem` abi then execStateT transaction vm3 else return vm3
 
       case vm4._result of
diff --git a/lib/Echidna/Transaction.hs b/lib/Echidna/Transaction.hs
index 82636bccc..b2cb33e28 100644
--- a/lib/Echidna/Transaction.hs
+++ b/lib/Echidna/Transaction.hs
@@ -51,7 +51,7 @@ genTxM memo m = do
   World ss hmm lmm ps _ <- asks fst
   genDict <- gets (._genDict)
   mm <- getSignatures hmm lmm
-  let ns = genDict._dictValues
+  let ns = genDict.dictValues
   s' <- rElem' ss
   r' <- rElem' $ Set.fromList (mapMaybe (toContractA mm) (toList m))
   c' <- genInteractionsM genDict (snd r')
diff --git a/lib/Echidna/Types/Solidity.hs b/lib/Echidna/Types/Solidity.hs
index d14de6d60..3303e1252 100644
--- a/lib/Echidna/Types/Solidity.hs
+++ b/lib/Echidna/Types/Solidity.hs
@@ -72,7 +72,7 @@ data SolConf = SolConf
   , initialize      :: Maybe FilePath   -- ^ Initialize world with Etheno txns
   , deployContracts :: [(Addr, String)] -- ^ List of contracts to deploy in specific addresses
   , deployBytecodes :: [(Addr, Text)]   -- ^ List of contracts to deploy in specific addresses
-  , multiAbi        :: Bool             -- ^ Whether or not to use the multi-abi mode
+  , allContracts    :: Bool             -- ^ Whether or not to fuzz all contracts
   , testMode        :: String           -- ^ Testing mode
   , testDestruction :: Bool             -- ^ Whether or not to add a property to detect contract destruction
   , allowFFI        :: Bool             -- ^ Whether or not to allow FFI hevm cheatcode
diff --git a/lib/Echidna/Types/Tx.hs b/lib/Echidna/Types/Tx.hs
index 0973a250b..ef3ee98dc 100644
--- a/lib/Echidna/Types/Tx.hs
+++ b/lib/Echidna/Types/Tx.hs
@@ -31,16 +31,16 @@ data TxCall = SolCreate   ByteString
   deriving (Show, Ord, Eq)
 $(deriveJSON defaultOptions ''TxCall)
 
-maxGasPerBlock :: Integer
+maxGasPerBlock :: Word64
 maxGasPerBlock = 12500000 -- https://cointelegraph.com/news/ethereum-miners-vote-to-increase-gas-limit-causing-community-debate
 
-unlimitedGasPerBlock :: Integer
+unlimitedGasPerBlock :: Word64
 unlimitedGasPerBlock = 0xffffffff
 
-defaultTimeDelay :: Integer
+defaultTimeDelay :: W256
 defaultTimeDelay = 604800
 
-defaultBlockDelay :: Integer
+defaultBlockDelay :: W256
 defaultBlockDelay = 60480
 
 initialTimestamp :: W256
@@ -207,5 +207,5 @@ getResult (VMFailure (FFI _))                   = ErrorFFI
 getResult (VMFailure NonceOverflow)             = ErrorNonceOverflow
 
 makeSingleTx :: Addr -> Addr -> W256 -> TxCall -> [Tx]
-makeSingleTx a d v (SolCall c) = [Tx (SolCall c) a d (fromInteger maxGasPerBlock) 0 v (0, 0)]
+makeSingleTx a d v (SolCall c) = [Tx (SolCall c) a d maxGasPerBlock 0 v (0, 0)]
 makeSingleTx _ _ _ _           = error "invalid usage of makeSingleTx"
diff --git a/lib/Echidna/UI.hs b/lib/Echidna/UI.hs
index 61c2e0c3e..426ce8a15 100644
--- a/lib/Echidna/UI.hs
+++ b/lib/Echidna/UI.hs
@@ -19,7 +19,7 @@ import Control.Monad (when)
 import Control.Monad.State.Strict (get)
 #endif
 
-import Control.Monad.Catch (MonadCatch(..))
+import Control.Monad.Catch (MonadCatch(..), catchAll)
 import Control.Monad.IO.Class (MonadIO(..))
 import Control.Monad.Reader (MonadReader, runReader, asks)
 import Control.Monad.Random.Strict (MonadRandom)
@@ -41,7 +41,10 @@ import Echidna.Types.World (World)
 import Echidna.UI.Report
 import Echidna.Types.Config
 
-data CampaignEvent = CampaignUpdated Campaign | CampaignTimedout Campaign
+data CampaignEvent =
+  CampaignUpdated Campaign
+  | CampaignTimedout Campaign
+  | CampaignCrashed String
 
 -- | Set up and run an Echidna 'Campaign' and display interactive UI or
 -- print non-interactive output in desired format at the end
@@ -78,9 +81,12 @@ ui vm world ts d txs = do
       ticker <- liftIO $ forkIO $ -- run UI update every 100ms
         forever $ threadDelay 100000 >> updateUI CampaignUpdated
       _ <- forkFinally -- run worker
-        (void $ runCampaign >>= \case
-          Nothing -> liftIO $ updateUI CampaignTimedout
-          Just _ -> liftIO $ updateUI CampaignUpdated
+        (void $ do
+          catchAll
+            (runCampaign >>= \case
+              Nothing -> liftIO $ updateUI CampaignTimedout
+              Just _ -> liftIO $ updateUI CampaignUpdated)
+            (liftIO . writeBChan bc . CampaignCrashed . show)
         )
         (const $ liftIO $ killThread ticker)
       let buildVty = do
@@ -132,6 +138,9 @@ monitor = do
 
       onEvent (AppEvent (CampaignUpdated c')) = put (c', Running)
       onEvent (AppEvent (CampaignTimedout c')) = put (c', Timedout)
+      onEvent (AppEvent (CampaignCrashed e)) = do
+        (c,_) <- get
+        put (c, Crashed e)
       onEvent (VtyEvent (EvKey KEsc _))                         = halt
       onEvent (VtyEvent (EvKey (KChar 'c') l)) | MCtrl `elem` l = halt
       onEvent (MouseDown (SBClick el n) _ _ _) =
diff --git a/lib/Echidna/UI/Report.hs b/lib/Echidna/UI/Report.hs
index c45ab5332..e25265418 100644
--- a/lib/Echidna/UI/Report.hs
+++ b/lib/Echidna/UI/Report.hs
@@ -124,7 +124,7 @@ ppCampaign c = do
   gasInfoPrinted <- ppGasInfo c
   let coveragePrinted = maybe "" ("\n" ++) . ppCoverage $ c._coverage
       corpusPrinted = maybe "" ("\n" ++) . ppCorpus $ c._corpus
-      seedPrinted = "\nSeed: " ++ show c._genDict._defSeed
+      seedPrinted = "\nSeed: " ++ show c._genDict.defSeed
   pure $
     testsPrinted
     ++ gasInfoPrinted
diff --git a/lib/Echidna/UI/Widgets.hs b/lib/Echidna/UI/Widgets.hs
index ac03d65a0..3f8b9c798 100644
--- a/lib/Echidna/UI/Widgets.hs
+++ b/lib/Echidna/UI/Widgets.hs
@@ -26,7 +26,7 @@ import Echidna.Types.Tx (Tx(..), TxResult(..))
 import Echidna.UI.Report
 import Echidna.Types.Config
 
-data UIState = Uninitialized | Running | Timedout
+data UIState = Uninitialized | Running | Timedout | Crashed String
 
 attrs :: A.AttrMap
 attrs = A.attrMap (V.white `on` V.black)
@@ -49,31 +49,42 @@ campaignStatus :: MonadReader EConfig m
 campaignStatus (c@Campaign{_tests, _coverage, _ncallseqs}, uiState) = do
   done <- isDone c
   case (uiState, done) of
-    (Uninitialized, _) -> pure $ mainbox (padLeft (Pad 1) $ str "Starting up, please wait...") emptyWidget
-    (Timedout, _)      -> mainbox <$> testsWidget _tests <*> pure (str "Timed out, C-c or esc to exit")
-    (_, True)          -> mainbox <$> testsWidget _tests <*> pure (str "Campaign complete, C-c or esc to exit")
-    _                  -> mainbox <$> testsWidget _tests <*> pure emptyWidget
+    (Uninitialized, _) ->
+      pure $ mainbox (padLeft (Pad 1) $ str "Starting up, please wait...") emptyWidget
+    (Crashed e, _) ->
+      pure $ mainbox (padLeft (Pad 1) $
+        withAttr (attrName "failure") $ strBreak $ formatCrashReport e) emptyWidget
+    (Timedout, _) ->
+      mainboxTests (str "Timed out, C-c or esc to exit")
+    (_, True) ->
+      mainboxTests (str "Campaign complete, C-c or esc to exit")
+    _ ->
+      mainboxTests emptyWidget
   where
+    mainboxTests underneath = do
+      t <- testsWidget _tests
+      pure $ mainbox (summaryWidget c <=> hBorderWithLabel (str "Tests") <=> t) underneath
+
     mainbox :: Widget Name -> Widget Name -> Widget Name
     mainbox inner underneath =
       padTop (Pad 1) $ hCenter $ hLimit 120 $
       wrapInner inner
       <=>
       hCenter underneath
-    wrapInner inner =
-      borderWithLabel (withAttr (attrName "bold") $ str title) $
-      summaryWidget c
-      <=>
-      hBorderWithLabel (str "Tests")
-      <=>
-      inner
+    wrapInner = borderWithLabel (withAttr (attrName "bold") $ str title)
     title = "Echidna " ++ showVersion Paths_echidna.version
 
+formatCrashReport :: String -> String
+formatCrashReport e =
+  "Echidna crashed with an error:\n\n" <>
+  e <>
+  "\n\nPlease report it to https://github.com/crytic/echidna/issues"
+
 summaryWidget :: Campaign -> Widget Name
 summaryWidget c =
   padLeft (Pad 1) (
       str ("Tests found: " ++ show (length c._tests)) <=>
-      str ("Seed: " ++ show c._genDict._defSeed)
+      str ("Seed: " ++ show c._genDict.defSeed)
     <=>
     maybe emptyWidget str (ppCoverage c._coverage)
     <=>
@@ -132,7 +143,7 @@ eventWidget :: Events -> Widget n
 eventWidget es =
   if null es then str ""
   else str "Event sequence" <+> str ":"
-       <=> strWrapWith wrapSettings (T.unpack $ T.intercalate "\n" es)
+       <=> strBreak (T.unpack $ T.intercalate "\n" es)
 
 failWidget :: MonadReader EConfig m
            => Maybe (Int, Int) -> [Tx] -> Events -> TestValue -> TxResult -> m (Widget Name, Widget Name)
@@ -177,7 +188,7 @@ seqWidget xs = do
     let ordinals = str . printf "%d." <$> [1 :: Int ..]
     pure $
       foldl (<=>) emptyWidget $
-        zipWith (<+>) ordinals (withAttr (attrName "tx") . strWrapWith wrapSettings <$> ppTxs)
+        zipWith (<+>) ordinals (withAttr (attrName "tx") . strBreak <$> ppTxs)
 
 failureBadge :: Widget Name
 failureBadge = withAttr (attrName "failure") $ str "FAILED!"
@@ -185,7 +196,7 @@ failureBadge = withAttr (attrName "failure") $ str "FAILED!"
 maximumBadge :: Widget Name
 maximumBadge = withAttr (attrName "maximum") $ str "OPTIMIZED!"
 
-wrapSettings :: WrapSettings
-wrapSettings = defaultWrapSettings { breakLongWords = True }
+strBreak :: String -> Widget n
+strBreak = strWrapWith $ defaultWrapSettings { breakLongWords = True }
 
-#endif
\ No newline at end of file
+#endif
diff --git a/package.yaml b/package.yaml
index b4796e731..f4c5edd47 100644
--- a/package.yaml
+++ b/package.yaml
@@ -61,11 +61,6 @@ library:
   source-dirs: lib/
 
 when:
-  - condition: os(darwin)
-    extra-libraries: c++
-    ld-options: -Wl,-keep_dwarf_unwind
-  - condition: os(windows)
-    extra-libraries: stdc++
   - condition: "!os(windows)"
     cpp-options: -DINTERACTIVE_UI
     dependencies:
@@ -89,7 +84,11 @@ executables:
           ghc-options:
             - -O2
           ld-options: -pthread
-
+        - condition: os(darwin)
+          extra-libraries: c++
+          ld-options: -Wl,-keep_dwarf_unwind
+        - condition: os(windows)
+          extra-libraries: stdc++
 tests:
   echidna-testsuite:
     main: Spec.hs
@@ -110,6 +109,11 @@ tests:
           ghc-options:
             - -O2
           ld-options: -pthread
+        - condition: os(darwin)
+          extra-libraries: c++
+          ld-options: -Wl,-keep_dwarf_unwind
+        - condition: os(windows)
+          extra-libraries: stdc++
 
 flags:
   static:
diff --git a/src/Main.hs b/src/Main.hs
index 19cbffb66..ca1f6e3a6 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -80,7 +80,7 @@ data Options = Options
   , cliOutputFormat     :: Maybe OutputFormat
   , cliCorpusDir        :: Maybe FilePath
   , cliTestMode         :: Maybe TestMode
-  , cliMultiAbi         :: Bool
+  , cliAllContracts     :: Bool
   , cliTestLimit        :: Maybe Int
   , cliShrinkLimit      :: Maybe Int
   , cliSeqLen           :: Maybe Int
@@ -115,8 +115,8 @@ options = Options
     <> help "Directory to save and load corpus and coverage data.")
   <*> optional (option str $ long "test-mode"
     <> help "Test mode to use. Either 'property', 'assertion', 'dapptest', 'optimization', 'overflow' or 'exploration'" )
-  <*> switch (long "multi-abi"
-    <> help "Use multi-abi mode of testing.")
+  <*> switch (long "all-contracts"
+    <> help "Generate calls to all deployed contracts.")
   <*> optional (option auto $ long "test-limit"
     <> metavar "INTEGER"
     <> help ("Number of sequences of transactions to generate during testing. Default is " ++ show defaultTestLimit))
@@ -180,5 +180,5 @@ overrideConfig config Options{..} =
       , deployer = fromMaybe solConf.deployer cliDeployer
       , contractAddr = fromMaybe solConf.contractAddr cliContractAddr
       , testMode = maybe solConf.testMode validateTestMode cliTestMode
-      , multiAbi = cliMultiAbi || solConf.multiAbi
+      , allContracts = cliAllContracts || solConf.allContracts
       }
diff --git a/src/test/Tests/Config.hs b/src/test/Tests/Config.hs
index f1aad7f66..74bcc53e5 100644
--- a/src/test/Tests/Config.hs
+++ b/src/test/Tests/Config.hs
@@ -1,14 +1,16 @@
 module Tests.Config (configTests) where
 
 import Test.Tasty (TestTree, testGroup)
-import Test.Tasty.HUnit (testCase, assertBool, (@?=))
+import Test.Tasty.HUnit (testCase, assertBool, (@?=), assertFailure)
 
 import Control.Lens (sans)
 import Control.Monad (void)
 import Data.Function ((&))
+import Data.Yaml qualified as Y
 
 import Echidna.Types.Config (EConfigWithUsage(..), EConfig(..))
 import Echidna.Types.Campaign (CampaignConf(..))
+import Echidna.Types.Tx (TxConf(..))
 import Echidna.Config (defaultConfig, parseConfig)
 
 configTests :: TestTree
@@ -24,6 +26,16 @@ configTests = testGroup "Configuration tests" $
       assertBool ("unused options: " ++ show bad) $ null bad
       let unset' = unset & sans "seed"
       assertBool ("unset options: " ++ show unset') $ null unset'
+  , testCase "W256 decoding" $ do
+      let maxW256  = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+          overW256 = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"
+      case Y.decodeEither' ("maxGasprice: " <> maxW256) of
+        Right (c :: EConfigWithUsage) | c.econfig.txConf.maxGasprice == maxBound -> pure ()
+        Right _ -> assertFailure "wrong value decoded"
+        Left e -> assertFailure $ "unexpected decoding error: " <> show e
+      case Y.decodeEither' ("maxGasprice: " <> overW256) of
+        Right (_ :: EConfigWithUsage) -> assertFailure "should not decode"
+        Left _ -> pure ()
   ]
   where files = ["basic/config.yaml", "basic/default.yaml"]
         assertCoverage config value = config.campaignConf.knownCoverage @?= value
diff --git a/src/test/Tests/Integration.hs b/src/test/Tests/Integration.hs
index 4da9a6dc9..bb0303609 100644
--- a/src/test/Tests/Integration.hs
+++ b/src/test/Tests/Integration.hs
@@ -57,7 +57,7 @@ integrationTests = testGroup "Solidity Integration Testing"
       ]
   , testContract "basic/library.sol"      (Just "basic/library.yaml")
       [ ("echidna_library_call failed",            solved      "echidna_library_call")
-      , ("echidna_valid_timestamp failed",         passed      "echidna_valid_timestamp") 
+      , ("echidna_valid_timestamp failed",         passed      "echidna_valid_timestamp")
       ]
   , testContractV "basic/fallback.sol"   (Just (< solcV (0,6,0))) Nothing
       [ ("echidna_fallback failed",                solved      "echidna_fallback") ]
@@ -74,7 +74,7 @@ integrationTests = testGroup "Solidity Integration Testing"
       [ ("echidna_construct passed",               solved      "echidna_construct") ]
   , testContract "basic/gasprice.sol"     (Just "basic/gasprice.yaml")
       [ ("echidna_state passed",                   solved      "echidna_state") ]
-  , testContract' "basic/multi-abi.sol" (Just "B") Nothing (Just "basic/multi-abi.yaml") True
+  , testContract' "basic/allContracts.sol" (Just "B") Nothing (Just "basic/allContracts.yaml") True
       [ ("echidna_test passed",                    solved      "echidna_test") ]
   , testContract "basic/array-mutation.sol"   Nothing
       [ ("echidna_mutated passed",                 solved      "echidna_mutated") ]
@@ -94,7 +94,7 @@ integrationTests = testGroup "Solidity Integration Testing"
   ,  checkConstructorConditions "basic/codesize.sol"
       "invalid codesize"
   , testContractV "basic/eip-170.sol" (Just (>= solcV (0,5,0))) (Just "basic/eip-170.yaml")
-      [ ("echidna_test passed",                    passed      "echidna_test") ] 
+      [ ("echidna_test passed",                    passed      "echidna_test") ]
   , testContract' "basic/deploy.sol" (Just "Test") Nothing (Just "basic/deployContract.yaml") True
       [ ("test passed",                    solved     "test") ]
   , testContract' "basic/deploy.sol" (Just "Test") Nothing (Just "basic/deployBytecode.yaml") True
diff --git a/tests/solidity/assert/multi.yaml b/tests/solidity/assert/multi.yaml
index 643cbf3fd..82643f037 100644
--- a/tests/solidity/assert/multi.yaml
+++ b/tests/solidity/assert/multi.yaml
@@ -1,2 +1,2 @@
 testMode: assertion
-multi-abi: true
+allContracts: true
diff --git a/tests/solidity/basic/multi-abi.sol b/tests/solidity/basic/allContracts.sol
similarity index 100%
rename from tests/solidity/basic/multi-abi.sol
rename to tests/solidity/basic/allContracts.sol
diff --git a/tests/solidity/basic/allContracts.yaml b/tests/solidity/basic/allContracts.yaml
new file mode 100644
index 000000000..8f7ae58ba
--- /dev/null
+++ b/tests/solidity/basic/allContracts.yaml
@@ -0,0 +1 @@
+allContracts: true
diff --git a/tests/solidity/basic/default.yaml b/tests/solidity/basic/default.yaml
index 732f83f48..5d31933de 100644
--- a/tests/solidity/basic/default.yaml
+++ b/tests/solidity/basic/default.yaml
@@ -54,8 +54,8 @@ initialize: null
 deployContracts: []
 #initialize the blockchain with some bytecode in some addresses
 deployBytecodes: []
-#whether ot not to use the multi-abi mode of testing
-multi-abi: false
+#whether ot not to fuzz all contracts
+allContracts: false
 #timeout controls test timeout settings
 timeout: null
 #seed not defined by default, is the random seed
diff --git a/tests/solidity/basic/multi-abi.yaml b/tests/solidity/basic/multi-abi.yaml
deleted file mode 100644
index 8b3fc2674..000000000
--- a/tests/solidity/basic/multi-abi.yaml
+++ /dev/null
@@ -1 +0,0 @@
-multi-abi: true