mirror of https://github.com/crytic/echidna
parent
35319e8d5d
commit
413f97266b
Binary file not shown.
@ -0,0 +1,22 @@ |
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) 2018 Truffle |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@ |
||||
This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove. |
@ -0,0 +1,10 @@ |
||||
pragma solidity >=0.4.25 <0.6.0; |
||||
|
||||
contract Bar { |
||||
|
||||
constructor() public {} |
||||
|
||||
function test() public pure returns (uint) { |
||||
return 1; |
||||
} |
||||
} |
@ -0,0 +1,25 @@ |
||||
pragma solidity >=0.4.25 <0.6.0; |
||||
|
||||
contract Bar { |
||||
function test() public pure returns (uint) {} |
||||
} |
||||
|
||||
contract Foo { |
||||
Bar bar; |
||||
uint isOne; |
||||
|
||||
constructor(address _bar) public { |
||||
bar = Bar(_bar); |
||||
//bar = new Bar(); |
||||
isOne = 0; |
||||
} |
||||
|
||||
function callBar() public { |
||||
isOne = bar.test(); |
||||
} |
||||
|
||||
function echidna_test() public view returns (bool) { |
||||
bar.test(); |
||||
return isOne == 0; |
||||
} |
||||
} |
@ -0,0 +1,23 @@ |
||||
pragma solidity >=0.4.25 <0.6.0; |
||||
|
||||
contract Migrations { |
||||
address public owner; |
||||
uint public last_completed_migration; |
||||
|
||||
modifier restricted() { |
||||
if (msg.sender == owner) _; |
||||
} |
||||
|
||||
constructor() public { |
||||
owner = msg.sender; |
||||
} |
||||
|
||||
function setCompleted(uint completed) public restricted { |
||||
last_completed_migration = completed; |
||||
} |
||||
|
||||
function upgrade(address new_address) public restricted { |
||||
Migrations upgraded = Migrations(new_address); |
||||
upgraded.setCompleted(last_completed_migration); |
||||
} |
||||
} |
@ -0,0 +1,2 @@ |
||||
contractAddr: "0x12342" |
||||
initialize: "./examples/basic_multicontract/export.json" |
@ -0,0 +1,17 @@ |
||||
[ |
||||
{"event": "AccountCreated", "address": "9bc0895dc163e5dc83f9654186c9ee60b7736f1a"}, |
||||
{"event": "AccountCreated", "address": "b4a07ad03011e7afa37e80890cfbab65960988b6"}, |
||||
{"event": "AccountCreated", "address": "b0d71bcbcca8d1c4c2cb0ab4bae6d951f035e577"}, |
||||
{"event": "AccountCreated", "address": "e498baf98383a8c0cb2a3ff8002cf4ca6c5295b8"}, |
||||
{"event": "AccountCreated", "address": "907128412912321ea7a01ef1d1196588b01cb98b"}, |
||||
{"event": "AccountCreated", "address": "93a3cda86dbb1b5dccd6f6719e5030dd65b267b4"}, |
||||
{"event": "AccountCreated", "address": "7a3a17fbebbaa1a9576845f31a07ef5be353f71d"}, |
||||
{"event": "AccountCreated", "address": "7fae60090e87dd649074938432e1d0af3f8fbcf9"}, |
||||
{"event": "AccountCreated", "address": "45d33bed8871017e7b1fbd22a1dd47faeb1d914a"}, |
||||
{"event": "AccountCreated", "address": "57da5aaf5de3ff574ffbd8cb3a4885238a926616"}, |
||||
{"event": "ContractCreated", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "contract_address": "0xf02e7bc30fdcc89826547b09303a253c85a68784", "gas_used": "0x43bd6", "gas_price": "0x4a817c800", "data": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f8806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820b27f3ee844fe76b108178ff61c03c5e1962752f695e0f1a3d1dc51c983c241310029", "value": "0x0"}, |
||||
{"event": "FunctionCall", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "to": "0xf02e7bc30fdcc89826547b09303a253c85a68784", "gas_used": "0xa418", "gas_price": "0x4a817c800", "data": "0xfdacd5760000000000000000000000000000000000000000000000000000000000000001", "value": "0x0"}, |
||||
{"event": "ContractCreated", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "contract_address": "0x2b1a87cac755d503e968296e19ccbd21da46462f", "gas_used": "0x171ed", "gas_price": "0x4a817c800", "data": "0x6080604052348015600f57600080fd5b50609d8061001e6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f8a8fd6d146044575b600080fd5b348015604f57600080fd5b506056606c565b6040518082815260200191505060405180910390f35b6000905600a165627a7a72305820fc76e4cc480ddc19670a05f11d40cca4bc0d260e9defbadaca10785b81cd16b60029", "value": "0x0"}, |
||||
{"event": "ContractCreated", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "contract_address": "0xc7a351e329e286f3b46dc8ab9ad82db6dc27daa1", "gas_used": "0x3b31c", "gas_price": "0x4a817c800", "data": "0x608060405234801561001057600080fd5b506040516020806102e483398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600181905550506102598061008b6000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317bf8bac14610051578063acffee6b14610080575b600080fd5b34801561005d57600080fd5b50610066610097565b604051808215151515815260200191505060405180910390f35b34801561008c57600080fd5b50610095610165565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8a8fd6d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561011e57600080fd5b505af1158015610132573d6000803e3d6000fd5b505050506040513d602081101561014857600080fd5b810190808051906020019092919050505050600060015414905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8a8fd6d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156101ea57600080fd5b505af11580156101fe573d6000803e3d6000fd5b505050506040513d602081101561021457600080fd5b81019080805190602001909291905050506001819055505600a165627a7a7230582064bd2903f96a9a349e15dd6aad759df3d037ca5f5f2eb800af9a5467a935fa0900290000000000000000000000002b1a87cac755d503e968296e19ccbd21da46462f", "value": "0x0"}, |
||||
{"event": "FunctionCall", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "to": "0xf02e7bc30fdcc89826547b09303a253c85a68784", "gas_used": "0x6980", "gas_price": "0x4a817c800", "data": "0xfdacd5760000000000000000000000000000000000000000000000000000000000000002", "value": "0x0"} |
||||
] |
@ -0,0 +1,5 @@ |
||||
const Migrations = artifacts.require("Migrations"); |
||||
|
||||
module.exports = function(deployer) { |
||||
deployer.deploy(Migrations); |
||||
}; |
@ -0,0 +1,8 @@ |
||||
const Foo = artifacts.require("Foo"); |
||||
const Bar = artifacts.require("Bar"); |
||||
|
||||
module.exports = function(deployer) { |
||||
deployer.deploy(Bar).then(function() { |
||||
return deployer.deploy(Foo, Bar.address); |
||||
}); |
||||
}; |
@ -0,0 +1 @@ |
||||
This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove. |
@ -0,0 +1,26 @@ |
||||
module.exports = { |
||||
// Uncommenting the defaults below
|
||||
// provides for an easier quick-start with Ganache.
|
||||
// You can also follow this format for other networks;
|
||||
// see <http://truffleframework.com/docs/advanced/configuration>
|
||||
// for more details on how to specify configuration options!
|
||||
/* |
||||
networks: { |
||||
development: { |
||||
host: "127.0.0.1", |
||||
port: 7545, |
||||
network_id: "*" |
||||
}, |
||||
test: { |
||||
host: "127.0.0.1", |
||||
port: 7545, |
||||
network_id: "*" |
||||
} |
||||
} |
||||
*/ |
||||
compilers: { |
||||
solc: { |
||||
version: "0.4.25" |
||||
}, |
||||
}, |
||||
}; |
@ -1,117 +1,181 @@ |
||||
{-# LANGUAGE TemplateHaskell #-} |
||||
{-# LANGUAGE DeriveGeneric #-} |
||||
{-# LANGUAGE LambdaCase #-} |
||||
{-# LANGUAGE FlexibleContexts #-} |
||||
{-# LANGUAGE OverloadedStrings #-} |
||||
{-# LANGUAGE ScopedTypeVariables #-} |
||||
|
||||
module Echidna.RPC where |
||||
|
||||
import Prelude hiding (Word) |
||||
|
||||
import Control.Exception (Exception) |
||||
import Control.Lens |
||||
import Control.Monad (foldM) |
||||
import Control.Monad.Catch (MonadThrow, throwM) |
||||
import Control.Monad.IO.Class (MonadIO(..)) |
||||
import Control.Monad.State.Strict (MonadState, execState, execStateT, get, put, runState) |
||||
import Data.Aeson (FromJSON(..), defaultOptions, eitherDecodeFileStrict, genericParseJSON, omitNothingFields) |
||||
import Data.ByteString (ByteString, empty) |
||||
import Data.Has (Has(..)) |
||||
import Data.List (partition) |
||||
import Data.Text.Encoding (encodeUtf8) |
||||
import EVM |
||||
import EVM.Concrete (w256) |
||||
import EVM.Exec (exec, vmForEthrunCreation) |
||||
import EVM.Types (Addr, W256) |
||||
import GHC.Generics |
||||
|
||||
import qualified Control.Monad.State.Strict as S (state) |
||||
import qualified Data.Text as T |
||||
|
||||
import Echidna.Exec |
||||
import Echidna.Transaction |
||||
|
||||
|
||||
-- | During initialization we can either call a function or create an account or contract |
||||
data EthenoEvent = AccountCreated | ContractCreated | FunctionCall deriving(Eq, Show, Generic) |
||||
|
||||
instance FromJSON EthenoEvent |
||||
|
||||
-- | A single initialization event |
||||
data Etheno = Etheno { _event :: !EthenoEvent |
||||
, _address :: !Addr |
||||
, _from :: !Addr |
||||
, _to :: !Addr |
||||
, _contractAddr :: !Addr |
||||
, _gasUsed :: !Integer |
||||
, _gasPrice :: !Integer |
||||
, _initCode :: !T.Text |
||||
, _value :: !W256 |
||||
} deriving (Eq, Show, Generic) |
||||
|
||||
makeLenses ''Etheno |
||||
|
||||
instance FromJSON Etheno where |
||||
parseJSON = genericParseJSON $ defaultOptions{omitNothingFields = True} |
||||
|
||||
|
||||
-- | Handler for parsing errors |
||||
data EthenoException = EthenoException String |
||||
|
||||
instance Show EthenoException where |
||||
show (EthenoException e) = "Error parsing Etheno initialization file: " ++ e |
||||
|
||||
instance Exception EthenoException |
||||
|
||||
|
||||
-- | Main function: takes a filepath where the initialization sequence lives and returns |
||||
-- | the initialized VM along with a list of Addr's to put in GenConf |
||||
loadEthenoBatch :: (MonadThrow m, MonadIO m) => ByteString -> FilePath -> m (VM, [Addr]) |
||||
loadEthenoBatch echidnaInit fp = do |
||||
bs <- liftIO $ eitherDecodeFileStrict fp |
||||
|
||||
case bs of |
||||
(Left e) -> throwM $ EthenoException e |
||||
(Right ethenoInit) -> do |
||||
-- | Separate out account creation txns to use later for config |
||||
let (accounts, txs) = partition (\t -> t ^. event == AccountCreated) ethenoInit |
||||
knownAddrs = map (\e -> e ^. address) accounts |
||||
|
||||
-- | Execute contract creations and initial transactions, |
||||
let blank = vmForEthrunCreation empty |
||||
initVM = foldM (execEthenoTxs echidnaInit) 0x0 txs >>= liftSH . loadContract |
||||
|
||||
vm <- execStateT initVM blank |
||||
|
||||
import Prelude hiding (Word) |
||||
|
||||
import Debug.Trace (traceShow, trace) |
||||
|
||||
import Control.Exception (Exception) |
||||
import Control.Lens |
||||
import Control.Monad (foldM) |
||||
import Control.Monad.Catch (MonadThrow, throwM) |
||||
import Control.Monad.IO.Class (MonadIO(..)) |
||||
import Control.Monad.State.Strict (MonadState, execState, execStateT, runStateT, get, put, runState) |
||||
import Data.Aeson (FromJSON(..), (.:), withObject, eitherDecodeFileStrict) |
||||
import Data.ByteString.Char8 (ByteString, empty, unpack) |
||||
import Data.Has (Has(..)) |
||||
import Data.List (partition) |
||||
import Data.Map (fromList) |
||||
import Data.Text.Encoding (encodeUtf8) |
||||
import EVM |
||||
import EVM.Concrete (w256) |
||||
import EVM.Exec (exec, vmForEthrunCreation) |
||||
import EVM.Types (Addr, W256) |
||||
|
||||
import qualified Control.Monad.Fail as M (MonadFail(..)) |
||||
import qualified Control.Monad.State.Strict as S (state) |
||||
import qualified Data.ByteString.Base16 as BS16 (decode, encode) |
||||
import qualified Data.Text as T (Text, drop) |
||||
|
||||
import Echidna.Exec |
||||
import Echidna.Transaction |
||||
|
||||
-- | During initialization we can either call a function or create an account or contract |
||||
--data EthenoEvent = AccountCreated | ContractCreated | FunctionCall deriving(Eq, Show, Generic) |
||||
|
||||
--instance FromJSON EthenoEvent |
||||
|
||||
-- | A single initialization event |
||||
--data Etheno = Etheno { _event :: !EthenoEvent |
||||
-- , _address :: Maybe Addr |
||||
-- , _from :: Maybe Addr |
||||
-- , _to :: Maybe Addr |
||||
-- , _contractAddr :: Maybe Addr |
||||
-- , _gasUsed :: Maybe Integer |
||||
-- , _gasPrice :: Maybe Integer |
||||
-- , _initCode :: Maybe T.Text |
||||
-- , _value :: Maybe W256 |
||||
-- } deriving (Eq, Show, Generic) |
||||
|
||||
data Etheno = AccountCreated Addr |
||||
| ContractCreated Addr Addr Integer Integer ByteString W256 |
||||
| FunctionCall Addr Addr Integer Integer ByteString W256 |
||||
deriving (Eq, Show) |
||||
|
||||
--makeLenses ''Etheno |
||||
|
||||
instance FromJSON Etheno where |
||||
-- parseJSON = genericParseJSON $ defaultOptions {fieldLabelModifier = tail, omitNothingFields = True} |
||||
parseJSON = withObject "Etheno" $ \v -> do |
||||
(ev :: String) <- v .: "event" |
||||
case ev of |
||||
"AccountCreated" -> AccountCreated <$> v .: "address" |
||||
"ContractCreated" -> ContractCreated <$> v .: "from" |
||||
<*> v .: "contract_address" |
||||
<*> (read <$> (v .: "gas_used")) |
||||
<*> (read <$> (v .: "gas_price")) |
||||
<*> (decode <$> (v .: "data")) |
||||
<*> v .: "value" |
||||
"FunctionCall" -> FunctionCall <$> v .: "from" |
||||
<*> v .: "to" |
||||
<*> (read <$> (v .: "gas_used")) |
||||
<*> (read <$> (v .: "gas_price")) |
||||
<*> (decode <$> (v .: "data")) |
||||
<*> v .: "value" |
||||
_ -> M.fail "event should be one of \"AccountCreated\", \"ContractCreated\", or \"FunctionCall\"" |
||||
where decode :: T.Text -> ByteString |
||||
decode = decodeHex . encodeUtf8 . T.drop 2 |
||||
decodeHex = fst . BS16.decode |
||||
|
||||
|
||||
-- | Handler for parsing errors |
||||
data EthenoException = EthenoException String |
||||
|
||||
instance Show EthenoException where |
||||
show (EthenoException e) = "Error parsing Etheno initialization file: " ++ e |
||||
|
||||
instance Exception EthenoException |
||||
|
||||
|
||||
-- | Main function: takes a filepath where the initialization sequence lives and returns |
||||
-- | the initialized VM along with a list of Addr's to put in GenConf |
||||
loadEthenoBatch :: (MonadThrow m, MonadIO m) => [T.Text] -> FilePath -> m (VM, [Addr]) |
||||
loadEthenoBatch ts fp = do |
||||
bs <- liftIO $ eitherDecodeFileStrict fp |
||||
|
||||
case bs of |
||||
(Left e) -> throwM $ EthenoException e |
||||
(Right ethenoInit) -> do |
||||
-- | Separate out account creation txns to use later for config |
||||
let (accounts, txs) = partition (\case { AccountCreated{} -> True; _ -> False; }) ethenoInit |
||||
knownAddrs = map (\(AccountCreated a) -> a) accounts |
||||
|
||||
-- | Execute contract creations and initial transactions, |
||||
let blank = vmForEthrunCreation empty & env . contracts .~ fromList [] |
||||
cs = blank ^. env . contracts |
||||
initVM = foldM (execEthenoTxs ts) Nothing txs |
||||
|
||||
liftIO $ print (length cs) |
||||
-- liftIO $ print $ view contractcode <$> cs |
||||
liftIO $ putStrLn "---" |
||||
(addr, vm') <- runStateT initVM blank |
||||
let cs' = vm' ^. env . contracts |
||||
liftIO $ print (length cs') |
||||
-- liftIO $ print $ view contractcode <$> cs' |
||||
liftIO $ putStrLn "done loading" |
||||
liftIO $ print ts |
||||
case addr of |
||||
Nothing -> throwM $ EthenoException "Could not find contract with echidna tests" |
||||
Just a -> do |
||||
liftIO $ putStrLn $ "found echidna at " ++ show addr |
||||
vm <- execStateT (liftSH . loadContract $ a) vm' |
||||
return (vm, knownAddrs) |
||||
|
||||
|
||||
-- | Takes a list of Etheno transactions and loads them into the VM, returning the |
||||
-- | address containing echidna tests |
||||
execEthenoTxs :: (MonadState x m, Has VM x, MonadThrow m) => ByteString -> Addr -> Etheno -> m Addr |
||||
execEthenoTxs bs addr t = do |
||||
og <- get |
||||
setupEthenoTx t |
||||
res <- liftSH exec |
||||
case (res, t ^. event == ContractCreated) of |
||||
(Reversion, _) -> put og |
||||
(VMFailure x, _) -> vmExcept x |
||||
(VMSuccess bc, True) -> hasLens %= execState ( replaceCodeOfSelf (RuntimeCode bc) |
||||
>> loadContract (t ^. contractAddr)) |
||||
_ -> pure () |
||||
|
||||
-- See if current contract is the same as echidna test |
||||
if t ^. event == ContractCreated && encodeUtf8 (t ^. initCode) == bs |
||||
then return (t ^. contractAddr) |
||||
else return addr |
||||
|
||||
|
||||
-- | For an etheno txn, set up VM to execute txn |
||||
setupEthenoTx :: (MonadState x m, Has VM x) => Etheno -> m () |
||||
setupEthenoTx (Etheno e _ f t c _ _ d v) = S.state . runState . zoom hasLens . sequence_ $ |
||||
[ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff |
||||
, tx . origin .= f, state . caller .= f, state . callvalue .= w256 v, setup] where |
||||
bc = encodeUtf8 d |
||||
setup = case e of |
||||
AccountCreated -> pure () |
||||
ContractCreated -> assign (env . contracts . at c) (Just . initialContract . RuntimeCode $ bc) >> loadContract c |
||||
FunctionCall -> loadContract t >> state . calldata .= bc |
||||
-- | Takes a list of Etheno transactions and loads them into the VM, returning the |
||||
-- | address containing echidna tests |
||||
execEthenoTxs :: (MonadState x m, Has VM x, MonadThrow m) => [T.Text] -> Maybe Addr -> Etheno -> m (Maybe Addr) |
||||
execEthenoTxs ts addr t = do |
||||
og <- get |
||||
setupEthenoTx t |
||||
res <- liftSH exec |
||||
case (res, t) of |
||||
(Reversion, _) -> throwM $ EthenoException "Encountered reversion while setting up Etheno transactions" |
||||
(VMFailure x, _) -> vmExcept x >> return addr |
||||
(VMSuccess bc, |
||||
ContractCreated _ ca _ _ _ _) -> |
||||
-- See if current contract is the same as echidna test |
||||
case addr of |
||||
Just m -> return $ Just m |
||||
Nothing -> let txs = ts <&> \t -> Tx (Left (t, [])) ca ca 0 |
||||
go [] = return $ Just ca |
||||
go (x:xs) = execTx x >>= \case |
||||
Reversion -> return Nothing |
||||
_ -> go xs in |
||||
go txs |
||||
-- hasLens %= execState (replaceCodeOfSelf (RuntimeCode bc) >> loadContract ca) |
||||
_ -> return addr |
||||
--if t ^. event == ContractCreated && encodeUtf8 (fromJustt (t ^. initCode)) == bs |
||||
-- then return (fromJust (t ^. contractAddr)) |
||||
-- else return addr |
||||
|
||||
|
||||
-- | For an etheno txn, set up VM to execute txn |
||||
setupEthenoTx :: (MonadState x m, Has VM x) => Etheno -> m () |
||||
setupEthenoTx (AccountCreated _) = pure () |
||||
setupEthenoTx (ContractCreated f c _ _ d v) = S.state . runState . zoom hasLens . sequence_ $ |
||||
[ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff |
||||
, tx . origin .= f, state . caller .= f, state . callvalue .= w256 v, setup] |
||||
where setup = assign (env . contracts . at (traceShow c c)) (Just . initialContract . RuntimeCode $ trace ("bc: " ++ (unpack $ BS16.encode d)) d) |
||||
--setup = do |
||||
-- env . contracts . at c .= Just . initialContract . RuntimeCode . encodeUtf8 $ d |
||||
-- loadContract c |
||||
|
||||
setupEthenoTx (FunctionCall f t _ _ d v) = S.state . runState . zoom hasLens . sequence_ $ |
||||
[ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff |
||||
, tx . origin .= f, state . caller .= f, state . callvalue .= w256 v, setup] |
||||
where setup = loadContract (traceShow t t) >> state . calldata .= d |
||||
--setupEthenoTx FunctionCall{} = pure () |
||||
--setupEthenoTx (Etheno e _ f t c _ _ d v) = S.state . runState . zoom hasLens . sequence_ $ |
||||
-- [ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff |
||||
-- , tx . origin .= fromJust f, state . caller .= fromJust f, state . callvalue .= w256 v, setup] where |
||||
-- bc = encodeUtf8 (fromJust d) |
||||
-- setup = case e of |
||||
-- AccountCreated -> pure () |
||||
-- ContractCreated -> assign (env . contracts . at c) (Just . initialContract . RuntimeCode $ bc) >> loadContract (fromJust c) |
||||
-- FunctionCall -> loadContract (fromJust t) >> state . calldata .= bc |
||||
|
Loading…
Reference in new issue