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

Fix W256 values parsing from config #935

Merged
merged 1 commit into from
Feb 21, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
21 changes: 14 additions & 7 deletions lib/Echidna/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/Echidna/Fetch.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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')
4 changes: 2 additions & 2 deletions lib/Echidna/RPC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
6 changes: 3 additions & 3 deletions lib/Echidna/Solidity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions lib/Echidna/Types/Tx.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
14 changes: 13 additions & 1 deletion src/test/Tests/Config.hs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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