hevm 0.50.0 → 0.50.1
raw patch · 28 files changed
+1063/−1817 lines, 28 filesdep +filemanipdep ~QuickCheckdep ~aesondep ~basesetup-changedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: filemanip
Dependency ranges changed: QuickCheck, aeson, base, base16-bytestring, binary, brick, bytestring, containers, cryptonite, data-dword, directory, filepath, here, lens, lens-aeson, mtl, parsec, process, regex-tdfa, temporary, text, time, vector, vty, witherable
API changes (from Hackage documentation)
- EVM.TestUtils: compileWithDSTest :: FilePath -> IO (Text, Text)
- EVM.TestUtils: debugDappTest :: FilePath -> RpcInfo -> IO ()
- EVM.TestUtils: runDappTest :: FilePath -> Text -> IO Bool
- EVM.TestUtils: runDappTestCustom :: FilePath -> Text -> Maybe Integer -> Bool -> RpcInfo -> IO Bool
- EVM.TestUtils: testOpts :: SolverGroup -> FilePath -> Text -> Text -> Maybe Integer -> Bool -> RpcInfo -> IO UnitTestOptions
- Paths_hevm: getBinDir :: IO FilePath
- Paths_hevm: getDataDir :: IO FilePath
- Paths_hevm: getDataFileName :: FilePath -> IO FilePath
- Paths_hevm: getDynLibDir :: IO FilePath
- Paths_hevm: getLibDir :: IO FilePath
- Paths_hevm: getLibexecDir :: IO FilePath
- Paths_hevm: getSysconfDir :: IO FilePath
- Paths_hevm: version :: Version
+ EVM: BadCheatCode :: Maybe Word32 -> Error
+ EVM: BadJumpDestination :: Error
+ EVM: BalanceTooLow :: W256 -> W256 -> Error
+ EVM: Block :: Addr -> Expr EWord -> W256 -> W256 -> Word64 -> W256 -> W256 -> FeeSchedule Word64 -> Block
+ EVM: Cache :: Map Addr Contract -> Map W256 (Map W256 W256) -> Map (CodeLocation, Int) Bool -> Cache
+ EVM: CallContext :: Addr -> Addr -> W256 -> W256 -> Expr EWord -> Maybe W256 -> Expr Buf -> (Map Addr Contract, Expr Storage) -> SubState -> FrameContext
+ EVM: CallDepthLimitReached :: Error
+ EVM: Case :: Bool -> BranchCondition
+ EVM: Choose :: Choose -> Error
+ EVM: Concrete :: StorageBase
+ EVM: ConcreteRuntimeCode :: ByteString -> RuntimeCode
+ EVM: ConcreteS :: StorageModel
+ EVM: Contract :: ContractCode -> W256 -> W256 -> Expr EWord -> Vector Int -> Vector (Int, Op) -> Bool -> Contract
+ EVM: CreationContext :: Addr -> Expr EWord -> Map Addr Contract -> SubState -> FrameContext
+ EVM: DeadPath :: Error
+ EVM: EntryTrace :: Text -> TraceData
+ EVM: Env :: Map Addr Contract -> W256 -> Expr Storage -> Map W256 (Map W256 W256) -> Map W256 ByteString -> Env
+ EVM: ErrorTrace :: Error -> TraceData
+ EVM: EventTrace :: Expr EWord -> Expr Buf -> [Expr EWord] -> TraceData
+ EVM: FFI :: [AbiValue] -> Error
+ EVM: Frame :: FrameContext -> FrameState -> Frame
+ EVM: FrameErrored :: Error -> FrameResult
+ EVM: FrameReturned :: Expr Buf -> FrameResult
+ EVM: FrameReverted :: Expr Buf -> FrameResult
+ EVM: FrameState :: Addr -> Addr -> ContractCode -> Int -> [Expr EWord] -> Expr Buf -> Word64 -> Expr Buf -> Expr EWord -> Expr EWord -> Word64 -> Expr Buf -> Bool -> FrameState
+ EVM: FrameTrace :: FrameContext -> TraceData
+ EVM: IllegalOverflow :: Error
+ EVM: Inconsistent :: BranchCondition
+ EVM: InconsistentU :: IsUnique a
+ EVM: InitCode :: ByteString -> Expr Buf -> ContractCode
+ EVM: InitialS :: StorageModel
+ EVM: InvalidFormat :: Error
+ EVM: InvalidMemoryAccess :: Error
+ EVM: MaxCodeSizeExceeded :: W256 -> W256 -> Error
+ EVM: Multiple :: IsUnique a
+ EVM: NonceOverflow :: Error
+ EVM: NotUnique :: Expr EWord -> Error
+ EVM: OutOfGas :: Word64 -> Word64 -> Error
+ EVM: PrecompileFailure :: Error
+ EVM: Query :: Query -> Error
+ EVM: QueryTrace :: Query -> TraceData
+ EVM: ReturnTrace :: Expr Buf -> FrameContext -> TraceData
+ EVM: Revert :: Expr Buf -> Error
+ EVM: RuntimeCode :: RuntimeCode -> ContractCode
+ EVM: SMTTimeout :: Error
+ EVM: SelfDestruction :: Error
+ EVM: StackLimitExceeded :: Error
+ EVM: StackUnderrun :: Error
+ EVM: StateChangeWhileStatic :: Error
+ EVM: SubState :: [Addr] -> [Addr] -> Set Addr -> Set (Addr, W256) -> [(Addr, Word64)] -> SubState
+ EVM: Symbolic :: StorageBase
+ EVM: SymbolicRuntimeCode :: Vector (Expr Byte) -> RuntimeCode
+ EVM: SymbolicS :: StorageModel
+ EVM: TimeoutU :: IsUnique a
+ EVM: Trace :: Int -> Contract -> TraceData -> Trace
+ EVM: TxState :: W256 -> Word64 -> W256 -> Addr -> Addr -> Expr EWord -> SubState -> Bool -> Map Addr Contract -> TxState
+ EVM: UnexpectedSymbolicArg :: Int -> String -> [Expr a] -> Error
+ EVM: Unique :: a -> IsUnique a
+ EVM: Unknown :: BranchCondition
+ EVM: UnrecognizedOpcode :: Word8 -> Error
+ EVM: VM :: Maybe VMResult -> FrameState -> [Frame] -> Env -> Block -> TxState -> [Expr Log] -> TreePos Empty Trace -> Cache -> Word64 -> Map CodeLocation Int -> [Prop] -> [Prop] -> Bool -> VM
+ EVM: VMFailure :: Error -> VMResult
+ EVM: VMOpts :: Contract -> (Expr Buf, [Prop]) -> StorageBase -> Expr EWord -> W256 -> Addr -> Expr EWord -> Addr -> Word64 -> Word64 -> W256 -> Expr EWord -> Addr -> W256 -> W256 -> Word64 -> W256 -> W256 -> FeeSchedule Word64 -> W256 -> Bool -> Map Addr [W256] -> Bool -> VMOpts
+ EVM: VMSuccess :: Expr Buf -> VMResult
+ EVM: [PleaseAskSMT] :: Expr EWord -> [Prop] -> (BranchCondition -> EVM ()) -> Query
+ EVM: [PleaseChoosePath] :: Expr EWord -> (Bool -> EVM ()) -> Choose
+ EVM: [PleaseDoFFI] :: [String] -> (ByteString -> EVM ()) -> Query
+ EVM: [PleaseFetchContract] :: Addr -> (Contract -> EVM ()) -> Query
+ EVM: [PleaseFetchSlot] :: Addr -> W256 -> (W256 -> EVM ()) -> Query
+ EVM: [_accessedAddresses] :: SubState -> Set Addr
+ EVM: [_accessedStorageKeys] :: SubState -> Set (Addr, W256)
+ EVM: [_allowFFI] :: VM -> Bool
+ EVM: [_balance] :: Contract -> W256
+ EVM: [_baseFee] :: Block -> W256
+ EVM: [_block] :: VM -> Block
+ EVM: [_burned] :: VM -> Word64
+ EVM: [_cache] :: VM -> Cache
+ EVM: [_calldata] :: FrameState -> Expr Buf
+ EVM: [_caller] :: FrameState -> Expr EWord
+ EVM: [_callvalue] :: FrameState -> Expr EWord
+ EVM: [_chainId] :: Env -> W256
+ EVM: [_codeContract] :: FrameState -> Addr
+ EVM: [_codeOps] :: Contract -> Vector (Int, Op)
+ EVM: [_code] :: FrameState -> ContractCode
+ EVM: [_codehash] :: Contract -> Expr EWord
+ EVM: [_coinbase] :: Block -> Addr
+ EVM: [_constraints] :: VM -> [Prop]
+ EVM: [_contract] :: FrameState -> Addr
+ EVM: [_contractcode] :: Contract -> ContractCode
+ EVM: [_contracts] :: Env -> Map Addr Contract
+ EVM: [_env] :: VM -> Env
+ EVM: [_external] :: Contract -> Bool
+ EVM: [_fetchedContracts] :: Cache -> Map Addr Contract
+ EVM: [_fetchedStorage] :: Cache -> Map W256 (Map W256 W256)
+ EVM: [_frameContext] :: Frame -> FrameContext
+ EVM: [_frameState] :: Frame -> FrameState
+ EVM: [_frames] :: VM -> [Frame]
+ EVM: [_gas] :: FrameState -> Word64
+ EVM: [_gaslimit] :: Block -> Word64
+ EVM: [_gasprice] :: TxState -> W256
+ EVM: [_isCreate] :: TxState -> Bool
+ EVM: [_iterations] :: VM -> Map CodeLocation Int
+ EVM: [_keccakEqs] :: VM -> [Prop]
+ EVM: [_logs] :: VM -> [Expr Log]
+ EVM: [_maxCodeSize] :: Block -> W256
+ EVM: [_memorySize] :: FrameState -> Word64
+ EVM: [_memory] :: FrameState -> Expr Buf
+ EVM: [_nonce] :: Contract -> W256
+ EVM: [_number] :: Block -> W256
+ EVM: [_opIxMap] :: Contract -> Vector Int
+ EVM: [_origStorage] :: Env -> Map W256 (Map W256 W256)
+ EVM: [_origin] :: TxState -> Addr
+ EVM: [_path] :: Cache -> Map (CodeLocation, Int) Bool
+ EVM: [_pc] :: FrameState -> Int
+ EVM: [_prevRandao] :: Block -> W256
+ EVM: [_refunds] :: SubState -> [(Addr, Word64)]
+ EVM: [_result] :: VM -> Maybe VMResult
+ EVM: [_returndata] :: FrameState -> Expr Buf
+ EVM: [_schedule] :: Block -> FeeSchedule Word64
+ EVM: [_selfdestructs] :: SubState -> [Addr]
+ EVM: [_sha3Crack] :: Env -> Map W256 ByteString
+ EVM: [_stack] :: FrameState -> [Expr EWord]
+ EVM: [_state] :: VM -> FrameState
+ EVM: [_static] :: FrameState -> Bool
+ EVM: [_storage] :: Env -> Expr Storage
+ EVM: [_substate] :: TxState -> SubState
+ EVM: [_timestamp] :: Block -> Expr EWord
+ EVM: [_toAddr] :: TxState -> Addr
+ EVM: [_touchedAccounts] :: SubState -> [Addr]
+ EVM: [_traceContract] :: Trace -> Contract
+ EVM: [_traceData] :: Trace -> TraceData
+ EVM: [_traceOpIx] :: Trace -> Int
+ EVM: [_traces] :: VM -> TreePos Empty Trace
+ EVM: [_txPriorityFee] :: TxState -> W256
+ EVM: [_txReversion] :: TxState -> Map Addr Contract
+ EVM: [_tx] :: VM -> TxState
+ EVM: [_txgaslimit] :: TxState -> Word64
+ EVM: [_value] :: TxState -> Expr EWord
+ EVM: [callContextAbi] :: FrameContext -> Maybe W256
+ EVM: [callContextCodehash] :: FrameContext -> Expr EWord
+ EVM: [callContextContext] :: FrameContext -> Addr
+ EVM: [callContextData] :: FrameContext -> Expr Buf
+ EVM: [callContextOffset] :: FrameContext -> W256
+ EVM: [callContextReversion] :: FrameContext -> (Map Addr Contract, Expr Storage)
+ EVM: [callContextSize] :: FrameContext -> W256
+ EVM: [callContextSubState] :: FrameContext -> SubState
+ EVM: [callContextTarget] :: FrameContext -> Addr
+ EVM: [creationContextAddress] :: FrameContext -> Addr
+ EVM: [creationContextCodehash] :: FrameContext -> Expr EWord
+ EVM: [creationContextReversion] :: FrameContext -> Map Addr Contract
+ EVM: [creationContextSubstate] :: FrameContext -> SubState
+ EVM: [vmoptAddress] :: VMOpts -> Addr
+ EVM: [vmoptAllowFFI] :: VMOpts -> Bool
+ EVM: [vmoptBaseFee] :: VMOpts -> W256
+ EVM: [vmoptBlockGaslimit] :: VMOpts -> Word64
+ EVM: [vmoptCalldata] :: VMOpts -> (Expr Buf, [Prop])
+ EVM: [vmoptCaller] :: VMOpts -> Expr EWord
+ EVM: [vmoptChainId] :: VMOpts -> W256
+ EVM: [vmoptCoinbase] :: VMOpts -> Addr
+ EVM: [vmoptContract] :: VMOpts -> Contract
+ EVM: [vmoptCreate] :: VMOpts -> Bool
+ EVM: [vmoptGas] :: VMOpts -> Word64
+ EVM: [vmoptGaslimit] :: VMOpts -> Word64
+ EVM: [vmoptGasprice] :: VMOpts -> W256
+ EVM: [vmoptMaxCodeSize] :: VMOpts -> W256
+ EVM: [vmoptNumber] :: VMOpts -> W256
+ EVM: [vmoptOrigin] :: VMOpts -> Addr
+ EVM: [vmoptPrevRandao] :: VMOpts -> W256
+ EVM: [vmoptPriorityFee] :: VMOpts -> W256
+ EVM: [vmoptSchedule] :: VMOpts -> FeeSchedule Word64
+ EVM: [vmoptStorageBase] :: VMOpts -> StorageBase
+ EVM: [vmoptTimestamp] :: VMOpts -> Expr EWord
+ EVM: [vmoptTxAccessList] :: VMOpts -> Map Addr [W256]
+ EVM: [vmoptValue] :: VMOpts -> Expr EWord
+ EVM: accessAccountForGas :: Addr -> EVM Bool
+ EVM: accessAndBurn :: Addr -> EVM () -> EVM ()
+ EVM: accessMemoryRange :: FeeSchedule Word64 -> W256 -> W256 -> EVM () -> EVM ()
+ EVM: accessMemoryWord :: FeeSchedule Word64 -> W256 -> EVM () -> EVM ()
+ EVM: accessStorage :: Addr -> Expr EWord -> (Expr EWord -> EVM ()) -> EVM ()
+ EVM: accessStorageForGas :: Addr -> Expr EWord -> EVM Bool
+ EVM: accessUnboundedMemoryRange :: FeeSchedule Word64 -> Word64 -> Word64 -> EVM () -> EVM ()
+ EVM: accessedAddresses :: Lens' SubState (Set Addr)
+ EVM: accessedStorageKeys :: Lens' SubState (Set (Addr, W256))
+ EVM: accountEmpty :: Contract -> Bool
+ EVM: accountExists :: Addr -> VM -> Bool
+ EVM: allButOne64th :: (Num a, Integral a) => a -> a
+ EVM: allowFFI :: Lens' VM Bool
+ EVM: asInteger :: ByteString -> Integer
+ EVM: balance :: Lens' Contract W256
+ EVM: baseFee :: Lens' Block W256
+ EVM: blankState :: FrameState
+ EVM: block :: Lens' VM Block
+ EVM: branch :: CodeLocation -> Expr EWord -> (Bool -> EVM ()) -> EVM ()
+ EVM: burn :: Word64 -> EVM () -> EVM ()
+ EVM: burned :: Lens' VM Word64
+ EVM: bytecode :: Getter Contract (Expr Buf)
+ EVM: cache :: Lens' VM Cache
+ EVM: callChecks :: (?op :: Word8) => Contract -> Word64 -> Addr -> Addr -> W256 -> W256 -> W256 -> W256 -> W256 -> [Expr EWord] -> (Word64 -> EVM ()) -> EVM ()
+ EVM: calldata :: Lens' FrameState (Expr 'Buf)
+ EVM: caller :: Lens' FrameState (Expr 'EWord)
+ EVM: callvalue :: Lens' FrameState (Expr 'EWord)
+ EVM: ceilDiv :: (Num a, Integral a) => a -> a -> a
+ EVM: chainId :: Lens' Env W256
+ EVM: cheat :: (?op :: Word8) => (W256, W256) -> (W256, W256) -> EVM ()
+ EVM: cheatActions :: Map Word32 CheatAction
+ EVM: cheatCode :: Addr
+ EVM: checkJump :: Int -> [Expr EWord] -> EVM ()
+ EVM: code :: Lens' FrameState ContractCode
+ EVM: codeContract :: Lens' FrameState Addr
+ EVM: codeOps :: Lens' Contract (Vector (Int, Op))
+ EVM: codehash :: Lens' Contract (Expr 'EWord)
+ EVM: codelen :: ContractCode -> Expr EWord
+ EVM: codeloc :: EVM CodeLocation
+ EVM: coinbase :: Lens' Block Addr
+ EVM: collision :: Maybe Contract -> Bool
+ EVM: concreteModexpGasFee :: ByteString -> Word64
+ EVM: constraints :: Lens' VM [Prop]
+ EVM: contract :: Lens' FrameState Addr
+ EVM: contractcode :: Lens' Contract ContractCode
+ EVM: contracts :: Lens' Env (Map Addr Contract)
+ EVM: copyBytesToMemory :: Expr Buf -> Expr EWord -> Expr EWord -> Expr EWord -> EVM ()
+ EVM: copyCallBytesToMemory :: Expr Buf -> Expr EWord -> Expr EWord -> Expr EWord -> EVM ()
+ EVM: costOfCall :: FeeSchedule Word64 -> Bool -> W256 -> Word64 -> Word64 -> Addr -> EVM (Word64, Word64)
+ EVM: costOfCreate :: FeeSchedule Word64 -> Word64 -> W256 -> (Word64, Word64)
+ EVM: costOfPrecompile :: FeeSchedule Word64 -> Addr -> Expr Buf -> Word64
+ EVM: create :: (?op :: Word8) => Addr -> Contract -> Word64 -> W256 -> [Expr EWord] -> Addr -> Expr Buf -> EVM ()
+ EVM: currentContract :: VM -> Maybe Contract
+ EVM: data Block
+ EVM: data BranchCondition
+ EVM: data Cache
+ EVM: data Choose
+ EVM: data Contract
+ EVM: data ContractCode
+ EVM: data Env
+ EVM: data Error
+ EVM: data Frame
+ EVM: data FrameContext
+ EVM: data FrameResult
+ EVM: data FrameState
+ EVM: data IsUnique a
+ EVM: data Query
+ EVM: data RuntimeCode
+ EVM: data StorageBase
+ EVM: data StorageModel
+ EVM: data SubState
+ EVM: data Trace
+ EVM: data TraceData
+ EVM: data TxState
+ EVM: data VM
+ EVM: data VMOpts
+ EVM: data VMResult
+ EVM: delegateCall :: (?op :: Word8) => Contract -> Word64 -> Expr EWord -> Expr EWord -> W256 -> W256 -> W256 -> W256 -> W256 -> [Expr EWord] -> (Addr -> EVM ()) -> EVM ()
+ EVM: env :: Lens' VM Env
+ EVM: ethsign :: PrivateKey -> Digest Keccak_256 -> Signature
+ EVM: exec1 :: EVM ()
+ EVM: executePrecompile :: (?op :: Word8) => Addr -> Word64 -> W256 -> W256 -> W256 -> W256 -> [Expr EWord] -> EVM ()
+ EVM: external :: Lens' Contract Bool
+ EVM: fetchAccount :: Addr -> (Contract -> EVM ()) -> EVM ()
+ EVM: fetchedContracts :: Lens' Cache (Map Addr Contract)
+ EVM: fetchedStorage :: Lens' Cache (Map W256 (Map W256 W256))
+ EVM: finalize :: EVM ()
+ EVM: finishFrame :: FrameResult -> EVM ()
+ EVM: forceConcrete :: Expr EWord -> String -> (W256 -> EVM ()) -> EVM ()
+ EVM: forceConcrete2 :: (Expr EWord, Expr EWord) -> String -> ((W256, W256) -> EVM ()) -> EVM ()
+ EVM: forceConcrete3 :: (Expr EWord, Expr EWord, Expr EWord) -> String -> ((W256, W256, W256) -> EVM ()) -> EVM ()
+ EVM: forceConcrete4 :: (Expr EWord, Expr EWord, Expr EWord, Expr EWord) -> String -> ((W256, W256, W256, W256) -> EVM ()) -> EVM ()
+ EVM: forceConcrete5 :: (Expr EWord, Expr EWord, Expr EWord, Expr EWord, Expr EWord) -> String -> ((W256, W256, W256, W256, W256) -> EVM ()) -> EVM ()
+ EVM: forceConcrete6 :: (Expr EWord, Expr EWord, Expr EWord, Expr EWord, Expr EWord, Expr EWord) -> String -> ((W256, W256, W256, W256, W256, W256) -> EVM ()) -> EVM ()
+ EVM: forceConcreteBuf :: Expr Buf -> String -> (ByteString -> EVM ()) -> EVM ()
+ EVM: frameContext :: Lens' Frame FrameContext
+ EVM: frameState :: Lens' Frame FrameState
+ EVM: frames :: Lens' VM [Frame]
+ EVM: gas :: Lens' FrameState Word64
+ EVM: gaslimit :: Lens' Block Word64
+ EVM: gasprice :: Lens' TxState W256
+ EVM: getCodeLocation :: VM -> CodeLocation
+ EVM: hashcode :: ContractCode -> Expr EWord
+ EVM: initialContract :: ContractCode -> Contract
+ EVM: insertTrace :: TraceData -> EVM ()
+ EVM: instance GHC.Base.Monoid EVM.Cache
+ EVM: instance GHC.Base.Semigroup EVM.Cache
+ EVM: instance GHC.Classes.Eq EVM.ContractCode
+ EVM: instance GHC.Classes.Eq EVM.RuntimeCode
+ EVM: instance GHC.Classes.Eq EVM.StorageBase
+ EVM: instance GHC.Classes.Ord EVM.ContractCode
+ EVM: instance GHC.Classes.Ord EVM.RuntimeCode
+ EVM: instance GHC.Read.Read EVM.StorageModel
+ EVM: instance GHC.Show.Show EVM.Block
+ EVM: instance GHC.Show.Show EVM.BranchCondition
+ EVM: instance GHC.Show.Show EVM.Cache
+ EVM: instance GHC.Show.Show EVM.Choose
+ EVM: instance GHC.Show.Show EVM.Contract
+ EVM: instance GHC.Show.Show EVM.ContractCode
+ EVM: instance GHC.Show.Show EVM.Env
+ EVM: instance GHC.Show.Show EVM.Error
+ EVM: instance GHC.Show.Show EVM.Frame
+ EVM: instance GHC.Show.Show EVM.FrameContext
+ EVM: instance GHC.Show.Show EVM.FrameResult
+ EVM: instance GHC.Show.Show EVM.FrameState
+ EVM: instance GHC.Show.Show EVM.Query
+ EVM: instance GHC.Show.Show EVM.RuntimeCode
+ EVM: instance GHC.Show.Show EVM.StorageBase
+ EVM: instance GHC.Show.Show EVM.StorageModel
+ EVM: instance GHC.Show.Show EVM.SubState
+ EVM: instance GHC.Show.Show EVM.Trace
+ EVM: instance GHC.Show.Show EVM.TraceData
+ EVM: instance GHC.Show.Show EVM.TxState
+ EVM: instance GHC.Show.Show EVM.VM
+ EVM: instance GHC.Show.Show EVM.VMOpts
+ EVM: instance GHC.Show.Show EVM.VMResult
+ EVM: instance GHC.Show.Show a => GHC.Show.Show (EVM.IsUnique a)
+ EVM: instance Options.Generic.ParseField EVM.StorageModel
+ EVM: isCreate :: Lens' TxState Bool
+ EVM: isZero :: W256 -> W256 -> ByteString -> Bool
+ EVM: iterations :: Lens' VM (Map CodeLocation Int)
+ EVM: keccakEqs :: Lens' VM [Prop]
+ EVM: lazySlice :: W256 -> W256 -> ByteString -> ByteString
+ EVM: limitStack :: Int -> EVM () -> EVM ()
+ EVM: loadContract :: Addr -> EVM ()
+ EVM: log2 :: FiniteBits b => b -> Int
+ EVM: logs :: Lens' VM [Expr 'Log]
+ EVM: makeVm :: VMOpts -> VM
+ EVM: maxCodeSize :: Lens' Block W256
+ EVM: memory :: Lens' FrameState (Expr 'Buf)
+ EVM: memoryCost :: FeeSchedule Word64 -> Word64 -> Word64
+ EVM: memorySize :: Lens' FrameState Word64
+ EVM: mkCodeOps :: ContractCode -> Vector (Int, Op)
+ EVM: mkOpIxMap :: ContractCode -> Vector Int
+ EVM: next :: (?op :: Word8) => EVM ()
+ EVM: nonce :: Lens' Contract W256
+ EVM: noop :: Monad m => m ()
+ EVM: notStatic :: EVM () -> EVM ()
+ EVM: number :: Lens' Block W256
+ EVM: opIxMap :: Lens' Contract (Vector Int)
+ EVM: opParams :: VM -> Map String (Expr EWord)
+ EVM: opSize :: Word8 -> Int
+ EVM: opslen :: ContractCode -> Int
+ EVM: origStorage :: Lens' Env (Map W256 (Map W256 W256))
+ EVM: origin :: Lens' TxState Addr
+ EVM: parseModexpLength :: ByteString -> (W256, W256, W256)
+ EVM: path :: Lens' Cache (Map (CodeLocation, Int) Bool)
+ EVM: pc :: Lens' FrameState Int
+ EVM: popTrace :: EVM ()
+ EVM: precompiledContract :: (?op :: Word8) => Contract -> Word64 -> Addr -> Addr -> W256 -> W256 -> W256 -> W256 -> W256 -> [Expr EWord] -> EVM ()
+ EVM: prevRandao :: Lens' Block W256
+ EVM: push :: W256 -> EVM ()
+ EVM: pushSym :: Expr EWord -> EVM ()
+ EVM: pushTo :: MonadState s m => ASetter s s [a] [a] -> a -> m ()
+ EVM: pushToSequence :: MonadState s m => ASetter s s (Seq a) (Seq a) -> a -> m ()
+ EVM: pushTrace :: TraceData -> EVM ()
+ EVM: readMemory :: Expr EWord -> Expr EWord -> VM -> Expr Buf
+ EVM: readOp :: Word8 -> [Expr Byte] -> Op
+ EVM: refund :: Word64 -> EVM ()
+ EVM: refunds :: Lens' SubState [(Addr, Word64)]
+ EVM: replaceCode :: Addr -> ContractCode -> EVM ()
+ EVM: replaceCodeOfSelf :: ContractCode -> EVM ()
+ EVM: resetState :: EVM ()
+ EVM: result :: Lens' VM (Maybe VMResult)
+ EVM: returndata :: Lens' FrameState (Expr 'Buf)
+ EVM: schedule :: Lens' Block (FeeSchedule Word64)
+ EVM: selfdestruct :: Addr -> EVM ()
+ EVM: selfdestructs :: Lens' SubState [Addr]
+ EVM: sha3Crack :: Lens' Env (Map W256 ByteString)
+ EVM: stack :: Lens' FrameState [Expr 'EWord]
+ EVM: stackOp1 :: (?op :: Word8) => (Expr EWord -> Word64) -> (Expr EWord -> Expr EWord) -> EVM ()
+ EVM: stackOp2 :: (?op :: Word8) => ((Expr EWord, Expr EWord) -> Word64) -> ((Expr EWord, Expr EWord) -> Expr EWord) -> EVM ()
+ EVM: stackOp3 :: (?op :: Word8) => ((Expr EWord, Expr EWord, Expr EWord) -> Word64) -> ((Expr EWord, Expr EWord, Expr EWord) -> Expr EWord) -> EVM ()
+ EVM: state :: Lens' VM FrameState
+ EVM: static :: Lens' FrameState Bool
+ EVM: storage :: Lens' Env (Expr 'Storage)
+ EVM: substate :: Lens' TxState SubState
+ EVM: timestamp :: Lens' Block (Expr 'EWord)
+ EVM: toAddr :: Lens' TxState Addr
+ EVM: toBuf :: ContractCode -> Expr Buf
+ EVM: touchAccount :: Addr -> EVM ()
+ EVM: touchedAccounts :: Lens' SubState [Addr]
+ EVM: traceContract :: Lens' Trace Contract
+ EVM: traceData :: Lens' Trace TraceData
+ EVM: traceForest :: VM -> Forest Trace
+ EVM: traceOpIx :: Lens' Trace Int
+ EVM: traceTopLog :: MonadState VM m => [Expr Log] -> m ()
+ EVM: traces :: Lens' VM (TreePos Empty Trace)
+ EVM: transfer :: Addr -> Addr -> W256 -> EVM ()
+ EVM: truncpadlit :: Int -> ByteString -> ByteString
+ EVM: tx :: Lens' VM TxState
+ EVM: txPriorityFee :: Lens' TxState W256
+ EVM: txReversion :: Lens' TxState (Map Addr Contract)
+ EVM: txgaslimit :: Lens' TxState Word64
+ EVM: type CheatAction = Expr EWord -> Expr EWord -> Expr Buf -> EVM ()
+ EVM: type CodeLocation = (Addr, Int)
+ EVM: type EVM a = State VM a
+ EVM: unRefund :: Word64 -> EVM ()
+ EVM: underrun :: EVM ()
+ EVM: unifyCachedContract :: Contract -> Contract -> Contract
+ EVM: unifyCachedStorage :: Map W256 W256 -> Map W256 W256 -> Map W256 W256
+ EVM: value :: Lens' TxState (Expr 'EWord)
+ EVM: vmError :: Error -> EVM ()
+ EVM: vmOp :: VM -> Maybe Op
+ EVM: vmOpIx :: VM -> Maybe Int
+ EVM: withTraceLocation :: MonadState VM m => TraceData -> m Trace
+ EVM: zipperRootForest :: TreePos Empty a -> Forest a
+ EVM.ABI: AbiAddress :: Addr -> AbiValue
+ EVM.ABI: AbiAddressType :: AbiType
+ EVM.ABI: AbiArray :: Int -> AbiType -> Vector AbiValue -> AbiValue
+ EVM.ABI: AbiArrayDynamic :: AbiType -> Vector AbiValue -> AbiValue
+ EVM.ABI: AbiArrayDynamicType :: AbiType -> AbiType
+ EVM.ABI: AbiArrayType :: Int -> AbiType -> AbiType
+ EVM.ABI: AbiBool :: Bool -> AbiValue
+ EVM.ABI: AbiBoolType :: AbiType
+ EVM.ABI: AbiBytes :: Int -> ByteString -> AbiValue
+ EVM.ABI: AbiBytesDynamic :: ByteString -> AbiValue
+ EVM.ABI: AbiBytesDynamicType :: AbiType
+ EVM.ABI: AbiBytesType :: Int -> AbiType
+ EVM.ABI: AbiInt :: Int -> Int256 -> AbiValue
+ EVM.ABI: AbiIntType :: Int -> AbiType
+ EVM.ABI: AbiString :: ByteString -> AbiValue
+ EVM.ABI: AbiStringType :: AbiType
+ EVM.ABI: AbiTuple :: Vector AbiValue -> AbiValue
+ EVM.ABI: AbiTupleType :: Vector AbiType -> AbiType
+ EVM.ABI: AbiUInt :: Int -> Word256 -> AbiValue
+ EVM.ABI: AbiUIntType :: Int -> AbiType
+ EVM.ABI: Anonymous :: Anonymity
+ EVM.ABI: CAbi :: [AbiValue] -> AbiVals
+ EVM.ABI: Dynamic :: AbiKind
+ EVM.ABI: Event :: Text -> Anonymity -> [(Text, AbiType, Indexed)] -> Event
+ EVM.ABI: Indexed :: Indexed
+ EVM.ABI: NoVals :: AbiVals
+ EVM.ABI: NotAnonymous :: Anonymity
+ EVM.ABI: NotIndexed :: Indexed
+ EVM.ABI: SAbi :: [Expr EWord] -> AbiVals
+ EVM.ABI: SolError :: Text -> [AbiType] -> SolError
+ EVM.ABI: Static :: AbiKind
+ EVM.ABI: abiKind :: AbiType -> AbiKind
+ EVM.ABI: abiMethod :: Text -> AbiValue -> ByteString
+ EVM.ABI: abiTypeSolidity :: AbiType -> Text
+ EVM.ABI: abiValueType :: AbiValue -> AbiType
+ EVM.ABI: data AbiKind
+ EVM.ABI: data AbiType
+ EVM.ABI: data AbiVals
+ EVM.ABI: data AbiValue
+ EVM.ABI: data Anonymity
+ EVM.ABI: data Event
+ EVM.ABI: data Indexed
+ EVM.ABI: data SolError
+ EVM.ABI: decodeAbiValue :: AbiType -> ByteString -> AbiValue
+ EVM.ABI: decodeBuf :: [AbiType] -> Expr Buf -> AbiVals
+ EVM.ABI: decodeStaticArgs :: Int -> Int -> Expr Buf -> [Expr EWord]
+ EVM.ABI: emptyAbi :: AbiValue
+ EVM.ABI: encodeAbiValue :: AbiValue -> ByteString
+ EVM.ABI: formatString :: ByteString -> String
+ EVM.ABI: genAbiValue :: AbiType -> Gen AbiValue
+ EVM.ABI: getAbi :: AbiType -> Get AbiValue
+ EVM.ABI: getAbiSeq :: Int -> [AbiType] -> Get (Vector AbiValue)
+ EVM.ABI: instance GHC.Classes.Eq EVM.ABI.AbiKind
+ EVM.ABI: instance GHC.Classes.Eq EVM.ABI.AbiType
+ EVM.ABI: instance GHC.Classes.Eq EVM.ABI.AbiValue
+ EVM.ABI: instance GHC.Classes.Eq EVM.ABI.Anonymity
+ EVM.ABI: instance GHC.Classes.Eq EVM.ABI.Event
+ EVM.ABI: instance GHC.Classes.Eq EVM.ABI.Indexed
+ EVM.ABI: instance GHC.Classes.Eq EVM.ABI.SolError
+ EVM.ABI: instance GHC.Classes.Ord EVM.ABI.AbiKind
+ EVM.ABI: instance GHC.Classes.Ord EVM.ABI.AbiType
+ EVM.ABI: instance GHC.Classes.Ord EVM.ABI.AbiValue
+ EVM.ABI: instance GHC.Classes.Ord EVM.ABI.Anonymity
+ EVM.ABI: instance GHC.Classes.Ord EVM.ABI.Event
+ EVM.ABI: instance GHC.Classes.Ord EVM.ABI.Indexed
+ EVM.ABI: instance GHC.Classes.Ord EVM.ABI.SolError
+ EVM.ABI: instance GHC.Generics.Generic EVM.ABI.AbiKind
+ EVM.ABI: instance GHC.Generics.Generic EVM.ABI.AbiType
+ EVM.ABI: instance GHC.Generics.Generic EVM.ABI.AbiValue
+ EVM.ABI: instance GHC.Generics.Generic EVM.ABI.Anonymity
+ EVM.ABI: instance GHC.Generics.Generic EVM.ABI.Event
+ EVM.ABI: instance GHC.Generics.Generic EVM.ABI.Indexed
+ EVM.ABI: instance GHC.Generics.Generic EVM.ABI.SolError
+ EVM.ABI: instance GHC.Read.Read EVM.ABI.AbiKind
+ EVM.ABI: instance GHC.Read.Read EVM.ABI.AbiType
+ EVM.ABI: instance GHC.Read.Read EVM.ABI.AbiValue
+ EVM.ABI: instance GHC.Read.Read EVM.ABI.Boolz
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.AbiKind
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.AbiType
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.AbiVals
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.AbiValue
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.Anonymity
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.Event
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.Indexed
+ EVM.ABI: instance GHC.Show.Show EVM.ABI.SolError
+ EVM.ABI: instance Test.QuickCheck.Arbitrary.Arbitrary EVM.ABI.AbiType
+ EVM.ABI: instance Test.QuickCheck.Arbitrary.Arbitrary EVM.ABI.AbiValue
+ EVM.ABI: makeAbiValue :: AbiType -> String -> AbiValue
+ EVM.ABI: parseAbiValue :: AbiType -> ReadP AbiValue
+ EVM.ABI: parseTypeName :: Vector AbiType -> Text -> Maybe AbiType
+ EVM.ABI: putAbi :: AbiValue -> Put
+ EVM.ABI: selector :: Text -> ByteString
+ EVM.CSE: eliminateExpr :: Expr a -> (Expr a, BufEnv, StoreEnv)
+ EVM.CSE: eliminateProps :: [Prop] -> ([Prop], BufEnv, StoreEnv)
+ EVM.CSE: instance GHC.Show.Show EVM.CSE.BuilderState
+ EVM.CSE: type BufEnv = Map Int (Expr Buf)
+ EVM.CSE: type StoreEnv = Map Int (Expr Storage)
+ EVM.Concrete: (^) :: W256 -> W256 -> W256
+ EVM.Concrete: byteStringSliceWithDefaultZeroes :: Int -> Int -> ByteString -> ByteString
+ EVM.Concrete: create2Address :: Addr -> W256 -> ByteString -> Addr
+ EVM.Concrete: createAddress :: Addr -> W256 -> Addr
+ EVM.Concrete: readByteOrZero :: Int -> ByteString -> Word8
+ EVM.Concrete: sliceMemory :: (Integral a, Integral b) => a -> b -> ByteString -> ByteString
+ EVM.Concrete: wordAt :: Int -> ByteString -> W256
+ EVM.Concrete: writeMemory :: ByteString -> W256 -> W256 -> W256 -> ByteString -> ByteString
+ EVM.Dapp: Code :: ByteString -> [Reference] -> Code
+ EVM.Dapp: ConcreteTest :: Text -> Test
+ EVM.Dapp: DappContext :: DappInfo -> Map Addr Contract -> DappContext
+ EVM.Dapp: DappInfo :: FilePath -> Map Text SolcContract -> Map W256 (CodeType, SolcContract) -> [(Code, SolcContract)] -> SourceCache -> [(Text, [(Test, [AbiType])])] -> Map Word32 Method -> Map W256 Event -> Map W256 SolError -> Map Int Value -> (SrcMap -> Maybe Value) -> DappInfo
+ EVM.Dapp: InvariantTest :: Text -> Test
+ EVM.Dapp: SymbolicTest :: Text -> Test
+ EVM.Dapp: [_contextEnv] :: DappContext -> Map Addr Contract
+ EVM.Dapp: [_contextInfo] :: DappContext -> DappInfo
+ EVM.Dapp: [_dappAbiMap] :: DappInfo -> Map Word32 Method
+ EVM.Dapp: [_dappAstIdMap] :: DappInfo -> Map Int Value
+ EVM.Dapp: [_dappAstSrcMap] :: DappInfo -> SrcMap -> Maybe Value
+ EVM.Dapp: [_dappErrorMap] :: DappInfo -> Map W256 SolError
+ EVM.Dapp: [_dappEventMap] :: DappInfo -> Map W256 Event
+ EVM.Dapp: [_dappRoot] :: DappInfo -> FilePath
+ EVM.Dapp: [_dappSolcByCode] :: DappInfo -> [(Code, SolcContract)]
+ EVM.Dapp: [_dappSolcByHash] :: DappInfo -> Map W256 (CodeType, SolcContract)
+ EVM.Dapp: [_dappSolcByName] :: DappInfo -> Map Text SolcContract
+ EVM.Dapp: [_dappSources] :: DappInfo -> SourceCache
+ EVM.Dapp: [_dappUnitTests] :: DappInfo -> [(Text, [(Test, [AbiType])])]
+ EVM.Dapp: [immutableLocations] :: Code -> [Reference]
+ EVM.Dapp: [raw] :: Code -> ByteString
+ EVM.Dapp: compareCode :: ByteString -> Code -> Bool
+ EVM.Dapp: contextEnv :: Lens' DappContext (Map Addr Contract)
+ EVM.Dapp: contextInfo :: Lens' DappContext DappInfo
+ EVM.Dapp: dappAbiMap :: Lens' DappInfo (Map Word32 Method)
+ EVM.Dapp: dappAstIdMap :: Lens' DappInfo (Map Int Value)
+ EVM.Dapp: dappAstSrcMap :: Lens' DappInfo (SrcMap -> Maybe Value)
+ EVM.Dapp: dappErrorMap :: Lens' DappInfo (Map W256 SolError)
+ EVM.Dapp: dappEventMap :: Lens' DappInfo (Map W256 Event)
+ EVM.Dapp: dappInfo :: FilePath -> Map Text SolcContract -> SourceCache -> DappInfo
+ EVM.Dapp: dappRoot :: Lens' DappInfo FilePath
+ EVM.Dapp: dappSolcByCode :: Lens' DappInfo [(Code, SolcContract)]
+ EVM.Dapp: dappSolcByHash :: Lens' DappInfo (Map W256 (CodeType, SolcContract))
+ EVM.Dapp: dappSolcByName :: Lens' DappInfo (Map Text SolcContract)
+ EVM.Dapp: dappSources :: Lens' DappInfo SourceCache
+ EVM.Dapp: dappUnitTests :: Lens' DappInfo [(Text, [(Test, [AbiType])])]
+ EVM.Dapp: data Code
+ EVM.Dapp: data DappContext
+ EVM.Dapp: data DappInfo
+ EVM.Dapp: data Test
+ EVM.Dapp: emptyDapp :: DappInfo
+ EVM.Dapp: extractSig :: Test -> Text
+ EVM.Dapp: findAllUnitTests :: [SolcContract] -> [(Text, [(Test, [AbiType])])]
+ EVM.Dapp: findSrc :: Contract -> DappInfo -> Maybe SolcContract
+ EVM.Dapp: findUnitTests :: Text -> [SolcContract] -> [(Text, [(Test, [AbiType])])]
+ EVM.Dapp: instance GHC.Show.Show EVM.Dapp.Code
+ EVM.Dapp: instance GHC.Show.Show EVM.Dapp.Test
+ EVM.Dapp: lookupCode :: ContractCode -> DappInfo -> Maybe SolcContract
+ EVM.Dapp: mkTest :: Text -> Maybe Test
+ EVM.Dapp: showTraceLocation :: DappInfo -> Trace -> Either Text Text
+ EVM.Dapp: srcMap :: DappInfo -> Contract -> Int -> Maybe SrcMap
+ EVM.Dapp: traceSrcMap :: DappInfo -> Trace -> Maybe SrcMap
+ EVM.Dapp: unitTestMarkerAbi :: Word32
+ EVM.Dapp: unitTestMethods :: SolcContract -> [(Test, [AbiType])]
+ EVM.Dapp: unitTestMethodsFiltered :: (Text -> Bool) -> SolcContract -> [(Test, [AbiType])]
+ EVM.Debug: Debug :: Mode
+ EVM.Debug: JsonTrace :: Mode
+ EVM.Debug: Run :: Mode
+ EVM.Debug: data Mode
+ EVM.Debug: instance GHC.Classes.Eq EVM.Debug.Mode
+ EVM.Debug: instance GHC.Show.Show EVM.Debug.Mode
+ EVM.Debug: object :: [(Doc, Doc)] -> Doc
+ EVM.Debug: prettyContract :: Contract -> Doc
+ EVM.Debug: prettyContracts :: Map Addr Contract -> Doc
+ EVM.Debug: srcMapCode :: SourceCache -> SrcMap -> Maybe ByteString
+ EVM.Debug: srcMapCodePos :: SourceCache -> SrcMap -> Maybe (Text, Int)
+ EVM.Demand: demand :: (MonadIO m, NFData a) => a -> m ()
+ EVM.Dev: analyzeDai :: IO ()
+ EVM.Dev: analyzeDeposit :: IO ()
+ EVM.Dev: analyzeVat :: IO ()
+ EVM.Dev: buildExpr :: SolverGroup -> ByteString -> IO (Expr End)
+ EVM.Dev: checkEquiv :: Typeable a => Expr a -> Expr a -> IO ()
+ EVM.Dev: dai :: IO ByteString
+ EVM.Dev: daiExpr :: IO (Expr End)
+ EVM.Dev: doTest :: IO ()
+ EVM.Dev: initVm :: ByteString -> VM
+ EVM.Dev: reachable' :: Bool -> ByteString -> IO ()
+ EVM.Dev: runDappTest :: FilePath -> IO ()
+ EVM.Dev: safeAdd :: IO ByteString
+ EVM.Dev: showExpr :: ByteString -> IO ()
+ EVM.Dev: summaryStore :: IO ByteString
+ EVM.Dev: testContract :: IO ByteString
+ EVM.Dev: testOpts :: SolverGroup -> FilePath -> FilePath -> IO UnitTestOptions
+ EVM.Dev: vat :: IO ByteString
+ EVM.Exec: ethrunAddress :: Addr
+ EVM.Exec: exec :: MonadState VM m => m VMResult
+ EVM.Exec: execWhile :: MonadState VM m => (VM -> Bool) -> m Int
+ EVM.Exec: run :: MonadState VM m => m VM
+ EVM.Exec: vmForEthrunCreation :: ByteString -> VM
+ EVM.Expr: add :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: addmod :: Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: allLit :: [Expr Byte] -> Bool
+ EVM.Expr: and :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: bufLength :: Expr Buf -> Expr EWord
+ EVM.Expr: bytesToW256 :: [Word8] -> W256
+ EVM.Expr: concPrefix :: Expr Buf -> Maybe Integer
+ EVM.Expr: copySlice :: Expr EWord -> Expr EWord -> Expr EWord -> Expr Buf -> Expr Buf -> Expr Buf
+ EVM.Expr: div :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: drop :: W256 -> Expr Buf -> Expr Buf
+ EVM.Expr: eq :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: eqByte :: Expr Byte -> Expr Byte -> Expr EWord
+ EVM.Expr: exp :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: fromList :: Vector (Expr Byte) -> Expr Buf
+ EVM.Expr: geq :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: gt :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: indexWord :: Expr EWord -> Expr EWord -> Expr Byte
+ EVM.Expr: instance GHC.Base.Monoid (EVM.Types.Expr 'EVM.Types.Buf)
+ EVM.Expr: instance GHC.Base.Semigroup (EVM.Types.Expr 'EVM.Types.Buf)
+ EVM.Expr: isLitByte :: Expr Byte -> Bool
+ EVM.Expr: isLitWord :: Expr EWord -> Bool
+ EVM.Expr: iszero :: Expr EWord -> Expr EWord
+ EVM.Expr: joinBytes :: [Expr Byte] -> Expr EWord
+ EVM.Expr: leq :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: litAddr :: Addr -> Expr EWord
+ EVM.Expr: litCode :: ByteString -> [Expr Byte]
+ EVM.Expr: lt :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: maxBytes :: W256
+ EVM.Expr: min :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: mod :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: mul :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: mulmod :: Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: normArgs :: (Expr EWord -> Expr EWord -> Expr EWord) -> (W256 -> W256 -> W256) -> Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: not :: Expr EWord -> Expr EWord
+ EVM.Expr: numBranches :: Expr End -> Int
+ EVM.Expr: op1 :: (Expr EWord -> Expr EWord) -> (W256 -> W256) -> Expr EWord -> Expr EWord
+ EVM.Expr: op2 :: (Expr EWord -> Expr EWord -> Expr EWord) -> (W256 -> W256 -> W256) -> Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: op3 :: (Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord) -> (W256 -> W256 -> W256 -> W256) -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: or :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: padByte :: Expr Byte -> Expr EWord
+ EVM.Expr: padBytesLeft :: Int -> [Expr Byte] -> [Expr Byte]
+ EVM.Expr: readByte :: Expr EWord -> Expr Buf -> Expr Byte
+ EVM.Expr: readBytes :: Int -> Expr EWord -> Expr Buf -> Expr EWord
+ EVM.Expr: readStorage :: Expr EWord -> Expr EWord -> Expr Storage -> Maybe (Expr EWord)
+ EVM.Expr: readStorage' :: Expr EWord -> Expr EWord -> Expr Storage -> Expr EWord
+ EVM.Expr: readWord :: Expr EWord -> Expr Buf -> Expr EWord
+ EVM.Expr: readWordFromBytes :: Expr EWord -> Expr Buf -> Expr EWord
+ EVM.Expr: sar :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: sdiv :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: sex :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: sgt :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: shl :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: shr :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: simplify :: Expr a -> Expr a
+ EVM.Expr: simplifyReads :: Expr a -> Expr a
+ EVM.Expr: slice :: Expr EWord -> Expr EWord -> Expr Buf -> Expr Buf
+ EVM.Expr: slt :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: smod :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: stripWrites :: W256 -> W256 -> Expr Buf -> Expr Buf
+ EVM.Expr: sub :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Expr: take :: W256 -> Expr Buf -> Expr Buf
+ EVM.Expr: to512 :: W256 -> Word512
+ EVM.Expr: toList :: Expr Buf -> Maybe (Vector (Expr Byte))
+ EVM.Expr: word256At :: Functor f => Expr EWord -> (Expr EWord -> f (Expr EWord)) -> Expr Buf -> f (Expr Buf)
+ EVM.Expr: writeByte :: Expr EWord -> Expr Byte -> Expr Buf -> Expr Buf
+ EVM.Expr: writeStorage :: Expr EWord -> Expr EWord -> Expr EWord -> Expr Storage -> Expr Storage
+ EVM.Expr: writeWord :: Expr EWord -> Expr EWord -> Expr Buf -> Expr Buf
+ EVM.Expr: xor :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Facts: BalanceFact :: Addr -> W256 -> Fact
+ EVM.Facts: CodeFact :: Addr -> ByteString -> Fact
+ EVM.Facts: Data :: ASCII -> Data
+ EVM.Facts: File :: Path -> Data -> File
+ EVM.Facts: NonceFact :: Addr -> W256 -> Fact
+ EVM.Facts: Path :: [ASCII] -> ASCII -> Path
+ EVM.Facts: StorageFact :: Addr -> W256 -> W256 -> Fact
+ EVM.Facts: [addr] :: Fact -> Addr
+ EVM.Facts: [blob] :: Fact -> ByteString
+ EVM.Facts: [dataASCII] :: Data -> ASCII
+ EVM.Facts: [fileData] :: File -> Data
+ EVM.Facts: [filePath] :: File -> Path
+ EVM.Facts: [what] :: Fact -> W256
+ EVM.Facts: [which] :: Fact -> W256
+ EVM.Facts: apply :: VM -> Set Fact -> VM
+ EVM.Facts: applyCache :: VM -> Set Fact -> VM
+ EVM.Facts: cacheFacts :: Cache -> Set Fact
+ EVM.Facts: contractFacts :: Addr -> Contract -> Map W256 (Map W256 W256) -> [Fact]
+ EVM.Facts: data Fact
+ EVM.Facts: data File
+ EVM.Facts: data Path
+ EVM.Facts: factToFile :: Fact -> File
+ EVM.Facts: fileToFact :: File -> Maybe Fact
+ EVM.Facts: instance EVM.Facts.AsASCII Data.ByteString.Internal.ByteString
+ EVM.Facts: instance EVM.Facts.AsASCII EVM.Types.Addr
+ EVM.Facts: instance EVM.Facts.AsASCII EVM.Types.W256
+ EVM.Facts: instance GHC.Classes.Eq EVM.Facts.Data
+ EVM.Facts: instance GHC.Classes.Eq EVM.Facts.Fact
+ EVM.Facts: instance GHC.Classes.Eq EVM.Facts.File
+ EVM.Facts: instance GHC.Classes.Eq EVM.Facts.Path
+ EVM.Facts: instance GHC.Classes.Ord EVM.Facts.Data
+ EVM.Facts: instance GHC.Classes.Ord EVM.Facts.Fact
+ EVM.Facts: instance GHC.Classes.Ord EVM.Facts.File
+ EVM.Facts: instance GHC.Classes.Ord EVM.Facts.Path
+ EVM.Facts: instance GHC.Show.Show EVM.Facts.Data
+ EVM.Facts: instance GHC.Show.Show EVM.Facts.Fact
+ EVM.Facts: instance GHC.Show.Show EVM.Facts.File
+ EVM.Facts: instance GHC.Show.Show EVM.Facts.Path
+ EVM.Facts: newtype Data
+ EVM.Facts: vmFacts :: VM -> Set Fact
+ EVM.Facts.Git: RepoAt :: String -> RepoAt
+ EVM.Facts.Git: instance GHC.Classes.Eq EVM.Facts.Git.RepoAt
+ EVM.Facts.Git: instance GHC.Classes.Ord EVM.Facts.Git.RepoAt
+ EVM.Facts.Git: instance GHC.Show.Show EVM.Facts.Git.RepoAt
+ EVM.Facts.Git: loadFacts :: RepoAt -> IO (Set Fact)
+ EVM.Facts.Git: newtype RepoAt
+ EVM.Facts.Git: saveFacts :: RepoAt -> Set Fact -> IO ()
+ EVM.FeeSchedule: FeeSchedule :: n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> n -> FeeSchedule n
+ EVM.FeeSchedule: [g_access_list_address] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_access_list_storage_key] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_balance] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_base] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_blockhash] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_call] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_callstipend] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_callvalue] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_codedeposit] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_cold_account_access] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_cold_sload] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_copy] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_create] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_ecadd] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_ecmul] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_exp] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_expbyte] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_extcode] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_extcodehash] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_fround] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_high] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_jumpdest] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_log] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_logdata] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_logtopic] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_low] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_memory] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_mid] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_newaccount] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_pairing_base] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_pairing_point] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_quaddivisor] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_selfdestruct] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_selfdestruct_newaccount] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_sha3] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_sha3word] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_sload] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_sreset] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_sset] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_transaction] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_txcreate] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_txdatanonzero] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_txdatazero] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_verylow] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_warm_storage_read] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [g_zero] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [r_block] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [r_sclear] :: FeeSchedule n -> n
+ EVM.FeeSchedule: [r_selfdestruct] :: FeeSchedule n -> n
+ EVM.FeeSchedule: berlin :: Num n => FeeSchedule n
+ EVM.FeeSchedule: data FeeSchedule n
+ EVM.FeeSchedule: eip1108 :: EIP n
+ EVM.FeeSchedule: eip150 :: EIP n
+ EVM.FeeSchedule: eip160 :: EIP n
+ EVM.FeeSchedule: eip1884 :: EIP n
+ EVM.FeeSchedule: eip2028 :: EIP n
+ EVM.FeeSchedule: eip2200 :: EIP n
+ EVM.FeeSchedule: eip2929 :: EIP n
+ EVM.FeeSchedule: homestead :: Num n => FeeSchedule n
+ EVM.FeeSchedule: instance GHC.Show.Show n => GHC.Show.Show (EVM.FeeSchedule.FeeSchedule n)
+ EVM.FeeSchedule: istanbul :: Num n => FeeSchedule n
+ EVM.FeeSchedule: metropolis :: Num n => FeeSchedule n
+ EVM.FeeSchedule: type EIP n = Num n => FeeSchedule n -> FeeSchedule n
+ EVM.Fetch: BlockNumber :: W256 -> BlockNumber
+ EVM.Fetch: Latest :: BlockNumber
+ EVM.Fetch: [QueryBalance] :: Addr -> RpcQuery W256
+ EVM.Fetch: [QueryBlock] :: RpcQuery Block
+ EVM.Fetch: [QueryChainId] :: RpcQuery W256
+ EVM.Fetch: [QueryCode] :: Addr -> RpcQuery ByteString
+ EVM.Fetch: [QueryNonce] :: Addr -> RpcQuery W256
+ EVM.Fetch: [QuerySlot] :: Addr -> W256 -> RpcQuery W256
+ EVM.Fetch: checkBranch :: SolverGroup -> Prop -> Prop -> IO BranchCondition
+ EVM.Fetch: class ToRPC a
+ EVM.Fetch: data BlockNumber
+ EVM.Fetch: data RpcQuery a
+ EVM.Fetch: fetchBlockFrom :: BlockNumber -> Text -> IO (Maybe Block)
+ EVM.Fetch: fetchBlockWithSession :: BlockNumber -> Text -> Session -> IO (Maybe Block)
+ EVM.Fetch: fetchContractFrom :: BlockNumber -> Text -> Addr -> IO (Maybe Contract)
+ EVM.Fetch: fetchContractWithSession :: BlockNumber -> Text -> Addr -> Session -> IO (Maybe Contract)
+ EVM.Fetch: fetchQuery :: Show a => BlockNumber -> (Value -> IO (Maybe Value)) -> RpcQuery a -> IO (Maybe a)
+ EVM.Fetch: fetchSlotFrom :: BlockNumber -> Text -> Addr -> W256 -> IO (Maybe W256)
+ EVM.Fetch: fetchSlotWithSession :: BlockNumber -> Text -> Session -> Addr -> W256 -> IO (Maybe W256)
+ EVM.Fetch: fetchWithSession :: Text -> Session -> Value -> IO (Maybe Value)
+ EVM.Fetch: http :: Natural -> Maybe Natural -> BlockNumber -> Text -> Fetcher
+ EVM.Fetch: instance EVM.Fetch.ToRPC EVM.Fetch.BlockNumber
+ EVM.Fetch: instance EVM.Fetch.ToRPC EVM.Types.Addr
+ EVM.Fetch: instance EVM.Fetch.ToRPC EVM.Types.W256
+ EVM.Fetch: instance EVM.Fetch.ToRPC GHC.Types.Bool
+ EVM.Fetch: instance GHC.Classes.Eq EVM.Fetch.BlockNumber
+ EVM.Fetch: instance GHC.Show.Show (EVM.Fetch.RpcQuery a)
+ EVM.Fetch: instance GHC.Show.Show EVM.Fetch.BlockNumber
+ EVM.Fetch: oracle :: SolverGroup -> RpcInfo -> Fetcher
+ EVM.Fetch: parseBlock :: (AsValue s, Show s) => s -> Maybe Block
+ EVM.Fetch: readText :: Read a => Text -> a
+ EVM.Fetch: rpc :: String -> [Value] -> Value
+ EVM.Fetch: toRPC :: ToRPC a => a -> Value
+ EVM.Fetch: type Fetcher = Query -> IO (EVM ())
+ EVM.Fetch: type RpcInfo = Maybe (BlockNumber, Text)
+ EVM.Fetch: zero :: Natural -> Maybe Natural -> Fetcher
+ EVM.Format: contractNamePart :: Text -> Text
+ EVM.Format: contractPathPart :: Text -> Text
+ EVM.Format: formatBinary :: ByteString -> Text
+ EVM.Format: formatBytes :: ByteString -> Text
+ EVM.Format: formatExpr :: Expr a -> Text
+ EVM.Format: indent :: Int -> Text -> Text
+ EVM.Format: instance GHC.Show.Show EVM.Format.Signedness
+ EVM.Format: parenthesise :: [Text] -> Text
+ EVM.Format: prettyIfConcreteWord :: Expr EWord -> Text
+ EVM.Format: prettyvmresult :: (?context :: DappContext) => Expr End -> String
+ EVM.Format: showAbiValue :: (?context :: DappContext) => AbiValue -> Text
+ EVM.Format: showCall :: (?context :: DappContext) => [AbiType] -> Expr Buf -> Text
+ EVM.Format: showError :: (?context :: DappContext) => Expr Buf -> Text
+ EVM.Format: showTraceTree :: DappInfo -> VM -> Text
+ EVM.Format: showTree :: Tree String -> String
+ EVM.Format: showValue :: (?context :: DappContext) => AbiType -> Expr Buf -> Text
+ EVM.Format: showValues :: (?context :: DappContext) => [AbiType] -> Expr Buf -> Text
+ EVM.Format: showWordExact :: W256 -> Text
+ EVM.Format: showWordExplanation :: W256 -> DappInfo -> Text
+ EVM.Format: textValues :: (?context :: DappContext) => [AbiType] -> Expr Buf -> [Text]
+ EVM.Format: unindexed :: [(Text, AbiType, Indexed)] -> [AbiType]
+ EVM.Hexdump: prettyHex :: Int -> ByteString -> String
+ EVM.Hexdump: simpleHex :: ByteString -> String
+ EVM.Keccak: instance GHC.Show.Show EVM.Keccak.BuilderState
+ EVM.Keccak: keccakAssumptions :: [Prop] -> [Expr Buf] -> [Expr Storage] -> [Prop]
+ EVM.Op: OpAdd :: Op
+ EVM.Op: OpAddmod :: Op
+ EVM.Op: OpAddress :: Op
+ EVM.Op: OpAnd :: Op
+ EVM.Op: OpBalance :: Op
+ EVM.Op: OpBlockhash :: Op
+ EVM.Op: OpByte :: Op
+ EVM.Op: OpCall :: Op
+ EVM.Op: OpCallcode :: Op
+ EVM.Op: OpCalldatacopy :: Op
+ EVM.Op: OpCalldataload :: Op
+ EVM.Op: OpCalldatasize :: Op
+ EVM.Op: OpCaller :: Op
+ EVM.Op: OpCallvalue :: Op
+ EVM.Op: OpChainid :: Op
+ EVM.Op: OpCodecopy :: Op
+ EVM.Op: OpCodesize :: Op
+ EVM.Op: OpCoinbase :: Op
+ EVM.Op: OpCreate :: Op
+ EVM.Op: OpCreate2 :: Op
+ EVM.Op: OpDelegatecall :: Op
+ EVM.Op: OpDiv :: Op
+ EVM.Op: OpDup :: !Word8 -> Op
+ EVM.Op: OpEq :: Op
+ EVM.Op: OpExp :: Op
+ EVM.Op: OpExtcodecopy :: Op
+ EVM.Op: OpExtcodehash :: Op
+ EVM.Op: OpExtcodesize :: Op
+ EVM.Op: OpGas :: Op
+ EVM.Op: OpGaslimit :: Op
+ EVM.Op: OpGasprice :: Op
+ EVM.Op: OpGt :: Op
+ EVM.Op: OpIszero :: Op
+ EVM.Op: OpJump :: Op
+ EVM.Op: OpJumpdest :: Op
+ EVM.Op: OpJumpi :: Op
+ EVM.Op: OpLog :: !Word8 -> Op
+ EVM.Op: OpLt :: Op
+ EVM.Op: OpMload :: Op
+ EVM.Op: OpMod :: Op
+ EVM.Op: OpMsize :: Op
+ EVM.Op: OpMstore :: Op
+ EVM.Op: OpMstore8 :: Op
+ EVM.Op: OpMul :: Op
+ EVM.Op: OpMulmod :: Op
+ EVM.Op: OpNot :: Op
+ EVM.Op: OpNumber :: Op
+ EVM.Op: OpOr :: Op
+ EVM.Op: OpOrigin :: Op
+ EVM.Op: OpPc :: Op
+ EVM.Op: OpPop :: Op
+ EVM.Op: OpPrevRandao :: Op
+ EVM.Op: OpPush :: Expr EWord -> Op
+ EVM.Op: OpReturn :: Op
+ EVM.Op: OpReturndatacopy :: Op
+ EVM.Op: OpReturndatasize :: Op
+ EVM.Op: OpRevert :: Op
+ EVM.Op: OpSar :: Op
+ EVM.Op: OpSdiv :: Op
+ EVM.Op: OpSelfbalance :: Op
+ EVM.Op: OpSelfdestruct :: Op
+ EVM.Op: OpSgt :: Op
+ EVM.Op: OpSha3 :: Op
+ EVM.Op: OpShl :: Op
+ EVM.Op: OpShr :: Op
+ EVM.Op: OpSignextend :: Op
+ EVM.Op: OpSload :: Op
+ EVM.Op: OpSlt :: Op
+ EVM.Op: OpSmod :: Op
+ EVM.Op: OpSstore :: Op
+ EVM.Op: OpStaticcall :: Op
+ EVM.Op: OpStop :: Op
+ EVM.Op: OpSub :: Op
+ EVM.Op: OpSwap :: !Word8 -> Op
+ EVM.Op: OpTimestamp :: Op
+ EVM.Op: OpUnknown :: Word8 -> Op
+ EVM.Op: OpXor :: Op
+ EVM.Op: data Op
+ EVM.Op: instance GHC.Classes.Eq EVM.Op.Op
+ EVM.Op: instance GHC.Show.Show EVM.Op.Op
+ EVM.Op: opString :: (Integral a, Show a) => (a, Op) -> String
+ EVM.Patricia: DB :: Free (KV k v) a -> DB k v a
+ EVM.Patricia: Empty :: Node
+ EVM.Patricia: Full :: Seq Ref -> ByteString -> Node
+ EVM.Patricia: Get :: k -> (v -> a) -> KV k v a
+ EVM.Patricia: Hash :: ByteString -> Ref
+ EVM.Patricia: Literal :: Node -> Ref
+ EVM.Patricia: Put :: k -> v -> a -> KV k v a
+ EVM.Patricia: Shortcut :: Path -> Either Ref ByteString -> Node
+ EVM.Patricia: addPrefix :: Path -> Node -> NodeDB Node
+ EVM.Patricia: calcRoot :: [(ByteString, ByteString)] -> Maybe ByteString
+ EVM.Patricia: data KV k v a
+ EVM.Patricia: data Node
+ EVM.Patricia: data Ref
+ EVM.Patricia: delete :: Node -> Path -> NodeDB Node
+ EVM.Patricia: emptyRef :: Ref
+ EVM.Patricia: emptyRefs :: Seq Ref
+ EVM.Patricia: encodePath :: Path -> Bool -> ByteString
+ EVM.Patricia: getNode :: Ref -> NodeDB Node
+ EVM.Patricia: getVal :: Path -> Node -> NodeDB ByteString
+ EVM.Patricia: insert :: Ref -> ByteString -> ByteString -> NodeDB Ref
+ EVM.Patricia: insertDB :: k -> v -> DB k v ()
+ EVM.Patricia: insertRef :: Ref -> Path -> ByteString -> NodeDB Ref
+ EVM.Patricia: insertValues :: [(ByteString, ByteString)] -> Maybe Ref
+ EVM.Patricia: instance GHC.Base.Applicative (EVM.Patricia.DB k v)
+ EVM.Patricia: instance GHC.Base.Functor (EVM.Patricia.DB k v)
+ EVM.Patricia: instance GHC.Base.Functor (EVM.Patricia.KV k v)
+ EVM.Patricia: instance GHC.Base.Monad (EVM.Patricia.DB k v)
+ EVM.Patricia: instance GHC.Classes.Eq EVM.Patricia.Node
+ EVM.Patricia: instance GHC.Classes.Eq EVM.Patricia.Ref
+ EVM.Patricia: instance GHC.Show.Show (EVM.Patricia.NodeDB EVM.Patricia.Node)
+ EVM.Patricia: instance GHC.Show.Show EVM.Patricia.Node
+ EVM.Patricia: instance GHC.Show.Show EVM.Patricia.Ref
+ EVM.Patricia: lookupDB :: k -> DB k v v
+ EVM.Patricia: lookupIn :: Ref -> ByteString -> NodeDB ByteString
+ EVM.Patricia: lookupPath :: Ref -> Path -> NodeDB ByteString
+ EVM.Patricia: newtype DB k v a
+ EVM.Patricia: putNode :: Node -> NodeDB Ref
+ EVM.Patricia: rlpNode :: Node -> RLP
+ EVM.Patricia: rlpRef :: Ref -> RLP
+ EVM.Patricia: runDB :: Monad m => (k -> v -> m ()) -> (k -> m v) -> DB k v a -> m a
+ EVM.Patricia: runMapDB :: Ord k => DB k v a -> MapDB k v a
+ EVM.Patricia: runTrie :: DB ByteString ByteString a -> Trie a
+ EVM.Patricia: type MapDB k v a = StateT (Map k v) Maybe a
+ EVM.Patricia: type NodeDB = DB ByteString Node
+ EVM.Patricia: type Path = [Nibble]
+ EVM.Patricia: type Trie = StateT Ref NodeDB
+ EVM.Patricia: update :: Node -> Path -> ByteString -> NodeDB Node
+ EVM.Precompiled: execute :: Int -> ByteString -> Int -> Maybe ByteString
+ EVM.RLP: BS :: ByteString -> RLP
+ EVM.RLP: List :: [RLP] -> RLP
+ EVM.RLP: data RLP
+ EVM.RLP: encodeLen :: Int -> ByteString -> ByteString
+ EVM.RLP: instance GHC.Classes.Eq EVM.RLP.RLP
+ EVM.RLP: instance GHC.Show.Show EVM.RLP.RLP
+ EVM.RLP: itemInfo :: ByteString -> (Int, Int, Bool, Bool)
+ EVM.RLP: octets :: W256 -> ByteString
+ EVM.RLP: octets160 :: Addr -> ByteString
+ EVM.RLP: octetsFull :: Int -> W256 -> ByteString
+ EVM.RLP: rlpAddrFull :: Addr -> RLP
+ EVM.RLP: rlpList :: [RLP] -> ByteString
+ EVM.RLP: rlpWord160 :: Addr -> RLP
+ EVM.RLP: rlpWord256 :: W256 -> RLP
+ EVM.RLP: rlpWordFull :: W256 -> RLP
+ EVM.RLP: rlpdecode :: ByteString -> Maybe RLP
+ EVM.RLP: rlpencode :: RLP -> ByteString
+ EVM.RLP: rlplengths :: ByteString -> Int -> Int -> [(Int, Int)]
+ EVM.RLP: slice :: Int -> Int -> ByteString -> ByteString
+ EVM.SMT: Bitwuzla :: Solver
+ EVM.SMT: CVC5 :: Solver
+ EVM.SMT: CexVars :: [Text] -> [Text] -> [Text] -> [Text] -> CexVars
+ EVM.SMT: Custom :: Text -> Solver
+ EVM.SMT: Error :: Text -> CheckSatResult
+ EVM.SMT: SMT2 :: [Builder] -> CexVars -> SMT2
+ EVM.SMT: SMTCex :: Map (Expr EWord) W256 -> Map (Expr Buf) ByteString -> Map (Expr EWord) W256 -> Map (Expr EWord) W256 -> SMTCex
+ EVM.SMT: Sat :: SMTCex -> CheckSatResult
+ EVM.SMT: SolverGroup :: Chan Task -> SolverGroup
+ EVM.SMT: SolverInstance :: Solver -> Handle -> Handle -> Handle -> ProcessHandle -> SolverInstance
+ EVM.SMT: Task :: SMT2 -> Chan CheckSatResult -> Task
+ EVM.SMT: Unknown :: CheckSatResult
+ EVM.SMT: Unsat :: CheckSatResult
+ EVM.SMT: Z3 :: Solver
+ EVM.SMT: [_process] :: SolverInstance -> ProcessHandle
+ EVM.SMT: [_stderr] :: SolverInstance -> Handle
+ EVM.SMT: [_stdin] :: SolverInstance -> Handle
+ EVM.SMT: [_stdout] :: SolverInstance -> Handle
+ EVM.SMT: [_type] :: SolverInstance -> Solver
+ EVM.SMT: [blockContextV] :: CexVars -> [Text]
+ EVM.SMT: [blockContext] :: SMTCex -> Map (Expr EWord) W256
+ EVM.SMT: [buffersV] :: CexVars -> [Text]
+ EVM.SMT: [buffers] :: SMTCex -> Map (Expr Buf) ByteString
+ EVM.SMT: [calldataV] :: CexVars -> [Text]
+ EVM.SMT: [resultChan] :: Task -> Chan CheckSatResult
+ EVM.SMT: [script] :: Task -> SMT2
+ EVM.SMT: [txContextV] :: CexVars -> [Text]
+ EVM.SMT: [txContext] :: SMTCex -> Map (Expr EWord) W256
+ EVM.SMT: [vars] :: SMTCex -> Map (Expr EWord) W256
+ EVM.SMT: assertProps :: [Prop] -> SMT2
+ EVM.SMT: checkSat :: SolverGroup -> SMT2 -> IO CheckSatResult
+ EVM.SMT: concatBytes :: [Expr Byte] -> Builder
+ EVM.SMT: copySlice :: Expr EWord -> Expr EWord -> Expr EWord -> Builder -> Builder -> Builder
+ EVM.SMT: data CexVars
+ EVM.SMT: data CheckSatResult
+ EVM.SMT: data SMT2
+ EVM.SMT: data SMTCex
+ EVM.SMT: data Solver
+ EVM.SMT: data SolverInstance
+ EVM.SMT: data Task
+ EVM.SMT: declareBlockContext :: [Builder] -> SMT2
+ EVM.SMT: declareBufs :: [Builder] -> SMT2
+ EVM.SMT: declareFrameContext :: [Builder] -> SMT2
+ EVM.SMT: declareIntermediates :: BufEnv -> StoreEnv -> SMT2
+ EVM.SMT: declareVars :: [Builder] -> SMT2
+ EVM.SMT: encodeConcreteStore :: Map W256 (Map W256 W256) -> Builder
+ EVM.SMT: expandExp :: Expr EWord -> W256 -> Builder
+ EVM.SMT: exprToSMT :: Expr a -> Builder
+ EVM.SMT: formatSMT2 :: SMT2 -> Text
+ EVM.SMT: getBufs :: SolverInstance -> [Text] -> IO (Map (Expr Buf) ByteString)
+ EVM.SMT: getValue :: SolverInstance -> Text -> IO Text
+ EVM.SMT: getVar :: SMTCex -> Text -> W256
+ EVM.SMT: getVars :: (Text -> Expr EWord) -> SolverInstance -> [Text] -> IO (Map (Expr EWord) W256)
+ EVM.SMT: instance GHC.Base.Monoid EVM.SMT.CexVars
+ EVM.SMT: instance GHC.Base.Monoid EVM.SMT.SMT2
+ EVM.SMT: instance GHC.Base.Semigroup EVM.SMT.CexVars
+ EVM.SMT: instance GHC.Base.Semigroup EVM.SMT.SMT2
+ EVM.SMT: instance GHC.Classes.Eq EVM.SMT.CexVars
+ EVM.SMT: instance GHC.Classes.Eq EVM.SMT.CheckSatResult
+ EVM.SMT: instance GHC.Classes.Eq EVM.SMT.SMT2
+ EVM.SMT: instance GHC.Classes.Eq EVM.SMT.SMTCex
+ EVM.SMT: instance GHC.Show.Show EVM.SMT.CexVars
+ EVM.SMT: instance GHC.Show.Show EVM.SMT.CheckSatResult
+ EVM.SMT: instance GHC.Show.Show EVM.SMT.SMT2
+ EVM.SMT: instance GHC.Show.Show EVM.SMT.SMTCex
+ EVM.SMT: instance GHC.Show.Show EVM.SMT.Solver
+ EVM.SMT: isErr :: CheckSatResult -> Bool
+ EVM.SMT: isSat :: CheckSatResult -> Bool
+ EVM.SMT: isUnsat :: CheckSatResult -> Bool
+ EVM.SMT: newtype SolverGroup
+ EVM.SMT: one :: Builder
+ EVM.SMT: parseBlockCtx :: Text -> Expr EWord
+ EVM.SMT: parseErr :: Show a => a -> b
+ EVM.SMT: parseFrameCtx :: Text -> Expr EWord
+ EVM.SMT: parseInteger :: SpecConstant -> Integer
+ EVM.SMT: parseSC :: (Num a, Eq a) => SpecConstant -> a
+ EVM.SMT: parseVar :: Text -> Expr EWord
+ EVM.SMT: parseW256 :: SpecConstant -> W256
+ EVM.SMT: parseW8 :: SpecConstant -> Word8
+ EVM.SMT: prelude :: SMT2
+ EVM.SMT: propToSMT :: Prop -> Builder
+ EVM.SMT: readSExpr :: Handle -> IO [Text]
+ EVM.SMT: referencedBlockContext :: Expr a -> [Builder]
+ EVM.SMT: referencedBlockContext' :: Prop -> [Builder]
+ EVM.SMT: referencedBufs :: Expr a -> [Builder]
+ EVM.SMT: referencedBufs' :: Prop -> [Builder]
+ EVM.SMT: referencedFrameContext :: Expr a -> [Builder]
+ EVM.SMT: referencedFrameContext' :: Prop -> [Builder]
+ EVM.SMT: referencedVars :: Expr a -> [Builder]
+ EVM.SMT: referencedVars' :: Prop -> [Builder]
+ EVM.SMT: sendCommand :: SolverInstance -> Text -> IO Text
+ EVM.SMT: sendLine :: SolverInstance -> Text -> IO Text
+ EVM.SMT: sendLine' :: SolverInstance -> Text -> IO ()
+ EVM.SMT: sendScript :: SolverInstance -> SMT2 -> IO (Either Text ())
+ EVM.SMT: solverArgs :: Solver -> Maybe Natural -> [Text]
+ EVM.SMT: sp :: Builder -> Builder -> Builder
+ EVM.SMT: spawnSolver :: Solver -> Maybe Natural -> IO SolverInstance
+ EVM.SMT: stopSolver :: SolverInstance -> IO ()
+ EVM.SMT: withSolvers :: Solver -> Natural -> Maybe Natural -> (SolverGroup -> IO a) -> IO a
+ EVM.SMT: writeBytes :: ByteString -> Expr Buf -> Builder
+ EVM.SMT: zero :: Builder
+ EVM.Solidity: Creation :: CodeType
+ EVM.Solidity: JumpFrom :: JumpType
+ EVM.Solidity: JumpInto :: JumpType
+ EVM.Solidity: JumpRegular :: JumpType
+ EVM.Solidity: Method :: [(Text, AbiType)] -> [(Text, AbiType)] -> Text -> Text -> Mutability -> Method
+ EVM.Solidity: NonPayable :: Mutability
+ EVM.Solidity: Payable :: Mutability
+ EVM.Solidity: Pure :: Mutability
+ EVM.Solidity: Reference :: Int -> Int -> Reference
+ EVM.Solidity: Runtime :: CodeType
+ EVM.Solidity: SM :: {-# UNPACK #-}Int -> {-# UNPACK #-}Int -> {-# UNPACK #-}Int -> JumpType -> {-# UNPACK #-}Int -> SrcMap
+ EVM.Solidity: SolcContract :: W256 -> W256 -> ByteString -> ByteString -> Text -> [(Text, AbiType)] -> Map Word32 Method -> Map W256 Event -> Map W256 SolError -> Map W256 [Reference] -> Maybe (Map Text StorageItem) -> Seq SrcMap -> Seq SrcMap -> SolcContract
+ EVM.Solidity: Solidity :: Language
+ EVM.Solidity: SourceCache :: [(Text, ByteString)] -> [Vector ByteString] -> Map Text Value -> SourceCache
+ EVM.Solidity: StorageItem :: SlotType -> Int -> Int -> StorageItem
+ EVM.Solidity: StorageMapping :: NonEmpty AbiType -> AbiType -> SlotType
+ EVM.Solidity: StorageValue :: AbiType -> SlotType
+ EVM.Solidity: View :: Mutability
+ EVM.Solidity: Yul :: Language
+ EVM.Solidity: [_abiMap] :: SolcContract -> Map Word32 Method
+ EVM.Solidity: [_constructorInputs] :: SolcContract -> [(Text, AbiType)]
+ EVM.Solidity: [_contractName] :: SolcContract -> Text
+ EVM.Solidity: [_creationCode] :: SolcContract -> ByteString
+ EVM.Solidity: [_creationCodehash] :: SolcContract -> W256
+ EVM.Solidity: [_creationSrcmap] :: SolcContract -> Seq SrcMap
+ EVM.Solidity: [_errorMap] :: SolcContract -> Map W256 SolError
+ EVM.Solidity: [_eventMap] :: SolcContract -> Map W256 Event
+ EVM.Solidity: [_immutableReferences] :: SolcContract -> Map W256 [Reference]
+ EVM.Solidity: [_methodInputs] :: Method -> [(Text, AbiType)]
+ EVM.Solidity: [_methodMutability] :: Method -> Mutability
+ EVM.Solidity: [_methodName] :: Method -> Text
+ EVM.Solidity: [_methodOutput] :: Method -> [(Text, AbiType)]
+ EVM.Solidity: [_methodSignature] :: Method -> Text
+ EVM.Solidity: [_offset] :: StorageItem -> Int
+ EVM.Solidity: [_refLength] :: Reference -> Int
+ EVM.Solidity: [_refStart] :: Reference -> Int
+ EVM.Solidity: [_runtimeCode] :: SolcContract -> ByteString
+ EVM.Solidity: [_runtimeCodehash] :: SolcContract -> W256
+ EVM.Solidity: [_runtimeSrcmap] :: SolcContract -> Seq SrcMap
+ EVM.Solidity: [_slot] :: StorageItem -> Int
+ EVM.Solidity: [_sourceAsts] :: SourceCache -> Map Text Value
+ EVM.Solidity: [_sourceFiles] :: SourceCache -> [(Text, ByteString)]
+ EVM.Solidity: [_sourceLines] :: SourceCache -> [Vector ByteString]
+ EVM.Solidity: [_storageLayout] :: SolcContract -> Maybe (Map Text StorageItem)
+ EVM.Solidity: [_type] :: StorageItem -> SlotType
+ EVM.Solidity: [srcMapFile] :: SrcMap -> {-# UNPACK #-}Int
+ EVM.Solidity: [srcMapJump] :: SrcMap -> JumpType
+ EVM.Solidity: [srcMapLength] :: SrcMap -> {-# UNPACK #-}Int
+ EVM.Solidity: [srcMapModifierDepth] :: SrcMap -> {-# UNPACK #-}Int
+ EVM.Solidity: [srcMapOffset] :: SrcMap -> {-# UNPACK #-}Int
+ EVM.Solidity: abiMap :: Lens' SolcContract (Map Word32 Method)
+ EVM.Solidity: astIdMap :: Foldable f => f Value -> Map Int Value
+ EVM.Solidity: astSrcMap :: Map Int Value -> SrcMap -> Maybe Value
+ EVM.Solidity: constructorInputs :: Lens' SolcContract [(Text, AbiType)]
+ EVM.Solidity: containsLinkerHole :: Text -> Bool
+ EVM.Solidity: contractName :: Lens' SolcContract Text
+ EVM.Solidity: creationCode :: Lens' SolcContract ByteString
+ EVM.Solidity: creationCodehash :: Lens' SolcContract W256
+ EVM.Solidity: creationSrcmap :: Lens' SolcContract (Seq SrcMap)
+ EVM.Solidity: data CodeType
+ EVM.Solidity: data JumpType
+ EVM.Solidity: data Language
+ EVM.Solidity: data Method
+ EVM.Solidity: data Mutability
+ EVM.Solidity: data Reference
+ EVM.Solidity: data SlotType
+ EVM.Solidity: data SolcContract
+ EVM.Solidity: data SourceCache
+ EVM.Solidity: data SrcMap
+ EVM.Solidity: data StorageItem
+ EVM.Solidity: errorMap :: Lens' SolcContract (Map W256 SolError)
+ EVM.Solidity: eventMap :: Lens' SolcContract (Map W256 Event)
+ EVM.Solidity: functionAbi :: Text -> IO Method
+ EVM.Solidity: immutableReferences :: Lens' SolcContract (Map W256 [Reference])
+ EVM.Solidity: instance Data.Aeson.Types.FromJSON.FromJSON EVM.Solidity.Reference
+ EVM.Solidity: instance Data.Aeson.Types.ToJSON.ToJSON EVM.Solidity.StandardJSON
+ EVM.Solidity: instance GHC.Base.Monoid EVM.Solidity.SourceCache
+ EVM.Solidity: instance GHC.Base.Semigroup EVM.Solidity.SourceCache
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.CodeType
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.JumpType
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.Method
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.Mutability
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.Reference
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.SlotType
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.SolcContract
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.SourceCache
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.SrcMap
+ EVM.Solidity: instance GHC.Classes.Eq EVM.Solidity.StorageItem
+ EVM.Solidity: instance GHC.Classes.Ord EVM.Solidity.CodeType
+ EVM.Solidity: instance GHC.Classes.Ord EVM.Solidity.JumpType
+ EVM.Solidity: instance GHC.Classes.Ord EVM.Solidity.Method
+ EVM.Solidity: instance GHC.Classes.Ord EVM.Solidity.Mutability
+ EVM.Solidity: instance GHC.Classes.Ord EVM.Solidity.SrcMap
+ EVM.Solidity: instance GHC.Generics.Generic EVM.Solidity.JumpType
+ EVM.Solidity: instance GHC.Generics.Generic EVM.Solidity.Method
+ EVM.Solidity: instance GHC.Generics.Generic EVM.Solidity.Mutability
+ EVM.Solidity: instance GHC.Generics.Generic EVM.Solidity.SolcContract
+ EVM.Solidity: instance GHC.Generics.Generic EVM.Solidity.SourceCache
+ EVM.Solidity: instance GHC.Generics.Generic EVM.Solidity.SrcMap
+ EVM.Solidity: instance GHC.Read.Read EVM.Solidity.SlotType
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.CodeType
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.JumpType
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.Language
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.Method
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.Mutability
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.Reference
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.SlotType
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.SolcContract
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.SourceCache
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.SrcMap
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.SrcMapParseState
+ EVM.Solidity: instance GHC.Show.Show EVM.Solidity.StorageItem
+ EVM.Solidity: lineSubrange :: Vector ByteString -> (Int, Int) -> Int -> Maybe (Int, Int)
+ EVM.Solidity: makeSourceCache :: [(Text, Maybe ByteString)] -> Map Text Value -> IO SourceCache
+ EVM.Solidity: makeSrcMaps :: Text -> Maybe (Seq SrcMap)
+ EVM.Solidity: methodInputs :: Lens' Method [(Text, AbiType)]
+ EVM.Solidity: methodMutability :: Lens' Method Mutability
+ EVM.Solidity: methodName :: Lens' Method Text
+ EVM.Solidity: methodOutput :: Lens' Method [(Text, AbiType)]
+ EVM.Solidity: methodSignature :: Lens' Method Text
+ EVM.Solidity: parseMethodInput :: AsValue s => s -> (Text, AbiType)
+ EVM.Solidity: readCombinedJSON :: Text -> Maybe (Map Text SolcContract, Map Text Value, [(Text, Maybe ByteString)])
+ EVM.Solidity: readJSON :: Text -> Maybe (Map Text SolcContract, Map Text Value, [(Text, Maybe ByteString)])
+ EVM.Solidity: readSolc :: FilePath -> IO (Maybe (Map Text SolcContract, SourceCache))
+ EVM.Solidity: readStdJSON :: Text -> Maybe (Map Text SolcContract, Map Text Value, [(Text, Maybe ByteString)])
+ EVM.Solidity: runtimeCode :: Lens' SolcContract ByteString
+ EVM.Solidity: runtimeCodehash :: Lens' SolcContract W256
+ EVM.Solidity: runtimeSrcmap :: Lens' SolcContract (Seq SrcMap)
+ EVM.Solidity: signature :: AsValue s => s -> Text
+ EVM.Solidity: solc :: Language -> Text -> IO Text
+ EVM.Solidity: solcRuntime :: Text -> Text -> IO (Maybe ByteString)
+ EVM.Solidity: solidity :: Text -> Text -> IO (Maybe ByteString)
+ EVM.Solidity: solidity' :: Text -> IO (Text, Text)
+ EVM.Solidity: sourceAsts :: Lens' SourceCache (Map Text Value)
+ EVM.Solidity: sourceFiles :: Lens' SourceCache [(Text, ByteString)]
+ EVM.Solidity: sourceLines :: Lens' SourceCache [Vector ByteString]
+ EVM.Solidity: stdjson :: Language -> Text -> Text
+ EVM.Solidity: storageLayout :: Lens' SolcContract (Maybe (Map Text StorageItem))
+ EVM.Solidity: stripBytecodeMetadata :: ByteString -> ByteString
+ EVM.Solidity: stripBytecodeMetadataSym :: [Expr Byte] -> [Expr Byte]
+ EVM.Solidity: yul :: Text -> Text -> IO (Maybe ByteString)
+ EVM.Solidity: yul' :: Text -> IO (Text, Text)
+ EVM.Solidity: yulRuntime :: Text -> Text -> IO (Maybe ByteString)
+ EVM.Stepper: [Ask] :: Choose -> Action ()
+ EVM.Stepper: [EVM] :: EVM a -> Action a
+ EVM.Stepper: [Exec] :: Action VMResult
+ EVM.Stepper: [IOAct] :: StateT VM IO a -> Action a
+ EVM.Stepper: [Run] :: Action VM
+ EVM.Stepper: [Wait] :: Query -> Action ()
+ EVM.Stepper: ask :: Choose -> Stepper ()
+ EVM.Stepper: data Action a
+ EVM.Stepper: enter :: Text -> Stepper ()
+ EVM.Stepper: entering :: Text -> Stepper a -> Stepper a
+ EVM.Stepper: evm :: EVM a -> Stepper a
+ EVM.Stepper: evmIO :: StateT VM IO a -> Stepper a
+ EVM.Stepper: exec :: Stepper VMResult
+ EVM.Stepper: execFully :: Stepper (Either Error (Expr Buf))
+ EVM.Stepper: interpret :: Fetcher -> Stepper a -> StateT VM IO a
+ EVM.Stepper: run :: Stepper VM
+ EVM.Stepper: runFully :: Stepper VM
+ EVM.Stepper: type Stepper a = Program Action a
+ EVM.Stepper: wait :: Query -> Stepper ()
+ EVM.StorageLayout: findContractDefinition :: DappInfo -> SolcContract -> Maybe Value
+ EVM.StorageLayout: grokDeclarationType :: Value -> SlotType
+ EVM.StorageLayout: grokMappingType :: [Value] -> SlotType
+ EVM.StorageLayout: grokValueType :: Value -> AbiType
+ EVM.StorageLayout: isStorageVariableDeclaration :: Value -> Bool
+ EVM.StorageLayout: nodeIs :: Text -> Value -> Bool
+ EVM.StorageLayout: slotTypeForDeclaration :: Value -> SlotType
+ EVM.StorageLayout: storageLayout :: DappInfo -> SolcContract -> [Text]
+ EVM.StorageLayout: storageVariablesForContract :: Value -> Maybe [Text]
+ EVM.SymExec: Cex :: b -> ProofResult a b c
+ EVM.SymExec: Comp :: [CalldataFragment] -> CalldataFragment
+ EVM.SymExec: Dy :: [Prop] -> Expr EWord -> Expr Buf -> CalldataFragment
+ EVM.SymExec: Qed :: a -> ProofResult a b c
+ EVM.SymExec: St :: [Prop] -> Expr EWord -> CalldataFragment
+ EVM.SymExec: Timeout :: c -> ProofResult a b c
+ EVM.SymExec: VeriOpts :: Bool -> Bool -> Maybe Integer -> Maybe Integer -> RpcInfo -> VeriOpts
+ EVM.SymExec: [askSmtIters] :: VeriOpts -> Maybe Integer
+ EVM.SymExec: [debug] :: VeriOpts -> Bool
+ EVM.SymExec: [maxIter] :: VeriOpts -> Maybe Integer
+ EVM.SymExec: [rpcInfo] :: VeriOpts -> RpcInfo
+ EVM.SymExec: [simp] :: VeriOpts -> Bool
+ EVM.SymExec: abstractVM :: Maybe (Text, [AbiType]) -> [String] -> ByteString -> Maybe Precondition -> StorageModel -> VM
+ EVM.SymExec: allPanicCodes :: [Word256]
+ EVM.SymExec: bool :: Expr EWord -> Prop
+ EVM.SymExec: both' :: (a -> b) -> (a, a) -> (b, b)
+ EVM.SymExec: cdLen :: [CalldataFragment] -> Expr EWord
+ EVM.SymExec: checkAssert :: SolverGroup -> [Word256] -> ByteString -> Maybe (Text, [AbiType]) -> [String] -> VeriOpts -> IO (Expr End, [VerifyResult])
+ EVM.SymExec: checkAssertions :: [Word256] -> Postcondition
+ EVM.SymExec: combineFragments :: [CalldataFragment] -> Expr Buf -> (Expr Buf, [Prop])
+ EVM.SymExec: containsA :: Eq a => Eq b => Eq c => ProofResult a b c -> [(d, e, ProofResult a b c)] -> Bool
+ EVM.SymExec: data CalldataFragment
+ EVM.SymExec: data ProofResult a b c
+ EVM.SymExec: data VeriOpts
+ EVM.SymExec: debugVeriOpts :: VeriOpts
+ EVM.SymExec: defaultPanicCodes :: [Word256]
+ EVM.SymExec: defaultVeriOpts :: VeriOpts
+ EVM.SymExec: equivalenceCheck :: SolverGroup -> ByteString -> ByteString -> VeriOpts -> Maybe (Text, [AbiType]) -> IO [(Maybe SMTCex, Prop, ProofResult () () ())]
+ EVM.SymExec: evalProp :: Prop -> Prop
+ EVM.SymExec: extractCex :: VerifyResult -> Maybe (Expr End, SMTCex)
+ EVM.SymExec: extractProps :: Expr End -> [Prop]
+ EVM.SymExec: flattenExpr :: Expr End -> [([Prop], Expr End)]
+ EVM.SymExec: formatCex :: Expr Buf -> SMTCex -> Text
+ EVM.SymExec: inRange :: Int -> Expr EWord -> Prop
+ EVM.SymExec: instance (GHC.Classes.Eq a, GHC.Classes.Eq b, GHC.Classes.Eq c) => GHC.Classes.Eq (EVM.SymExec.ProofResult a b c)
+ EVM.SymExec: instance (GHC.Show.Show a, GHC.Show.Show b, GHC.Show.Show c) => GHC.Show.Show (EVM.SymExec.ProofResult a b c)
+ EVM.SymExec: instance GHC.Classes.Eq EVM.SymExec.CalldataFragment
+ EVM.SymExec: instance GHC.Classes.Eq EVM.SymExec.VeriOpts
+ EVM.SymExec: instance GHC.Show.Show EVM.SymExec.CalldataFragment
+ EVM.SymExec: instance GHC.Show.Show EVM.SymExec.VeriOpts
+ EVM.SymExec: interpret :: Fetcher -> Maybe Integer -> Maybe Integer -> Stepper (Expr End) -> StateT VM IO (Expr End)
+ EVM.SymExec: isQed :: ProofResult a b c -> Bool
+ EVM.SymExec: loadSymVM :: ContractCode -> Expr Storage -> Expr EWord -> Expr EWord -> Expr Buf -> [Prop] -> VM
+ EVM.SymExec: maxIterationsReached :: VM -> Maybe Integer -> Maybe Bool
+ EVM.SymExec: panicMsg :: Word256 -> ByteString
+ EVM.SymExec: produceModels :: SolverGroup -> Expr End -> IO [(Expr End, CheckSatResult)]
+ EVM.SymExec: pruneDeadPaths :: [VM] -> [VM]
+ EVM.SymExec: reachable :: SolverGroup -> Expr End -> IO ([SMT2], Expr End)
+ EVM.SymExec: rpcVeriOpts :: (BlockNumber, Text) -> VeriOpts
+ EVM.SymExec: runExpr :: Stepper (Expr End)
+ EVM.SymExec: showModel :: Expr Buf -> (Expr End, CheckSatResult) -> IO ()
+ EVM.SymExec: subModel :: SMTCex -> Expr a -> Expr a
+ EVM.SymExec: symAbiArg :: Text -> AbiType -> CalldataFragment
+ EVM.SymExec: symCalldata :: Text -> [AbiType] -> [String] -> Expr Buf -> (Expr Buf, [Prop])
+ EVM.SymExec: type EquivalenceResult = ProofResult ([VM], [VM]) VM ()
+ EVM.SymExec: type Postcondition = VM -> Expr End -> Prop
+ EVM.SymExec: type Precondition = VM -> Prop
+ EVM.SymExec: type VerifyResult = ProofResult () (Expr End, SMTCex) (Expr End)
+ EVM.SymExec: verify :: SolverGroup -> VeriOpts -> VM -> Maybe Postcondition -> IO (Expr End, [VerifyResult])
+ EVM.SymExec: verifyContract :: SolverGroup -> ByteString -> Maybe (Text, [AbiType]) -> [String] -> VeriOpts -> StorageModel -> Maybe Precondition -> Maybe Postcondition -> IO (Expr End, [VerifyResult])
+ EVM.SymExec: writeSelector :: Expr Buf -> Text -> Expr Buf
+ EVM.TTY: AbiPane :: Name
+ EVM.TTY: BrowserPane :: Name
+ EVM.TTY: BytecodePane :: Name
+ EVM.TTY: Continue :: Stepper a -> Continuation a
+ EVM.TTY: Pager :: Name
+ EVM.TTY: SolidityPane :: Name
+ EVM.TTY: StackPane :: Name
+ EVM.TTY: Step :: !Int -> StepMode
+ EVM.TTY: StepUntil :: Pred VM -> StepMode
+ EVM.TTY: Stopped :: a -> Continuation a
+ EVM.TTY: TestPickerPane :: Name
+ EVM.TTY: TracePane :: Name
+ EVM.TTY: UiBrowserState :: List Name (Addr, Contract) -> UiVmState -> UiBrowserState
+ EVM.TTY: UiTestPickerState :: List Name (Text, Text) -> DappInfo -> UnitTestOptions -> UiTestPickerState
+ EVM.TTY: UiVmState :: VM -> Int -> Map Int (VM, Stepper ()) -> Stepper () -> Bool -> UnitTestOptions -> UiVmState
+ EVM.TTY: ViewContracts :: UiBrowserState -> UiState
+ EVM.TTY: ViewHelp :: UiVmState -> UiState
+ EVM.TTY: ViewPicker :: UiTestPickerState -> UiState
+ EVM.TTY: ViewVm :: UiVmState -> UiState
+ EVM.TTY: [_browserContractList] :: UiBrowserState -> List Name (Addr, Contract)
+ EVM.TTY: [_browserVm] :: UiBrowserState -> UiVmState
+ EVM.TTY: [_testOpts] :: UiTestPickerState -> UnitTestOptions
+ EVM.TTY: [_testPickerDapp] :: UiTestPickerState -> DappInfo
+ EVM.TTY: [_testPickerList] :: UiTestPickerState -> List Name (Text, Text)
+ EVM.TTY: [_uiShowMemory] :: UiVmState -> Bool
+ EVM.TTY: [_uiSnapshots] :: UiVmState -> Map Int (VM, Stepper ())
+ EVM.TTY: [_uiStep] :: UiVmState -> Int
+ EVM.TTY: [_uiStepper] :: UiVmState -> Stepper ()
+ EVM.TTY: [_uiTestOpts] :: UiVmState -> UnitTestOptions
+ EVM.TTY: [_uiVm] :: UiVmState -> VM
+ EVM.TTY: _ViewContracts :: Prism' UiState UiBrowserState
+ EVM.TTY: _ViewHelp :: Prism' UiState UiVmState
+ EVM.TTY: _ViewPicker :: Prism' UiState UiTestPickerState
+ EVM.TTY: _ViewVm :: Prism' UiState UiVmState
+ EVM.TTY: activeAttr :: AttrName
+ EVM.TTY: app :: UnitTestOptions -> App UiState () Name
+ EVM.TTY: appEvent :: (?fetcher :: Fetcher, ?maxIter :: Maybe Integer) => BrickEvent Name e -> EventM Name UiState ()
+ EVM.TTY: backstep :: (?fetcher :: Fetcher, ?maxIter :: Maybe Integer) => UiVmState -> IO UiVmState
+ EVM.TTY: backstepUntil :: (?fetcher :: Fetcher, ?maxIter :: Maybe Integer) => (UiVmState -> Pred VM) -> EventM n UiState ()
+ EVM.TTY: boldAttr :: AttrName
+ EVM.TTY: browserContractList :: Lens' UiBrowserState (List Name (Addr, Contract))
+ EVM.TTY: browserVm :: Lens' UiBrowserState UiVmState
+ EVM.TTY: currentSrcMap :: DappInfo -> VM -> Maybe SrcMap
+ EVM.TTY: data Continuation a
+ EVM.TTY: data Name
+ EVM.TTY: data StepMode
+ EVM.TTY: data UiBrowserState
+ EVM.TTY: data UiState
+ EVM.TTY: data UiTestPickerState
+ EVM.TTY: data UiVmState
+ EVM.TTY: debuggableTests :: UnitTestOptions -> (Text, [(Test, [AbiType])]) -> [(Text, Text)]
+ EVM.TTY: dim :: Widget n -> Widget n
+ EVM.TTY: dimAttr :: AttrName
+ EVM.TTY: drawBytecodePane :: UiVmState -> UiWidget
+ EVM.TTY: drawHelpBar :: UiWidget
+ EVM.TTY: drawHelpView :: [UiWidget]
+ EVM.TTY: drawSolidityPane :: UiVmState -> UiWidget
+ EVM.TTY: drawStackPane :: UiVmState -> UiWidget
+ EVM.TTY: drawTestPicker :: UiTestPickerState -> [UiWidget]
+ EVM.TTY: drawTracePane :: UiVmState -> UiWidget
+ EVM.TTY: drawUi :: UiState -> [UiWidget]
+ EVM.TTY: drawVm :: UiVmState -> [UiWidget]
+ EVM.TTY: drawVmBrowser :: UiBrowserState -> [UiWidget]
+ EVM.TTY: ifTallEnough :: Int -> Widget n -> Widget n -> Widget n
+ EVM.TTY: initUiVmState :: VM -> UnitTestOptions -> Stepper () -> UiVmState
+ EVM.TTY: initialUiVmStateForTest :: UnitTestOptions -> (Text, Text) -> UiVmState
+ EVM.TTY: instance GHC.Classes.Eq EVM.TTY.Name
+ EVM.TTY: instance GHC.Classes.Ord EVM.TTY.Name
+ EVM.TTY: instance GHC.Show.Show EVM.TTY.Name
+ EVM.TTY: interpret :: (?fetcher :: Fetcher, ?maxIter :: Maybe Integer) => StepMode -> Stepper a -> StateT UiVmState IO (Continuation a)
+ EVM.TTY: isExecutionHalted :: UiVmState -> Pred VM
+ EVM.TTY: isFuzzTest :: (Test, [AbiType]) -> Bool
+ EVM.TTY: isNewTraceAdded :: UiVmState -> Pred VM
+ EVM.TTY: isNextSourcePosition :: UiVmState -> Pred VM
+ EVM.TTY: isNextSourcePositionWithoutEntering :: UiVmState -> Pred VM
+ EVM.TTY: isUnitTestContract :: Text -> DappInfo -> Bool
+ EVM.TTY: keepExecuting :: (?fetcher :: Fetcher, ?maxIter :: Maybe Integer) => StepMode -> Stepper a -> StateT UiVmState IO (Continuation a)
+ EVM.TTY: main :: UnitTestOptions -> FilePath -> FilePath -> IO ()
+ EVM.TTY: message :: VM -> String
+ EVM.TTY: mkVty :: IO Vty
+ EVM.TTY: myTheme :: [(AttrName, Attr)]
+ EVM.TTY: opWidget :: (Integral a, Show a) => (a, Op) -> Widget n
+ EVM.TTY: ourWrap :: String -> Widget n
+ EVM.TTY: prettyIfConcrete :: Expr Buf -> String
+ EVM.TTY: runFromVM :: SolverGroup -> RpcInfo -> Maybe Integer -> DappInfo -> VM -> IO VM
+ EVM.TTY: selectedAttr :: AttrName
+ EVM.TTY: snapshotInterval :: Int
+ EVM.TTY: solidityList :: VM -> DappInfo -> List Name (Int, ByteString)
+ EVM.TTY: stepOneOpcode :: Stepper a -> StateT UiVmState IO ()
+ EVM.TTY: takeStep :: (?fetcher :: Fetcher, ?maxIter :: Maybe Integer) => UiVmState -> StepMode -> EventM n UiState ()
+ EVM.TTY: testOpts :: Lens' UiTestPickerState UnitTestOptions
+ EVM.TTY: testPickerDapp :: Lens' UiTestPickerState DappInfo
+ EVM.TTY: testPickerList :: Lens' UiTestPickerState (List Name (Text, Text))
+ EVM.TTY: type Pred a = a -> Bool
+ EVM.TTY: type UiWidget = Widget Name
+ EVM.TTY: uiShowMemory :: Lens' UiVmState Bool
+ EVM.TTY: uiSnapshots :: Lens' UiVmState (Map Int (VM, Stepper ()))
+ EVM.TTY: uiStep :: Lens' UiVmState Int
+ EVM.TTY: uiStepper :: Lens' UiVmState (Stepper ())
+ EVM.TTY: uiTestOpts :: Lens' UiVmState UnitTestOptions
+ EVM.TTY: uiVm :: Lens' UiVmState VM
+ EVM.TTY: withHighlight :: Bool -> Widget n -> Widget n
+ EVM.TTY: wordAttr :: AttrName
+ EVM.TTYCenteredList: drawListElements :: (Ord n, Show n) => Bool -> List n e -> (Bool -> e -> Widget n) -> Widget n
+ EVM.TTYCenteredList: renderList :: (Ord n, Show n) => (Bool -> e -> Widget n) -> Bool -> List n e -> Widget n
+ EVM.Transaction: AccessListEntry :: Addr -> [W256] -> AccessListEntry
+ EVM.Transaction: AccessListTransaction :: TxType
+ EVM.Transaction: EIP1559Transaction :: TxType
+ EVM.Transaction: LegacyTransaction :: TxType
+ EVM.Transaction: Transaction :: ByteString -> Word64 -> Maybe W256 -> W256 -> W256 -> W256 -> Maybe Addr -> W256 -> W256 -> TxType -> [AccessListEntry] -> Maybe W256 -> Maybe W256 -> Transaction
+ EVM.Transaction: [accessAddress] :: AccessListEntry -> Addr
+ EVM.Transaction: [accessStorageKeys] :: AccessListEntry -> [W256]
+ EVM.Transaction: [txAccessList] :: Transaction -> [AccessListEntry]
+ EVM.Transaction: [txData] :: Transaction -> ByteString
+ EVM.Transaction: [txGasLimit] :: Transaction -> Word64
+ EVM.Transaction: [txGasPrice] :: Transaction -> Maybe W256
+ EVM.Transaction: [txMaxFeePerGas] :: Transaction -> Maybe W256
+ EVM.Transaction: [txMaxPriorityFeeGas] :: Transaction -> Maybe W256
+ EVM.Transaction: [txNonce] :: Transaction -> W256
+ EVM.Transaction: [txR] :: Transaction -> W256
+ EVM.Transaction: [txS] :: Transaction -> W256
+ EVM.Transaction: [txToAddr] :: Transaction -> Maybe Addr
+ EVM.Transaction: [txType] :: Transaction -> TxType
+ EVM.Transaction: [txV] :: Transaction -> W256
+ EVM.Transaction: [txValue] :: Transaction -> W256
+ EVM.Transaction: accessListPrice :: FeeSchedule Word64 -> [AccessListEntry] -> Word64
+ EVM.Transaction: accountAt :: Addr -> Getter (Map Addr Contract) Contract
+ EVM.Transaction: data AccessListEntry
+ EVM.Transaction: data Transaction
+ EVM.Transaction: data TxType
+ EVM.Transaction: ecrec :: W256 -> W256 -> W256 -> W256 -> Maybe Addr
+ EVM.Transaction: initTx :: VM -> VM
+ EVM.Transaction: instance Data.Aeson.Types.FromJSON.FromJSON EVM.Transaction.AccessListEntry
+ EVM.Transaction: instance Data.Aeson.Types.FromJSON.FromJSON EVM.Transaction.Transaction
+ EVM.Transaction: instance GHC.Classes.Eq EVM.Transaction.TxType
+ EVM.Transaction: instance GHC.Show.Show EVM.Transaction.AccessListEntry
+ EVM.Transaction: instance GHC.Show.Show EVM.Transaction.Transaction
+ EVM.Transaction: instance GHC.Show.Show EVM.Transaction.TxType
+ EVM.Transaction: newAccount :: Contract
+ EVM.Transaction: sender :: Int -> Transaction -> Maybe Addr
+ EVM.Transaction: setupTx :: Addr -> Addr -> W256 -> Word64 -> Map Addr Contract -> Map Addr Contract
+ EVM.Transaction: signingData :: Int -> Transaction -> ByteString
+ EVM.Transaction: touchAccount :: Addr -> Map Addr Contract -> Map Addr Contract
+ EVM.Transaction: txAccessMap :: Transaction -> Map Addr [W256]
+ EVM.Transaction: txGasCost :: FeeSchedule Word64 -> Transaction -> Word64
+ EVM.Traversals: foldExpr :: forall b c. Monoid b => (forall a. Expr a -> b) -> b -> Expr c -> b
+ EVM.Traversals: foldProp :: forall b. Monoid b => (forall a. Expr a -> b) -> b -> Prop -> b
+ EVM.Traversals: mapExpr :: (forall a. Expr a -> Expr a) -> Expr b -> Expr b
+ EVM.Traversals: mapExprM :: Monad m => (forall a. Expr a -> m (Expr a)) -> Expr b -> m (Expr b)
+ EVM.Traversals: mapProp :: (forall a. Expr a -> Expr a) -> Prop -> Prop
+ EVM.Traversals: mapPropM :: Monad m => (forall a. Expr a -> m (Expr a)) -> Prop -> m Prop
+ EVM.Types: (.&&) :: Prop -> Prop -> Prop
+ EVM.Types: (./=) :: Typeable a => Expr a -> Expr a -> Prop
+ EVM.Types: (.<) :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: (.<=) :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: (.==) :: Typeable a => Expr a -> Expr a -> Prop
+ EVM.Types: (.>) :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: (.>=) :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: (.||) :: Prop -> Prop -> Prop
+ EVM.Types: Addr :: Word160 -> Addr
+ EVM.Types: BadJumpDestination :: Error
+ EVM.Types: Buf :: EType
+ EVM.Types: Byte :: EType
+ EVM.Types: ByteStringS :: ByteString -> ByteStringS
+ EVM.Types: EWord :: EType
+ EVM.Types: End :: EType
+ EVM.Types: IllegalOverflow :: Error
+ EVM.Types: Int512 :: {-# UNPACK #-} !Int256 -> {-# UNPACK #-} !Word256 -> Int512
+ EVM.Types: Invalid :: Error
+ EVM.Types: InvalidMemoryAccess :: Error
+ EVM.Types: Log :: EType
+ EVM.Types: Nibble :: Word8 -> Nibble
+ EVM.Types: SelfDestruct :: Error
+ EVM.Types: StackLimitExceeded :: Error
+ EVM.Types: Storage :: EType
+ EVM.Types: TmpErr :: String -> Error
+ EVM.Types: W256 :: Word256 -> W256
+ EVM.Types: Word512 :: {-# UNPACK #-} !Word256 -> {-# UNPACK #-} !Word256 -> Word512
+ EVM.Types: [AbstractBuf] :: Text -> Expr Buf
+ EVM.Types: [AbstractStore] :: Expr Storage
+ EVM.Types: [AddMod] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Add] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Address] :: Int -> Expr EWord
+ EVM.Types: [And] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Balance] :: Int -> Int -> Expr EWord -> Expr EWord
+ EVM.Types: [BaseFee] :: Expr EWord
+ EVM.Types: [BlockHash] :: Expr EWord -> Expr EWord
+ EVM.Types: [BlockNumber] :: Expr EWord
+ EVM.Types: [BufLength] :: Expr Buf -> Expr EWord
+ EVM.Types: [BufVar] :: Int -> GVar Buf
+ EVM.Types: [CallCode] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> [Expr Log] -> Expr Storage -> Expr EWord
+ EVM.Types: [CallValue] :: Int -> Expr EWord
+ EVM.Types: [Call] :: Expr EWord -> Maybe (Expr EWord) -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> [Expr Log] -> Expr Storage -> Expr EWord
+ EVM.Types: [Caller] :: Int -> Expr EWord
+ EVM.Types: [ChainId] :: Expr EWord
+ EVM.Types: [CodeSize] :: Expr EWord -> Expr EWord
+ EVM.Types: [Coinbase] :: Expr EWord
+ EVM.Types: [ConcreteBuf] :: ByteString -> Expr Buf
+ EVM.Types: [ConcreteStore] :: Map W256 (Map W256 W256) -> Expr Storage
+ EVM.Types: [CopySlice] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr Buf -> Expr Buf -> Expr Buf
+ EVM.Types: [Create2] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr Buf -> [Expr Log] -> Expr Storage -> Expr EWord
+ EVM.Types: [Create] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr Buf -> [Expr Log] -> Expr Storage -> Expr EWord
+ EVM.Types: [DelegeateCall] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord -> [Expr Log] -> Expr Storage -> Expr EWord
+ EVM.Types: [Div] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [EmptyStore] :: Expr Storage
+ EVM.Types: [EqByte] :: Expr Byte -> Expr Byte -> Expr EWord
+ EVM.Types: [Eq] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Exp] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [ExtCodeHash] :: Expr EWord -> Expr EWord
+ EVM.Types: [Failure] :: [Prop] -> Error -> Expr End
+ EVM.Types: [GEq] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [GT] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [GVar] :: GVar a -> Expr a
+ EVM.Types: [GasLimit] :: Expr EWord
+ EVM.Types: [Gas] :: Int -> Int -> Expr EWord
+ EVM.Types: [ITE] :: Expr EWord -> Expr End -> Expr End -> Expr End
+ EVM.Types: [IndexWord] :: Expr EWord -> Expr EWord -> Expr Byte
+ EVM.Types: [IsZero] :: Expr EWord -> Expr EWord
+ EVM.Types: [JoinBytes] :: Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr Byte -> Expr EWord
+ EVM.Types: [Keccak] :: Expr Buf -> Expr EWord
+ EVM.Types: [LEq] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [LT] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [LitByte] :: Word8 -> Expr Byte
+ EVM.Types: [Lit] :: W256 -> Expr EWord
+ EVM.Types: [LogEntry] :: Expr EWord -> Expr Buf -> [Expr EWord] -> Expr Log
+ EVM.Types: [Min] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Mod] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [MulMod] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Mul] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Not] :: Expr EWord -> Expr EWord
+ EVM.Types: [Or] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Origin] :: Expr EWord
+ EVM.Types: [PAnd] :: Prop -> Prop -> Prop
+ EVM.Types: [PBool] :: Bool -> Prop
+ EVM.Types: [PEq] :: forall a. Typeable a => Expr a -> Expr a -> Prop
+ EVM.Types: [PGEq] :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: [PGT] :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: [PLEq] :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: [PLT] :: Expr EWord -> Expr EWord -> Prop
+ EVM.Types: [PNeg] :: Prop -> Prop
+ EVM.Types: [POr] :: Prop -> Prop -> Prop
+ EVM.Types: [PrevRandao] :: Expr EWord
+ EVM.Types: [ReadByte] :: Expr EWord -> Expr Buf -> Expr Byte
+ EVM.Types: [ReadWord] :: Expr EWord -> Expr Buf -> Expr EWord
+ EVM.Types: [Return] :: [Prop] -> Expr Buf -> Expr Storage -> Expr End
+ EVM.Types: [Revert] :: [Prop] -> Expr Buf -> Expr End
+ EVM.Types: [SAR] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SDiv] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SEx] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SGT] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SHA256] :: Expr Buf -> Expr EWord
+ EVM.Types: [SHL] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SHR] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SLT] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SLoad] :: Expr EWord -> Expr EWord -> Expr Storage -> Expr EWord
+ EVM.Types: [SMod] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [SStore] :: Expr EWord -> Expr EWord -> Expr EWord -> Expr Storage -> Expr Storage
+ EVM.Types: [SelfBalance] :: Int -> Int -> Expr EWord
+ EVM.Types: [StoreVar] :: Int -> GVar Storage
+ EVM.Types: [Sub] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [Timestamp] :: Expr EWord
+ EVM.Types: [Var] :: Text -> Expr EWord
+ EVM.Types: [WriteByte] :: Expr EWord -> Expr Byte -> Expr Buf -> Expr Buf
+ EVM.Types: [WriteWord] :: Expr EWord -> Expr EWord -> Expr Buf -> Expr Buf
+ EVM.Types: [Xor] :: Expr EWord -> Expr EWord -> Expr EWord
+ EVM.Types: [addressWord160] :: Addr -> Word160
+ EVM.Types: abiKeccak :: ByteString -> Word32
+ EVM.Types: addrField :: Object -> Key -> Parser Addr
+ EVM.Types: addrFieldMaybe :: Object -> Key -> Parser (Maybe Addr)
+ EVM.Types: asBE :: Integral a => a -> ByteString
+ EVM.Types: byteAt :: (Bits a, Bits b, Integral a, Num b) => a -> Int -> b
+ EVM.Types: concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]
+ EVM.Types: data EType
+ EVM.Types: data Error
+ EVM.Types: data Expr (a :: EType)
+ EVM.Types: data GVar (a :: EType)
+ EVM.Types: data Int512
+ EVM.Types: data Prop
+ EVM.Types: data Word512
+ EVM.Types: dataField :: Object -> Key -> Parser ByteString
+ EVM.Types: fromBE :: Integral a => ByteString -> a
+ EVM.Types: fromWord512 :: Word512 -> W256
+ EVM.Types: hexByteString :: String -> ByteString -> ByteString
+ EVM.Types: hexText :: Text -> ByteString
+ EVM.Types: hi :: Word8 -> Nibble
+ EVM.Types: infix 4 ./=
+ EVM.Types: infixr 2 .||
+ EVM.Types: infixr 3 .&&
+ EVM.Types: instance Data.Aeson.Types.FromJSON.FromJSON EVM.Types.Addr
+ EVM.Types: instance Data.Aeson.Types.FromJSON.FromJSON EVM.Types.W256
+ EVM.Types: instance Data.Aeson.Types.FromJSON.FromJSONKey EVM.Types.Addr
+ EVM.Types: instance Data.Aeson.Types.FromJSON.FromJSONKey EVM.Types.W256
+ EVM.Types: instance Data.Aeson.Types.ToJSON.ToJSON EVM.Types.ByteStringS
+ EVM.Types: instance Data.Aeson.Types.ToJSON.ToJSON EVM.Types.W256
+ EVM.Types: instance Data.BinaryWord.BinaryWord EVM.Types.Int512
+ EVM.Types: instance Data.BinaryWord.BinaryWord EVM.Types.Word512
+ EVM.Types: instance Data.Data.Data EVM.Types.Int512
+ EVM.Types: instance Data.Data.Data EVM.Types.Word512
+ EVM.Types: instance Data.DoubleWord.Base.DoubleWord EVM.Types.Int512
+ EVM.Types: instance Data.DoubleWord.Base.DoubleWord EVM.Types.Word512
+ EVM.Types: instance Data.Hashable.Class.Hashable EVM.Types.Int512
+ EVM.Types: instance Data.Hashable.Class.Hashable EVM.Types.Word512
+ EVM.Types: instance GHC.Bits.Bits EVM.Types.Addr
+ EVM.Types: instance GHC.Bits.Bits EVM.Types.Int512
+ EVM.Types: instance GHC.Bits.Bits EVM.Types.W256
+ EVM.Types: instance GHC.Bits.Bits EVM.Types.Word512
+ EVM.Types: instance GHC.Bits.FiniteBits EVM.Types.Addr
+ EVM.Types: instance GHC.Bits.FiniteBits EVM.Types.Int512
+ EVM.Types: instance GHC.Bits.FiniteBits EVM.Types.W256
+ EVM.Types: instance GHC.Bits.FiniteBits EVM.Types.Word512
+ EVM.Types: instance GHC.Classes.Eq (EVM.Types.Expr a)
+ EVM.Types: instance GHC.Classes.Eq (EVM.Types.GVar a)
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.Addr
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.ByteStringS
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.Error
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.Int512
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.Nibble
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.Prop
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.W256
+ EVM.Types: instance GHC.Classes.Eq EVM.Types.Word512
+ EVM.Types: instance GHC.Classes.Ord (EVM.Types.Expr a)
+ EVM.Types: instance GHC.Classes.Ord (EVM.Types.GVar a)
+ EVM.Types: instance GHC.Classes.Ord EVM.Types.Addr
+ EVM.Types: instance GHC.Classes.Ord EVM.Types.Error
+ EVM.Types: instance GHC.Classes.Ord EVM.Types.Int512
+ EVM.Types: instance GHC.Classes.Ord EVM.Types.Nibble
+ EVM.Types: instance GHC.Classes.Ord EVM.Types.Prop
+ EVM.Types: instance GHC.Classes.Ord EVM.Types.W256
+ EVM.Types: instance GHC.Classes.Ord EVM.Types.Word512
+ EVM.Types: instance GHC.Enum.Bounded EVM.Types.Int512
+ EVM.Types: instance GHC.Enum.Bounded EVM.Types.Nibble
+ EVM.Types: instance GHC.Enum.Bounded EVM.Types.W256
+ EVM.Types: instance GHC.Enum.Bounded EVM.Types.Word512
+ EVM.Types: instance GHC.Enum.Enum EVM.Types.Addr
+ EVM.Types: instance GHC.Enum.Enum EVM.Types.Int512
+ EVM.Types: instance GHC.Enum.Enum EVM.Types.Nibble
+ EVM.Types: instance GHC.Enum.Enum EVM.Types.W256
+ EVM.Types: instance GHC.Enum.Enum EVM.Types.Word512
+ EVM.Types: instance GHC.Generics.Generic EVM.Types.Addr
+ EVM.Types: instance GHC.Generics.Generic EVM.Types.Int512
+ EVM.Types: instance GHC.Generics.Generic EVM.Types.Nibble
+ EVM.Types: instance GHC.Generics.Generic EVM.Types.W256
+ EVM.Types: instance GHC.Generics.Generic EVM.Types.Word512
+ EVM.Types: instance GHC.Ix.Ix EVM.Types.Int512
+ EVM.Types: instance GHC.Ix.Ix EVM.Types.Word512
+ EVM.Types: instance GHC.Num.Num EVM.Types.Addr
+ EVM.Types: instance GHC.Num.Num EVM.Types.Int512
+ EVM.Types: instance GHC.Num.Num EVM.Types.Nibble
+ EVM.Types: instance GHC.Num.Num EVM.Types.W256
+ EVM.Types: instance GHC.Num.Num EVM.Types.Word512
+ EVM.Types: instance GHC.Read.Read EVM.Types.Addr
+ EVM.Types: instance GHC.Read.Read EVM.Types.Int512
+ EVM.Types: instance GHC.Read.Read EVM.Types.W256
+ EVM.Types: instance GHC.Read.Read EVM.Types.Word512
+ EVM.Types: instance GHC.Real.Integral EVM.Types.Addr
+ EVM.Types: instance GHC.Real.Integral EVM.Types.Int512
+ EVM.Types: instance GHC.Real.Integral EVM.Types.Nibble
+ EVM.Types: instance GHC.Real.Integral EVM.Types.W256
+ EVM.Types: instance GHC.Real.Integral EVM.Types.Word512
+ EVM.Types: instance GHC.Real.Real EVM.Types.Addr
+ EVM.Types: instance GHC.Real.Real EVM.Types.Int512
+ EVM.Types: instance GHC.Real.Real EVM.Types.Nibble
+ EVM.Types: instance GHC.Real.Real EVM.Types.W256
+ EVM.Types: instance GHC.Real.Real EVM.Types.Word512
+ EVM.Types: instance GHC.Show.Show (EVM.Types.Expr a)
+ EVM.Types: instance GHC.Show.Show (EVM.Types.GVar a)
+ EVM.Types: instance GHC.Show.Show EVM.Types.Addr
+ EVM.Types: instance GHC.Show.Show EVM.Types.ByteStringS
+ EVM.Types: instance GHC.Show.Show EVM.Types.Error
+ EVM.Types: instance GHC.Show.Show EVM.Types.Int512
+ EVM.Types: instance GHC.Show.Show EVM.Types.Nibble
+ EVM.Types: instance GHC.Show.Show EVM.Types.Prop
+ EVM.Types: instance GHC.Show.Show EVM.Types.W256
+ EVM.Types: instance GHC.Show.Show EVM.Types.Word512
+ EVM.Types: instance Options.Generic.ParseField EVM.Types.Addr
+ EVM.Types: instance Options.Generic.ParseField EVM.Types.W256
+ EVM.Types: instance Options.Generic.ParseFields EVM.Types.Addr
+ EVM.Types: instance Options.Generic.ParseFields EVM.Types.W256
+ EVM.Types: instance Options.Generic.ParseRecord EVM.Types.Addr
+ EVM.Types: instance Options.Generic.ParseRecord EVM.Types.W256
+ EVM.Types: keccak :: Expr Buf -> Expr EWord
+ EVM.Types: keccak' :: ByteString -> W256
+ EVM.Types: keccakBytes :: ByteString -> ByteString
+ EVM.Types: lo :: Word8 -> Nibble
+ EVM.Types: maybeLitWord :: Expr EWord -> Maybe W256
+ EVM.Types: newtype Addr
+ EVM.Types: newtype ByteStringS
+ EVM.Types: newtype Nibble
+ EVM.Types: newtype W256
+ EVM.Types: num :: (Integral a, Num b) => a -> b
+ EVM.Types: packNibbles :: [Nibble] -> ByteString
+ EVM.Types: padLeft :: Int -> ByteString -> ByteString
+ EVM.Types: padLeft' :: Int -> Vector (Expr Byte) -> Vector (Expr Byte)
+ EVM.Types: padLeftStr :: Int -> String -> String
+ EVM.Types: padRight :: Int -> ByteString -> ByteString
+ EVM.Types: padRight' :: Int -> String -> String
+ EVM.Types: readN :: Integral a => String -> a
+ EVM.Types: readNull :: Read a => a -> String -> a
+ EVM.Types: regexMatches :: Text -> Text -> Bool
+ EVM.Types: strip0x :: ByteString -> ByteString
+ EVM.Types: strip0x' :: String -> String
+ EVM.Types: toByte :: Nibble -> Nibble -> Word8
+ EVM.Types: toChecksumAddress :: String -> String
+ EVM.Types: toInt :: W256 -> Maybe Int
+ EVM.Types: toWord512 :: W256 -> Word512
+ EVM.Types: toWord64 :: W256 -> Maybe Word64
+ EVM.Types: unlit :: Expr EWord -> Maybe W256
+ EVM.Types: unlitByte :: Expr Byte -> Maybe Word8
+ EVM.Types: unpackNibbles :: ByteString -> [Nibble]
+ EVM.Types: word :: ByteString -> W256
+ EVM.Types: word160Bytes :: Addr -> ByteString
+ EVM.Types: word256 :: ByteString -> Word256
+ EVM.Types: word256Bytes :: W256 -> ByteString
+ EVM.Types: word32 :: [Word8] -> Word32
+ EVM.Types: word64Field :: Object -> Key -> Parser Word64
+ EVM.Types: wordField :: Object -> Key -> Parser W256
+ EVM.UnitTest: OpLocation :: Contract -> Int -> OpLocation
+ EVM.UnitTest: TestVMParams :: Addr -> Addr -> Addr -> Word64 -> Word64 -> W256 -> W256 -> W256 -> Addr -> W256 -> W256 -> Word64 -> W256 -> W256 -> W256 -> W256 -> TestVMParams
+ EVM.UnitTest: UnitTestOptions :: RpcInfo -> SolverGroup -> Maybe Int -> Maybe Integer -> Maybe Integer -> Bool -> Maybe Int -> Maybe Natural -> Maybe Text -> Maybe Text -> Text -> Int -> Maybe (Text, ByteString) -> (VM -> VM) -> DappInfo -> TestVMParams -> Bool -> UnitTestOptions
+ EVM.UnitTest: [askSmtIters] :: UnitTestOptions -> Maybe Integer
+ EVM.UnitTest: [covMatch] :: UnitTestOptions -> Maybe Text
+ EVM.UnitTest: [dapp] :: UnitTestOptions -> DappInfo
+ EVM.UnitTest: [ffiAllowed] :: UnitTestOptions -> Bool
+ EVM.UnitTest: [fuzzRuns] :: UnitTestOptions -> Int
+ EVM.UnitTest: [match] :: UnitTestOptions -> Text
+ EVM.UnitTest: [maxDepth] :: UnitTestOptions -> Maybe Int
+ EVM.UnitTest: [maxIter] :: UnitTestOptions -> Maybe Integer
+ EVM.UnitTest: [replay] :: UnitTestOptions -> Maybe (Text, ByteString)
+ EVM.UnitTest: [rpcInfo] :: UnitTestOptions -> RpcInfo
+ EVM.UnitTest: [smtDebug] :: UnitTestOptions -> Bool
+ EVM.UnitTest: [smtTimeout] :: UnitTestOptions -> Maybe Natural
+ EVM.UnitTest: [solver] :: UnitTestOptions -> Maybe Text
+ EVM.UnitTest: [solvers] :: UnitTestOptions -> SolverGroup
+ EVM.UnitTest: [srcContract] :: OpLocation -> Contract
+ EVM.UnitTest: [srcOpIx] :: OpLocation -> Int
+ EVM.UnitTest: [testAddress] :: TestVMParams -> Addr
+ EVM.UnitTest: [testBalanceCreate] :: TestVMParams -> W256
+ EVM.UnitTest: [testBaseFee] :: TestVMParams -> W256
+ EVM.UnitTest: [testCaller] :: TestVMParams -> Addr
+ EVM.UnitTest: [testChainId] :: TestVMParams -> W256
+ EVM.UnitTest: [testCoinbase] :: TestVMParams -> Addr
+ EVM.UnitTest: [testGasCall] :: TestVMParams -> Word64
+ EVM.UnitTest: [testGasCreate] :: TestVMParams -> Word64
+ EVM.UnitTest: [testGaslimit] :: TestVMParams -> Word64
+ EVM.UnitTest: [testGasprice] :: TestVMParams -> W256
+ EVM.UnitTest: [testMaxCodeSize] :: TestVMParams -> W256
+ EVM.UnitTest: [testNumber] :: TestVMParams -> W256
+ EVM.UnitTest: [testOrigin] :: TestVMParams -> Addr
+ EVM.UnitTest: [testParams] :: UnitTestOptions -> TestVMParams
+ EVM.UnitTest: [testPrevrandao] :: TestVMParams -> W256
+ EVM.UnitTest: [testPriorityFee] :: TestVMParams -> W256
+ EVM.UnitTest: [testTimestamp] :: TestVMParams -> W256
+ EVM.UnitTest: [verbose] :: UnitTestOptions -> Maybe Int
+ EVM.UnitTest: [vmModifier] :: UnitTestOptions -> VM -> VM
+ EVM.UnitTest: abiCall :: TestVMParams -> Either (Text, AbiValue) ByteString -> EVM ()
+ EVM.UnitTest: checkFailures :: UnitTestOptions -> ABIMethod -> Bool -> Stepper Bool
+ EVM.UnitTest: checkSymFailures :: UnitTestOptions -> Stepper VM
+ EVM.UnitTest: coverageForUnitTestContract :: UnitTestOptions -> Map Text SolcContract -> SourceCache -> (Text, [(Test, [AbiType])]) -> IO (MultiSet SrcMap)
+ EVM.UnitTest: coverageReport :: DappInfo -> MultiSet SrcMap -> Map Text (Vector (Int, ByteString))
+ EVM.UnitTest: currentOpLocation :: VM -> OpLocation
+ EVM.UnitTest: dappTest :: UnitTestOptions -> String -> Maybe String -> IO Bool
+ EVM.UnitTest: data OpLocation
+ EVM.UnitTest: data TestVMParams
+ EVM.UnitTest: data UnitTestOptions
+ EVM.UnitTest: decodeCalls :: ByteString -> [ExploreTx]
+ EVM.UnitTest: defaultBalanceForTestContract :: W256
+ EVM.UnitTest: defaultGasForCreating :: Word64
+ EVM.UnitTest: defaultGasForInvoking :: Word64
+ EVM.UnitTest: defaultMaxCodeSize :: W256
+ EVM.UnitTest: execSymTest :: UnitTestOptions -> ABIMethod -> (Expr Buf, [Prop]) -> Stepper (Expr End)
+ EVM.UnitTest: execTest :: UnitTestOptions -> VM -> ABIMethod -> AbiValue -> IO (Bool, VM)
+ EVM.UnitTest: execTestStepper :: UnitTestOptions -> ABIMethod -> AbiValue -> Stepper Bool
+ EVM.UnitTest: execWithCoverage :: StateT CoverageState IO VMResult
+ EVM.UnitTest: explorationStepper :: UnitTestOptions -> ABIMethod -> [ExploreTx] -> [Addr] -> RLP -> Int -> Stepper (Bool, RLP)
+ EVM.UnitTest: exploreRun :: UnitTestOptions -> VM -> ABIMethod -> [ExploreTx] -> IO (Text, Either Text Text, VM)
+ EVM.UnitTest: exploreStep :: UnitTestOptions -> ByteString -> Stepper Bool
+ EVM.UnitTest: failOutput :: VM -> UnitTestOptions -> Text -> Text
+ EVM.UnitTest: formatTestLog :: (?context :: DappContext) => Map W256 Event -> Expr Log -> Maybe Text
+ EVM.UnitTest: formatTestLogs :: (?context :: DappContext) => Map W256 Event -> [Expr Log] -> Text
+ EVM.UnitTest: fuzzRun :: UnitTestOptions -> VM -> Text -> [AbiType] -> IO (Text, Either Text Text, VM)
+ EVM.UnitTest: fuzzTest :: UnitTestOptions -> Text -> [AbiType] -> VM -> Property
+ EVM.UnitTest: getParametersFromEnvironmentVariables :: Maybe Text -> IO TestVMParams
+ EVM.UnitTest: getTargetContracts :: UnitTestOptions -> Stepper [Addr]
+ EVM.UnitTest: indentLines :: Int -> Text -> Text
+ EVM.UnitTest: initialExplorationStepper :: UnitTestOptions -> ABIMethod -> [ExploreTx] -> [Addr] -> Int -> Stepper (Bool, RLP)
+ EVM.UnitTest: initialUnitTestVm :: UnitTestOptions -> SolcContract -> VM
+ EVM.UnitTest: initializeUnitTest :: UnitTestOptions -> SolcContract -> Stepper ()
+ EVM.UnitTest: instance GHC.Classes.Eq EVM.UnitTest.OpLocation
+ EVM.UnitTest: instance GHC.Classes.Ord EVM.UnitTest.OpLocation
+ EVM.UnitTest: instance GHC.Show.Show EVM.UnitTest.OpLocation
+ EVM.UnitTest: interpretWithCoverage :: UnitTestOptions -> Stepper a -> StateT CoverageState IO a
+ EVM.UnitTest: makeTxCall :: TestVMParams -> (Expr Buf, [Prop]) -> EVM ()
+ EVM.UnitTest: makeVeriOpts :: UnitTestOptions -> VeriOpts
+ EVM.UnitTest: passOutput :: VM -> UnitTestOptions -> Text -> Text
+ EVM.UnitTest: prettyCalldata :: (?context :: DappContext) => SMTCex -> Expr Buf -> Text -> [AbiType] -> Text
+ EVM.UnitTest: runOne :: UnitTestOptions -> VM -> ABIMethod -> AbiValue -> IO (Text, Either Text Text, VM)
+ EVM.UnitTest: runTest :: UnitTestOptions -> VM -> (Test, [AbiType]) -> IO (Text, Either Text Text, VM)
+ EVM.UnitTest: runUnitTest :: UnitTestOptions -> ABIMethod -> AbiValue -> Stepper Bool
+ EVM.UnitTest: runUnitTestContract :: UnitTestOptions -> Map Text SolcContract -> (Text, [(Test, [AbiType])]) -> IO [(Bool, VM)]
+ EVM.UnitTest: runWithCoverage :: StateT CoverageState IO VM
+ EVM.UnitTest: showCalldata :: (?context :: DappContext) => SMTCex -> [AbiType] -> Expr Buf -> Text
+ EVM.UnitTest: showVal :: AbiValue -> Text
+ EVM.UnitTest: srcMapForOpLocation :: DappInfo -> OpLocation -> Maybe SrcMap
+ EVM.UnitTest: symFailure :: UnitTestOptions -> Text -> Expr Buf -> [AbiType] -> [(Expr End, SMTCex)] -> Text
+ EVM.UnitTest: symRun :: UnitTestOptions -> VM -> Text -> [AbiType] -> IO (Text, Either Text Text, VM)
+ EVM.UnitTest: tick :: Text -> IO ()
+ EVM.UnitTest: type ABIMethod = Text
+ EVM.UnitTest: type CoverageState = (VM, MultiSet OpLocation)
+ EVM.UnitTest: type ExploreTx = (Addr, Addr, ByteString, W256)
+ EVM.UnitTest: word32Bytes :: Word32 -> ByteString
Files
- CHANGELOG.md +24/−2
- Setup.hs +0/−2
- hevm-cli/hevm-cli.hs +25/−215
- hevm.cabal +39/−35
- run-blockchain-tests +0/−150
- run-consensus-tests +0/−110
- src/EVM.hs +88/−66
- src/EVM/ABI.hs +10/−8
- src/EVM/Dapp.hs +7/−3
- src/EVM/Dev.hs +2/−3
- src/EVM/Exec.hs +1/−1
- src/EVM/Expr.hs +5/−2
- src/EVM/Facts.hs +2/−3
- src/EVM/Fetch.hs +3/−4
- src/EVM/Flatten.hs +0/−466
- src/EVM/Format.hs +23/−15
- src/EVM/SMT.hs +3/−4
- src/EVM/Solidity.hs +20/−16
- src/EVM/SymExec.hs +19/−30
- src/EVM/TTY.hs +215/−231
- src/EVM/Transaction.hs +6/−6
- src/EVM/Traversals.hs +3/−28
- src/EVM/Types.hs +27/−8
- src/EVM/UnitTest.hs +27/−11
- src/EVM/VMTest.hs +0/−374
- test/BlockchainTests.hs +466/−0
- test/rpc.hs +6/−2
- test/test.hs +42/−22
CHANGELOG.md view
@@ -5,6 +5,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.50.1] - 2022-12-29++## Fixed++- `hevm exec` no longer fails with `hevm: No match in record selector smttimeout`+- the `gas`, `gaslimit`, `priorityfee`, and `gasprice` cli options are now respected+- cleaner formatting for the gas value in the visual debugger++### Changed++- we now build with ghc 9.2.4 by default+- various perf improvements for concrete execution ([#157](https://github.com/ethereum/hevm/pull/157), [#152](https://github.com/ethereum/hevm/pull/152))+ ## [0.50.0] - 2022-12-19 ### Changed@@ -13,13 +26,22 @@ symbolic execution decompiles bytecode into a custom IR, and smt queries are constructed based on the structure of the term in this IR. -This gives us much deeper control over the encoding, and makes the addition of custom static-analysis and simplification passes much easier to implement.+This gives us much deeper control over the encoding, and makes custom static analysis and+simplification passes much easier to implement. The symbolic execution engine is now parallel by default, and will distribute granular SMT queries across a pool of solvers, allowing analysis to be scaled out horizontally across many CPUs. more details can be found in the [architecuture](../../architecture.md) docs.++### Removed++The following cli commands have been removed:++- `abiencode`+- `rlp`+- `flatten`+- `strip-metadata` ## [0.49.0] - 2021-11-12
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
hevm-cli/hevm-cli.hs view
@@ -1,9 +1,7 @@ -- Main file of the hevm CLI program -{-# Language CPP #-} {-# Language DataKinds #-} {-# Language DeriveAnyClass #-}-{-# Language GADTs #-} module Main where @@ -14,13 +12,8 @@ import qualified EVM.Fetch import qualified EVM.Stepper --import qualified EVM.VMTest as VMTest-- import EVM.SymExec import EVM.Debug-import EVM.ABI import qualified EVM.Expr as Expr import EVM.SMT import qualified EVM.TTY as TTY@@ -31,36 +24,25 @@ import EVM.Dapp (findUnitTests, dappInfo, DappInfo, emptyDapp) import GHC.Natural import EVM.Format (showTraceTree, formatExpr)-import qualified EVM.Patricia as Patricia-import Data.Map (Map)+import Data.Word (Word64) import qualified EVM.Facts as Facts import qualified EVM.Facts.Git as Git import qualified EVM.UnitTest -import GHC.Stack import GHC.Conc-import Control.Concurrent.Async (async, waitCatch) import Control.Lens hiding (pre, passing) import Control.Monad (void, when, forM_, unless) import Control.Monad.State.Strict (execStateT, liftIO) import Data.ByteString (ByteString) import Data.List (intercalate, isSuffixOf) import Data.Text (unpack, pack)-import Data.Text.Encoding (encodeUtf8)-import Data.Maybe (fromMaybe, fromJust, mapMaybe)+import Data.Maybe (fromMaybe, mapMaybe) import Data.Version (showVersion) import Data.DoubleWord (Word256)-import System.IO (hFlush, stdout, stderr)+import System.IO (stderr) import System.Directory (withCurrentDirectory, listDirectory) import System.Exit (exitFailure, exitWith, ExitCode(..))-import System.Process (callProcess)-import qualified Data.Aeson as JSON-import qualified Data.Aeson.Types as JSON-import Data.Aeson (FromJSON (..), (.:))-import Data.Aeson.Lens hiding (values)-import qualified Data.Vector as V-import qualified Data.ByteString.Lazy as Lazy import qualified Data.ByteString as ByteString import qualified Data.ByteString.Char8 as Char8@@ -68,11 +50,11 @@ import qualified Data.Map as Map import qualified Data.Text as T import qualified Data.Text.IO as T-import qualified System.Timeout as Timeout import qualified Paths_hevm as Paths import Options.Generic as Options+import qualified EVM.Transaction -- This record defines the program's command-line options -- automatically via the `optparse-generic` package.@@ -87,12 +69,12 @@ , coinbase :: w ::: Maybe Addr <?> "Block: coinbase" , value :: w ::: Maybe W256 <?> "Tx: Eth amount" , nonce :: w ::: Maybe W256 <?> "Nonce of origin"- , gas :: w ::: Maybe W256 <?> "Tx: gas amount"+ , gas :: w ::: Maybe Word64 <?> "Tx: gas amount" , number :: w ::: Maybe W256 <?> "Block: number" , timestamp :: w ::: Maybe W256 <?> "Block: timestamp" , basefee :: w ::: Maybe W256 <?> "Block: base fee" , priorityFee :: w ::: Maybe W256 <?> "Tx: priority fee"- , gaslimit :: w ::: Maybe W256 <?> "Tx: gas limit"+ , gaslimit :: w ::: Maybe Word64 <?> "Tx: gas limit" , gasprice :: w ::: Maybe W256 <?> "Tx: gas price" , create :: w ::: Bool <?> "Tx: creation" , maxcodesize :: w ::: Maybe W256 <?> "Block: max code size"@@ -142,12 +124,12 @@ , coinbase :: w ::: Maybe Addr <?> "Block: coinbase" , value :: w ::: Maybe W256 <?> "Tx: Eth amount" , nonce :: w ::: Maybe W256 <?> "Nonce of origin"- , gas :: w ::: Maybe W256 <?> "Tx: gas amount"+ , gas :: w ::: Maybe Word64 <?> "Tx: gas amount" , number :: w ::: Maybe W256 <?> "Block: number" , timestamp :: w ::: Maybe W256 <?> "Block: timestamp" , basefee :: w ::: Maybe W256 <?> "Block: base fee" , priorityFee :: w ::: Maybe W256 <?> "Tx: priority fee"- , gaslimit :: w ::: Maybe W256 <?> "Tx: gas limit"+ , gaslimit :: w ::: Maybe Word64 <?> "Tx: gas limit" , gasprice :: w ::: Maybe W256 <?> "Tx: gas price" , create :: w ::: Bool <?> "Tx: creation" , maxcodesize :: w ::: Maybe W256 <?> "Block: max code size"@@ -185,25 +167,6 @@ , maxIterations :: w ::: Maybe Integer <?> "Number of times we may revisit a particular branching point" , askSmtIterations :: w ::: Maybe Integer <?> "Number of times we may revisit a particular branching point before we consult the smt solver to check reachability (default: 5)" }- | BcTest -- Run an Ethereum Blockchain/GeneralState test- { file :: w ::: String <?> "Path to .json test file"- , test :: w ::: [String] <?> "Test case filter - only run specified test method(s)"- , debug :: w ::: Bool <?> "Run interactively"- , jsontrace :: w ::: Bool <?> "Print json trace output at every step"- , diff :: w ::: Bool <?> "Print expected vs. actual state on failure"- , timeout :: w ::: Maybe Int <?> "Execution timeout (default: 10 sec.)"- }- | Compliance -- Run Ethereum Blockchain compliance report- { tests :: w ::: String <?> "Path to Ethereum Tests directory"- , group :: w ::: Maybe String <?> "Report group to run: VM or Blockchain (default: Blockchain)"- , match :: w ::: Maybe String <?> "Test case filter - only run methods matching regex"- , skip :: w ::: Maybe String <?> "Test case filter - skip tests containing string"- , html :: w ::: Bool <?> "Output html report"- , timeout :: w ::: Maybe Int <?> "Execution timeout (default: 10 sec.)"- }- | MerkleTest -- Insert a set of key values and check against the given root- { file :: w ::: String <?> "Path to .json test file"- } | Version deriving (Options.Generic)@@ -299,8 +262,6 @@ Equivalence {} -> equivalence cmd Exec {} -> launchExec cmd- BcTest {} ->- launchTest cmd DappTest {} -> withCurrentDirectory root $ do cores <- num <$> getNumProcessors@@ -314,26 +275,7 @@ (False, Debug) -> liftIO $ TTY.main testOpts root testFile (False, JsonTrace) -> error "json traces not implemented for dappTest" (True, _) -> liftIO $ dappCoverage testOpts (optsMode cmd) testFile- Compliance {} ->- case (group cmd) of- Just "Blockchain" -> launchScript "/run-blockchain-tests" cmd- Just "VM" -> launchScript "/run-consensus-tests" cmd- _ -> launchScript "/run-blockchain-tests" cmd- MerkleTest {} -> merkleTest cmd -launchScript :: String -> Command Options.Unwrapped -> IO ()-launchScript script cmd =- withCurrentDirectory (tests cmd) $ do- dataDir <- Paths.getDataDir- callProcess "bash"- [ dataDir ++ script- , "."- , show (html cmd)- , fromMaybe "" (match cmd)- , fromMaybe "" (skip cmd)- , show $ fromMaybe 10 (timeout cmd)- ]- findJsonFile :: Maybe String -> IO String findJsonFile (Just s) = pure s findJsonFile Nothing = do@@ -377,19 +319,6 @@ putStrLn $ "Not equivalent. Counterexample(s):" <> show res exitFailure -checkForVMErrors :: [EVM.VM] -> [String]-checkForVMErrors [] = []-checkForVMErrors (vm:vms) =- case view EVM.result vm of- Just (EVM.VMFailure (EVM.UnexpectedSymbolicArg pc msg _)) ->- ("Unexpected symbolic argument at opcode: "- <> show pc- <> ". "- <> msg- ) : checkForVMErrors vms- _ ->- checkForVMErrors vms- getSrcInfo :: Command Options.Unwrapped -> IO DappInfo getSrcInfo cmd = let root = fromMaybe "." (dappRoot cmd)@@ -536,8 +465,8 @@ launchExec cmd = do dapp <- getSrcInfo cmd vm <- vmFromCommand cmd- smtjobs <- fromIntegral <$> getNumProcessors- withSolvers Z3 smtjobs (smttimeout cmd) $ \solvers -> do+ -- TODO: we shouldn't need solvers to execute this code+ withSolvers Z3 0 Nothing $ \solvers -> do case optsMode cmd of Run -> do vm' <- execStateT (EVM.Stepper.interpret (EVM.Fetch.oracle solvers rpcinfo) . void $ EVM.Stepper.execFully) vm@@ -574,65 +503,6 @@ where block' = maybe EVM.Fetch.Latest EVM.Fetch.BlockNumber (block cmd) rpcinfo = (,) block' <$> rpc cmd -data Testcase = Testcase {- _entries :: [(Text, Maybe Text)],- _root :: Text-} deriving Show--parseTups :: JSON.Value -> JSON.Parser [(Text, Maybe Text)]-parseTups (JSON.Array arr) = do- tupList <- mapM parseJSON (V.toList arr)- mapM (\[k, v] -> do- rhs <- parseJSON v- lhs <- parseJSON k- return (lhs, rhs))- tupList-parseTups invalid = JSON.typeMismatch "Malformed array" invalid---parseTrieTest :: JSON.Object -> JSON.Parser Testcase-parseTrieTest p = do- kvlist <- p .: "in"- entries <- parseTups kvlist- root <- p .: "root"- return $ Testcase entries root--instance FromJSON Testcase where- parseJSON (JSON.Object p) = parseTrieTest p- parseJSON invalid = JSON.typeMismatch "Merkle test case" invalid--parseTrieTests :: Lazy.ByteString -> Either String (Map String Testcase)-parseTrieTests = JSON.eitherDecode'--merkleTest :: Command Options.Unwrapped -> IO ()-merkleTest cmd = do- parsed <- parseTrieTests <$> LazyByteString.readFile (file cmd)- case parsed of- Left err -> print err- Right testcases -> mapM_ runMerkleTest testcases--runMerkleTest :: Testcase -> IO ()-runMerkleTest (Testcase entries root) =- case Patricia.calcRoot entries' of- Nothing ->- error "Test case failed"- Just n ->- case n == strip0x (hexText root) of- True ->- putStrLn "Test case success"- False ->- error ("Test case failure; expected " <> show root- <> " but got " <> show (ByteStringS n))- where entries' = fmap (\(k, v) ->- (tohexOrText k,- tohexOrText (fromMaybe mempty v)))- entries--tohexOrText :: Text -> ByteString-tohexOrText s = case "0x" `Char8.isPrefixOf` encodeUtf8 s of- True -> hexText s- False -> encodeUtf8 s- -- | Creates a (concrete) VM from command line options vmFromCommand :: Command Options.Unwrapped -> IO EVM.VM vmFromCommand cmd = do@@ -680,7 +550,7 @@ Just t -> t Nothing -> error "unexpected symbolic timestamp when executing vm test" - return $ VMTest.initTx $ withCache (vm0 baseFee miner ts' blockNum prevRan contract)+ return $ EVM.Transaction.initTx $ withCache (vm0 baseFee miner ts' blockNum prevRan contract) where block' = maybe EVM.Fetch.Latest EVM.Fetch.BlockNumber (block cmd) value' = word value 0@@ -690,7 +560,7 @@ decipher = hexByteString "bytes" . strip0x mkCode bs = if create cmd then EVM.InitCode bs mempty- else EVM.RuntimeCode (fromJust $ Expr.toList (ConcreteBuf bs))+ else EVM.RuntimeCode (EVM.ConcreteRuntimeCode bs) address' = if create cmd then addr address (createAddress origin' (word nonce 0)) else addr address 0xacab@@ -702,15 +572,15 @@ , EVM.vmoptAddress = address' , EVM.vmoptCaller = litAddr caller' , EVM.vmoptOrigin = origin'- , EVM.vmoptGas = 0+ , EVM.vmoptGas = word64 gas 0xffffffffffffffff , EVM.vmoptBaseFee = baseFee- , EVM.vmoptPriorityFee = 0- , EVM.vmoptGaslimit = 0+ , EVM.vmoptPriorityFee = word priorityFee 0+ , EVM.vmoptGaslimit = word64 gaslimit 0xffffffffffffffff , EVM.vmoptCoinbase = addr coinbase miner , EVM.vmoptNumber = word number blockNum , EVM.vmoptTimestamp = Lit $ word timestamp ts- , EVM.vmoptBlockGaslimit = 0- , EVM.vmoptGasprice = 0+ , EVM.vmoptBlockGaslimit = word64 gaslimit 0xffffffffffffffff+ , EVM.vmoptGasprice = word gasprice 0 , EVM.vmoptMaxCodeSize = word maxcodesize 0xffffffff , EVM.vmoptPrevRandao = word prevRandao prevRan , EVM.vmoptSchedule = FeeSchedule.berlin@@ -721,6 +591,7 @@ , EVM.vmoptAllowFFI = False } word f def = fromMaybe def (f cmd)+ word64 f def = fromMaybe def (f cmd) addr f def = fromMaybe def (f cmd) bytes f def = maybe def decipher (f cmd) @@ -776,7 +647,7 @@ (_, _, Nothing) -> error "must provide at least (rpc + address) or code" - return $ (VMTest.initTx $ withCache $ vm0 baseFee miner ts blockNum prevRan calldata' callvalue' caller' contract')+ return $ (EVM.Transaction.initTx $ withCache $ vm0 baseFee miner ts blockNum prevRan calldata' callvalue' caller' contract') & set (EVM.env . EVM.storage) store where@@ -785,7 +656,7 @@ origin' = addr origin 0 mkCode bs = if create cmd then EVM.InitCode bs mempty- else EVM.RuntimeCode (fromJust . Expr.toList $ ConcreteBuf bs)+ else EVM.RuntimeCode (EVM.ConcreteRuntimeCode bs) address' = if create cmd then addr address (createAddress origin' (word nonce 0)) else addr address 0xacab@@ -796,15 +667,15 @@ , EVM.vmoptAddress = address' , EVM.vmoptCaller = caller' , EVM.vmoptOrigin = origin'- , EVM.vmoptGas = 0xffffffffffffffff- , EVM.vmoptGaslimit = 0xffffffffffffffff+ , EVM.vmoptGas = word64 gas 0xffffffffffffffff+ , EVM.vmoptGaslimit = word64 gaslimit 0xffffffffffffffff , EVM.vmoptBaseFee = baseFee , EVM.vmoptPriorityFee = word priorityFee 0 , EVM.vmoptCoinbase = addr coinbase miner , EVM.vmoptNumber = word number blockNum , EVM.vmoptTimestamp = ts- , EVM.vmoptBlockGaslimit = 0- , EVM.vmoptGasprice = 0+ , EVM.vmoptBlockGaslimit = word64 gaslimit 0xffffffffffffffff+ , EVM.vmoptGasprice = word gasprice 0 , EVM.vmoptMaxCodeSize = word maxcodesize 0xffffffff , EVM.vmoptPrevRandao = word prevRandao prevRan , EVM.vmoptSchedule = FeeSchedule.berlin@@ -816,65 +687,4 @@ } word f def = fromMaybe def (f cmd) addr f def = fromMaybe def (f cmd)--launchTest :: HasCallStack => Command Options.Unwrapped -> IO ()-launchTest cmd = do- parsed <- VMTest.parseBCSuite <$> LazyByteString.readFile (file cmd)- case parsed of- Left "No cases to check." -> putStrLn "no-cases ok"- Left err -> print err- Right allTests ->- let testFilter =- if null (test cmd)- then id- else filter (\(x, _) -> elem x (test cmd))- in- mapM_ (runVMTest (diff cmd) (optsMode cmd) (timeout cmd)) $- testFilter (Map.toList allTests)--runVMTest :: HasCallStack => Bool -> Mode -> Maybe Int -> (String, VMTest.Case) -> IO Bool-runVMTest diffmode mode timelimit (name, x) =- do- let vm0 = VMTest.vmForCase x- putStr (name ++ " ")- hFlush stdout- result <- do- action <- async $- case mode of- Run ->- Timeout.timeout (1000000 * (fromMaybe 10 timelimit)) $- execStateT (EVM.Stepper.interpret (EVM.Fetch.zero 0 (Just 0)) . void $ EVM.Stepper.execFully) vm0- Debug ->- withSolvers Z3 0 Nothing $ \solvers -> Just <$> TTY.runFromVM solvers Nothing Nothing emptyDapp vm0- JsonTrace ->- error "JsonTrace: implement me"- -- Just <$> execStateT (EVM.UnitTest.interpretWithCoverage EVM.Fetch.zero EVM.Stepper.runFully) vm0- waitCatch action- case result of- Right (Just vm1) -> do- ok <- VMTest.checkExpectation diffmode x vm1- putStrLn (if ok then "ok" else "")- return ok- Right Nothing -> do- putStrLn "timeout"- return False- Left e -> do- putStrLn $ "error: " ++ if diffmode- then show e- else (head . lines . show) e- return False--parseAbi :: (AsValue s) => s -> (Text, [AbiType])-parseAbi abijson =- (signature abijson, snd- <$> parseMethodInput- <$> V.toList- (fromMaybe (error "Malformed function abi") (abijson ^? key "inputs" . _Array)))--abiencode :: (AsValue s) => Maybe s -> [String] -> ByteString-abiencode Nothing _ = error "missing required argument: abi"-abiencode (Just abijson) args =- let (sig', declarations) = parseAbi abijson- in if length declarations == length args- then abiMethod sig' $ AbiTuple . V.fromList $ zipWith makeAbiValue declarations args- else error $ "wrong number of arguments:" <> show (length args) <> ": " <> show args+ word64 f def = fromMaybe def (f cmd)
hevm.cabal view
@@ -2,7 +2,7 @@ name: hevm version:- 0.50.0+ 0.50.1 synopsis: Ethereum virtual machine evaluator description:@@ -22,9 +22,6 @@ Ethereum build-type: Simple-data-files:- run-blockchain-tests- run-consensus-tests extra-source-files: CHANGELOG.md test/contracts/lib/test.sol@@ -43,32 +40,25 @@ test/contracts/fail/dsProveFail.sol test/contracts/fail/invariantFail.sol +flag ci+ description: Sets flags for compilation in CI+ default: False+ manual: True++source-repository head+ type: git+ location: https://github.com/ethereum/hevm.git+ common shared- default-language:- Haskell2010+ if flag(ci)+ ghc-options: -Werror+ default-language: GHC2021 default-extensions: LambdaCase OverloadedStrings RecordWildCards TypeFamilies ViewPatterns- -- GHC2021 default extensions, remove me when GHC is updated to 9.2- BangPatterns- ConstraintKinds- DeriveDataTypeable- DeriveFunctor- DeriveGeneric- DoAndIfThenElse- EmptyDataDecls- FlexibleContexts- FlexibleInstances- ForeignFunctionInterface- GeneralizedNewtypeDeriving- PolyKinds- RankNTypes- ScopedTypeVariables- StandaloneDeriving- TypeOperators library import: shared@@ -85,7 +75,6 @@ EVM.Exec, EVM.Facts, EVM.Facts.Git,- EVM.Flatten, EVM.Format, EVM.Fetch, EVM.FeeSchedule,@@ -106,7 +95,6 @@ EVM.TTYCenteredList, EVM.Types, EVM.UnitTest,- EVM.VMTest other-modules: Paths_hevm autogen-modules:@@ -130,12 +118,12 @@ Decimal >= 0.5.1 && < 0.6, containers >= 0.6.0 && < 0.7, deepseq >= 1.4.4 && < 1.5,- time >= 1.8.0 && < 1.11,+ time >= 1.11.1.1 && < 1.12, transformers >= 0.5.6 && < 0.6, tree-view >= 0.5 && < 0.6, abstract-par >= 0.3.3 && < 0.4, aeson >= 2.0.0 && < 2.1,- bytestring >= 0.10.8 && < 0.11,+ bytestring >= 0.11.3.1 && < 0.12, scientific >= 0.3.6 && < 0.4, binary >= 0.8.6 && < 0.9, text >= 1.2.3 && < 1.3,@@ -143,22 +131,22 @@ vector >= 0.12.1 && < 0.13, ansi-wl-pprint >= 0.6.9 && < 0.7, base16-bytestring >= 1.0.0 && < 2.0,- brick >= 0.68 && < 0.69,+ brick >= 1.4 && < 1.5, megaparsec >= 9.0.0 && < 10.0, mtl >= 2.2.2 && < 2.3, directory >= 1.3.3 && < 1.4, filepath >= 1.4.2 && < 1.5,- vty >= 5.25.1 && < 5.34,+ vty >= 5.37 && < 5.38, cereal >= 0.5.8 && < 0.6,- cryptonite >= 0.27 && <= 0.29,+ cryptonite >= 0.30 && < 0.31, memory >= 0.16.0 && < 0.20, data-dword >= 0.3.1 && < 0.4, fgl >= 5.7.0 && < 5.8, free >= 5.1.3 && < 5.2, haskeline >= 0.8.0 && < 0.9, process >= 1.6.5 && < 1.7,- lens >= 5.0.0 && < 5.1,- lens-aeson >= 1.0.2 && < 1.2,+ lens >= 5.1.1 && < 5.2,+ lens-aeson >= 1.2.2 && < 1.3, monad-par >= 0.3.5 && < 0.4, async >= 2.2.4 && < 2.3, multiset >= 0.3.4 && < 0.4,@@ -179,7 +167,7 @@ smt2-parser >= 0.1.0.1, word-wrap >= 0.5 && < 0.6, spool >= 0.1 && < 0.2,- parsec >= 3.1.14.0 && < 3.1.15+ parsec >= 3.1.15 && < 3.2, hs-source-dirs: src @@ -247,12 +235,15 @@ HUnit >= 1.6, QuickCheck, quickcheck-instances,+ aeson, base, base16-bytestring, binary, containers, directory, bytestring,+ filemanip,+ filepath, here, hevm, lens,@@ -270,6 +261,7 @@ time, array, vector,+ witherable, smt2-parser >= 0.1.0.1 library test-utils@@ -283,10 +275,14 @@ test-base build-depends: test-utils+ other-modules:+ EVM.TestUtils if os(darwin)- extra-libraries: c+++ extra-libraries: c+++ -- https://gitlab.haskell.org/ghc/ghc/-/issues/11829+ ld-options: -Wl,-keep_dwarf_unwind else- extra-libraries: stdc+++ extra-libraries: stdc++ --- Test Suites --- @@ -307,3 +303,11 @@ exitcode-stdio-1.0 main-is: rpc.hs++test-suite ethereum-tests+ import:+ test-common+ type:+ exitcode-stdio-1.0+ main-is:+ BlockchainTests.hs
− run-blockchain-tests
@@ -1,150 +0,0 @@-#!/usr/bin/env bash-set -e--# Invoke with hevm e.g.-# hevm compliance --tests ~/ethereum-tests --skip modexp --timeout 20 --html--HEVM=${HEVM:-hevm}--if [[ "$#" -lt 1 ]]; then- echo >&2 "usage: $(basename "$0") <tests-dir>"- exit 1-fi--tests=$1-html=$2-match=$3-skip=$4-timeout=${5:-10}--_html () {-cat <<.-<!doctype html>-<title>hevm test results</title>-<style>-* { font-family:-"latin modern mono", "fantasque sans mono",-inconsolata, menlo, monospace;-font-size: 22px;-line-height: 26px; }-body { margin: 2rem; }-header { text-align: center; margin: 4rem 0; }-table { border-collapse: collapse; width: 100%; }-tr:nth-child(even) { background: rgba(0, 0, 0, 0.05); }-td:not(:first-child):not(:last-child) { padding: 0 1rem; }-.category { opacity: 0.6; text-align: right }-a { color: darkblue; text-decoration: none; }-h1, h2 { text-align: center; margin-top: 2rem }-.testcase { font-weight: bold }-#failed .testcase { color: rgb(200, 0, 0) }-#balancefailed .testcase { color: rgb(200, 200, 0) }-#passed .testcase { color: rgb(0, 150, 0) }-#skipped .testcase { color: rgb(0, 100, 250) }-#timeout .testcase { color: rgb(0, 0, 250) }-</style>-<header>-<h1>hevm consensus test report</h1>-<p>$(date +%Y-%m-%d)</p>-<p>$(echo "$npass passed, $nbal bad-balance, $nnon bad-nonce, $nstr bad-storage, $nfail failed, $nskip skipped, $ntime timeout")</p>-(Test suite: <span class=GeneralStateTests</span>GeneralStateTests</span> for Berlin)-</header>-<h2>Failed tests</h2>-<table id=failed>-<tbody>-$(echo $noncefailed)-$(echo $storagefailed)-$(echo $failed)-</table>-<h2>Failed tests (due to balance only)</h2>-<table id=balancefailed>-<tbody>-$(echo $balancefailed)-</table>-<h2>Timeout tests</h2>-<table id=timeout>-<tbody>-$(echo $timeouts)-</table>-<h2>Skipped tests</h2>-<table id=skipped>-<tbody>-$(echo $skipped)-</table>-<h2>Passed tests</h2>-<table id=passed>-<tbody>-$(echo $passed)-</table>-.-}--shopt -s nocasematch-{- cd "$tests"- for x in BlockchainTests/GeneralStateTests/*/*; do- if [ -d $x ]; then- for y in $x/*; do- if [[ $y =~ .*$match.* ]] && [[ -n $skip && $y =~ .*$skip.* ]]; then- for job in $(<$y jq '.|keys[]' -r); do- echo -n "$job " ; echo "skip"- done- elif [[ $y =~ .*$match.* ]]; then- set +e- "$HEVM" bc-test --file $y --timeout $timeout 2>&1- set -e- fi- done- else- if [[ $x =~ .*$match.* ]] && [[ -n $skip && $x =~ .*$skip.* ]]; then- for job in $(<$x jq '.|keys[]' -r); do- echo -n "$job " ; echo "skip"- done- elif [[ $x =~ .*$match.* ]]; then- set +e- "$HEVM" bc-test --file $x --timeout $timeout 2>&1- set -e- fi- fi- done-} | {- while read test outcome; do- echo >&2 "$test $outcome"- row="<tr><td class=testcase>$test<td>$outcome"- row+=$'\n'- case $outcome in- ok) passed+=$row ;;- bad-balance) balancefailed+=$row ;;- bad-nonce) noncefailed+=$row ;;- bad-storage) storagefailed+=$row ;;- timeout) timeouts+=$row ;;- skip) skipped+=$row ;;- *) failed+=$row ;;- esac- done-- sum () { echo -ne "$1" | wc -l | awk '{print $1}'; }-- npass=$(sum "$passed")- nbal=$(sum "$balancefailed")- nnon=$(sum "$noncefailed")- nstr=$(sum "$storagefailed")- nfail=$(sum "$failed")- ntime=$(sum "$timeouts")- nskip=$(sum "$skipped")-- echo >&2 "passed: $npass"- echo >&2 "bad-balance: $nbal"- echo >&2 "bad-nonce: $nnon"- echo >&2 "bad-storage: $nstr"- echo >&2 "failed: $nfail"- echo >&2 "timeout: $ntime"- echo >&2 "skipped: $nskip"-- if [[ $html == "True" ]]; then- _html- fi-- nbad=$(($nbal + $nnon + $nstr + $nfail))-- [[ $nbad -gt 0 ]] && exit 1 || exit 0-}
− run-consensus-tests
@@ -1,110 +0,0 @@-#!/usr/bin/env bash-set -e--# Invoke with hevm e.g.-# hevm compliance --tests ~/ethereum-tests --group VM --skip quadratic --html--HEVM=${HEVM:-hevm}--if [[ "$#" -lt 1 ]]; then- echo >&2 "usage: $(basename "$0") <tests-dir>"- exit 1-fi--tests=$1-html=$2-match=$3-skip=$4-timeout=${5:-10}--_html() {-cat <<.-<!doctype html>-<title>hevm test results</title>-<style>-* { font-family:-"latin modern mono", "fantasque sans mono",-inconsolata, menlo, monospace;-font-size: 22px;-line-height: 26px; }-body { margin: 2rem; }-header { text-align: center; margin: 4rem 0; }-table { border-collapse: collapse; width: 100%; }-tr:nth-child(even) { background: rgba(0, 0, 0, 0.05); }-td:not(:first-child):not(:last-child) { padding: 0 1rem; }-.category { opacity: 0.6; text-align: right }-a { color: darkblue; text-decoration: none; }-h1, h2 { text-align: center; margin-top: 2rem }-.testcase { font-weight: bold }-#failed .testcase { color: rgb(200, 0, 0) }-#passed .testcase { color: rgb(0, 150, 0) }-#skipped .testcase { color: rgb(0, 100, 250) }-</style>-<header>-<h1>hevm consensus test report</h1>-<p>$(date +%Y-%m-%d)</p>-<p>$(echo "$npass passed, $nfail failed, $nskip skipped")</p>-(Test suite: <span class=VMTests</span>VMTests</span> for ConstantinopleFix)-</header>-<h2>Failed tests</h2>-<table id=failed>-<tbody>-$(echo $failed)-</table>-<h2>Skipped tests</h2>-<table id=skipped>-<tbody>-$(echo $skipped)-</table>-<h2>Passed tests</h2>-<table id=passed>-<tbody>-$(echo $passed)-</table>-.-}--{- cd "$tests"- for x in VMTests/*/*; do- if [[ $x =~ .*$match.* ]] && [[ -n $skip && $x =~ .*$skip.* ]]; then- for job in $(<$x jq '.|keys[]' -r); do- echo "$x $job skip"- done- elif [[ $x =~ .*$match.* ]]; then- echo -n "$x " ; "$HEVM" vm-test --file $x --timeout $timeout 2>&1- fi- done-} | {- while read path test outcome; do- echo >&2 "$path $test $outcome"- category=$(dirname "$path")- testcase=$(basename "${path%.json}")- row="<tr><td class=testcase>$testcase<td>$outcome<td class=category>$category"- row+=$'\n'- case $outcome in- ok) passed+=$row ;;- skip) skipped+=$row ;;- timeout) timouts+=row ;;- *) failed+=$row ;;- esac- done-- sum () { echo -ne "$1" | wc -l | awk '{print $1}'; }-- nfail=$(sum "$failed")- npass=$(sum "$passed")- nskip=$(sum "$skipped")- ntime=$(sum "$timeouts")-- echo >&2 "passed: $npass"- echo >&2 "failed: $nfail"- echo >&2 "timeout: $ntime"- echo >&2 "skipped: $nskip"-- if [[ $html == "True" ]]; then- _html- fi-- [[ $nfail -gt 0 ]] && exit 1 || exit 0-}
src/EVM.hs view
@@ -11,11 +11,11 @@ import Data.Text (unpack) import Data.Text.Encoding (decodeUtf8, encodeUtf8) import EVM.ABI-import EVM.Types hiding (IllegalOverflow)+import EVM.Types hiding (IllegalOverflow, Error) import EVM.Solidity import EVM.Concrete (createAddress, create2Address) import EVM.Op-import EVM.Expr (readStorage, writeStorage, readByte, readWord, writeWord, writeByte, bufLength, indexWord, litAddr, readBytes, word256At, copySlice, isLitByte)+import EVM.Expr (readStorage, writeStorage, readByte, readWord, writeWord, writeByte, bufLength, indexWord, litAddr, readBytes, word256At, copySlice) import EVM.FeeSchedule (FeeSchedule (..)) import Options.Generic as Options import qualified EVM.Precompiled@@ -28,7 +28,7 @@ import Data.ByteString.Lazy (fromStrict) import Data.Map.Strict (Map) import Data.Set (Set, insert, member, fromList)-import Data.Maybe (fromMaybe)+import Data.Maybe (fromMaybe, fromJust) import Data.Sequence (Seq) import Data.Vector.Storable (Vector) import Data.Foldable (toList)@@ -58,7 +58,6 @@ import Crypto.PubKey.ECC.ECDSA (signDigestWith, PrivateKey(..), Signature(..)) import Crypto.PubKey.ECC.Types (getCurveByName, CurveName(..), Point(..)) import Crypto.PubKey.ECC.Generate (generateQ)-import Data.DoubleWord (Word256(Word256), Word128 (Word128)) -- * Data types @@ -305,10 +304,18 @@ hopefully we do not have to deal with dynamic immutable before we get a real data section... -} data ContractCode- = InitCode ByteString (Expr Buf) -- ^ "Constructor" code, during contract creation- | RuntimeCode (V.Vector (Expr Byte)) -- ^ "Instance" code, after contract creation+ = InitCode ByteString (Expr Buf) -- ^ "Constructor" code, during contract creation+ | RuntimeCode RuntimeCode -- ^ "Instance" code, after contract creation deriving (Show) +-- | We have two variants here to optimize the fully concrete case.+-- ConcreteRuntimeCode just wraps a ByteString+-- SymbolicRuntimeCode is a fixed length vector of potentially symbolic bytes, which lets us handle symbolic pushdata (e.g. from immutable variables in solidity).+data RuntimeCode+ = ConcreteRuntimeCode ByteString+ | SymbolicRuntimeCode (V.Vector (Expr Byte))+ deriving (Show, Eq, Ord)+ -- runtime err when used for symbolic code instance Eq ContractCode where (InitCode a b) == (InitCode c d) = a == c && b == d@@ -392,7 +399,7 @@ blankState = FrameState { _contract = 0 , _codeContract = 0- , _code = RuntimeCode mempty+ , _code = RuntimeCode (ConcreteRuntimeCode "") , _pc = 0 , _stack = mempty , _memory = mempty@@ -421,7 +428,8 @@ bytecode :: Getter Contract (Expr Buf) bytecode = contractcode . to f where f (InitCode _ _) = mempty- f (RuntimeCode ops) = Expr.fromList ops+ f (RuntimeCode (ConcreteRuntimeCode bs)) = ConcreteBuf bs+ f (RuntimeCode (SymbolicRuntimeCode ops)) = Expr.fromList ops instance Semigroup Cache where a <> b = Cache@@ -603,7 +611,8 @@ else do let ?op = case (the state code) of InitCode conc _ -> BS.index conc (the state pc)- RuntimeCode ops ->+ RuntimeCode (ConcreteRuntimeCode bs) -> BS.index bs (the state pc)+ RuntimeCode (SymbolicRuntimeCode ops) -> fromMaybe (error "could not analyze symbolic code") $ unlitByte $ ops V.! the state pc @@ -614,13 +623,10 @@ let !n = num x - 0x60 + 1 !xs = case the state code of InitCode conc _ -> Lit $ word $ padRight n $ BS.take n (BS.drop (1 + the state pc) conc)- RuntimeCode ops ->+ RuntimeCode (ConcreteRuntimeCode bs) -> Lit $ word $ BS.take n $ BS.drop (1 + the state pc) bs+ RuntimeCode (SymbolicRuntimeCode ops) -> let bytes = V.take n $ V.drop (1 + the state pc) ops- in if all isLitByte bytes then -- optimize concrete path- let litBytes = V.toList $ V.catMaybes $ unlitByte <$> bytes- padded = BS.replicate (32 - length litBytes) 0 <> BS.pack litBytes- in Lit $ word padded- else readWord (Lit 0) $ Expr.fromList $ padLeft' 32 bytes+ in readWord (Lit 0) $ Expr.fromList $ padLeft' 32 bytes limitStack 1 $ burn g_verylow $ do next@@ -1075,7 +1081,9 @@ case stk of (x:xs) -> burn g_mid $ forceConcrete x "JUMP: symbolic jumpdest" $ \x' ->- checkJump x' xs+ case toInt x' of+ Nothing -> vmError EVM.BadJumpDestination+ Just i -> checkJump i xs _ -> underrun -- op: JUMPI@@ -1085,7 +1093,9 @@ burn g_high $ let jump :: Bool -> EVM () jump False = assign (state . stack) xs >> next- jump _ = checkJump x' xs+ jump _ = case toInt x' of+ Nothing -> vmError EVM.BadJumpDestination+ Just i -> checkJump i xs in case maybeLitWord y of Just y' -> jump (0 /= y') -- if the jump condition is symbolic, we explore both sides@@ -1674,7 +1684,8 @@ accountEmpty :: Contract -> Bool accountEmpty c = case view contractcode c of- RuntimeCode b -> null b+ RuntimeCode (ConcreteRuntimeCode "") -> True+ RuntimeCode (SymbolicRuntimeCode b) -> null b _ -> False && (view nonce c == 0) && (view balance c == 0)@@ -1703,10 +1714,17 @@ creation <- use (tx . isCreate) createe <- use (state . contract) createeExists <- (Map.member createe) <$> use (env . contracts)- case Expr.toList output of- Nothing -> vmError $ UnexpectedSymbolicArg pc' "runtime code cannot have an abstract lentgh" [output]- Just ops ->- when (creation && createeExists) $ replaceCode createe (RuntimeCode ops)+ let onContractCode contractCode =+ when (creation && createeExists) $ replaceCode createe contractCode+ case output of+ ConcreteBuf bs ->+ onContractCode $ RuntimeCode (ConcreteRuntimeCode bs)+ _ ->+ case Expr.toList output of+ Nothing ->+ vmError $ UnexpectedSymbolicArg pc' "runtime code cannot have an abstract lentgh" [output]+ Just ops ->+ onContractCode $ RuntimeCode (SymbolicRuntimeCode ops) -- compute and pay the refund to the caller and the -- corresponding payment to the miner@@ -1735,7 +1753,7 @@ -- pay out the block reward, recreating the miner if necessary preuse (env . contracts . ix miner) >>= \case Nothing -> modifying (env . contracts)- (Map.insert miner (initialContract (EVM.RuntimeCode mempty)))+ (Map.insert miner (initialContract (EVM.RuntimeCode (ConcreteRuntimeCode "")))) Just _ -> noop modifying (env . contracts) (Map.adjust (over balance (+ blockReward)) miner)@@ -2119,7 +2137,8 @@ collision :: Maybe Contract -> Bool collision c' = case c' of Just c -> (view nonce c /= 0) || case view contractcode c of- RuntimeCode b -> not $ null b+ RuntimeCode (ConcreteRuntimeCode "") -> False+ RuntimeCode (SymbolicRuntimeCode b) -> not $ null b _ -> True Nothing -> False @@ -2368,17 +2387,23 @@ case how of -- Case 4: Returning during a creation? FrameReturned output -> do- case Expr.toList output of- Nothing -> vmError $- UnexpectedSymbolicArg- (view (state . pc) oldVm)- "runtime code cannot have an abstract length"- [output]- Just newCode -> do- replaceCode createe (RuntimeCode newCode)+ let onContractCode contractCode = do+ replaceCode createe contractCode assign (state . returndata) mempty reclaimRemainingGasAllowance push (num createe)+ case output of+ ConcreteBuf bs ->+ onContractCode $ RuntimeCode (ConcreteRuntimeCode bs)+ _ ->+ case Expr.toList output of+ Nothing -> vmError $+ UnexpectedSymbolicArg+ (view (state . pc) oldVm)+ "runtime code cannot have an abstract length"+ [output]+ Just newCode -> do+ onContractCode $ RuntimeCode (SymbolicRuntimeCode newCode) -- Case 5: Reverting during a creation? FrameReverted output -> do@@ -2459,9 +2484,7 @@ :: (MonadState VM m) => TraceData -> m Trace withTraceLocation x = do vm <- get- let- Just this =- currentContract vm+ let this = fromJust $ currentContract vm pure Trace { _traceData = x , _traceContract = this@@ -2558,19 +2581,16 @@ -- * Bytecode data functions -checkJump :: (Integral n) => n -> [Expr EWord] -> EVM ()+checkJump :: Int -> [Expr EWord] -> EVM () checkJump x xs = do theCode <- use (state . code) self <- use (state . codeContract) theCodeOps <- use (env . contracts . ix self . codeOps) theOpIxMap <- use (env . contracts . ix self . opIxMap)- let ops = case theCode of- InitCode ops' _ -> V.fromList $ LitByte <$> BS.unpack ops'- RuntimeCode ops' -> ops'- op = do- -- TODO: not a big fan of how bounds are checked, change this- b <- if x < num (length ops) then ops V.!? num x else Nothing- unlitByte b+ let op = case theCode of+ InitCode ops _ -> BS.indexMaybe ops x+ RuntimeCode (ConcreteRuntimeCode ops) -> BS.indexMaybe ops x+ RuntimeCode (SymbolicRuntimeCode ops) -> ops V.!? x >>= unlitByte case op of Nothing -> vmError EVM.BadJumpDestination Just b ->@@ -2606,7 +2626,10 @@ go v (n, !i, !j, !m) _ = {- PUSH data. -} (n - 1, i + 1, j, m >> Vector.write v i j) -mkOpIxMap (RuntimeCode ops)+mkOpIxMap (RuntimeCode (ConcreteRuntimeCode ops)) =+ mkOpIxMap (InitCode ops mempty) -- a bit hacky++mkOpIxMap (RuntimeCode (SymbolicRuntimeCode ops)) = Vector.create $ Vector.new (length ops) >>= \v -> let (_, _, _, m) = foldl (go v) (0, 0, 0, return ()) (stripBytecodeMetadataSym $ V.toList ops) in m >> return v@@ -2632,7 +2655,9 @@ (op, pushdata) = case code' of InitCode xs' _ -> (BS.index xs' i, fmap LitByte $ BS.unpack $ BS.drop i xs')- RuntimeCode xs' ->+ RuntimeCode (ConcreteRuntimeCode xs') ->+ (BS.index xs' i, fmap LitByte $ BS.unpack $ BS.drop i xs')+ RuntimeCode (SymbolicRuntimeCode xs') -> ( fromMaybe (error "unexpected symbolic code") . unlitByte $ xs' V.! i , V.toList $ V.drop i xs') in if (opslen code' < i) then Nothing@@ -2756,25 +2781,24 @@ -- Maps operation indicies into a pair of (bytecode index, operation) mkCodeOps :: ContractCode -> RegularVector.Vector (Int, Op)-mkCodeOps (InitCode bytes _) = RegularVector.fromList . toList $ go 0 bytes+mkCodeOps contractCode =+ let l = case contractCode of+ InitCode bytes _ ->+ LitByte <$> (BS.unpack bytes)+ RuntimeCode (ConcreteRuntimeCode ops) ->+ LitByte <$> (BS.unpack $ stripBytecodeMetadata ops)+ RuntimeCode (SymbolicRuntimeCode ops) ->+ stripBytecodeMetadataSym $ V.toList ops+ in RegularVector.fromList . toList $ go 0 l where go !i !xs =- case BS.uncons xs of- Nothing ->- mempty- Just (x, xs') ->- let j = opSize x- in (i, readOp x (fmap LitByte $ BS.unpack xs')) Seq.<| go (i + j) (BS.drop j xs)-mkCodeOps (RuntimeCode ops) = RegularVector.fromList . toList $ go' 0 (stripBytecodeMetadataSym $ V.toList ops)- where- go' !i !xs = case uncons xs of Nothing -> mempty Just (x, xs') -> let x' = fromMaybe (error "unexpected symbolic code argument") $ unlitByte x j = opSize x'- in (i, readOp x' xs') Seq.<| go' (i + j) (drop j xs)+ in (i, readOp x' xs') Seq.<| go (i + j) (drop j xs) -- * Gas cost calculation helpers @@ -2889,23 +2913,27 @@ hashcode :: ContractCode -> Expr EWord hashcode (InitCode ops args) = keccak $ (ConcreteBuf ops) <> args-hashcode (RuntimeCode ops) = keccak . Expr.fromList $ ops+hashcode (RuntimeCode (ConcreteRuntimeCode ops)) = keccak (ConcreteBuf ops)+hashcode (RuntimeCode (SymbolicRuntimeCode ops)) = keccak . Expr.fromList $ ops -- | The length of the code ignoring any constructor args. -- This represents the region that can contain executable opcodes opslen :: ContractCode -> Int opslen (InitCode ops _) = BS.length ops-opslen (RuntimeCode ops) = length ops+opslen (RuntimeCode (ConcreteRuntimeCode ops)) = BS.length ops+opslen (RuntimeCode (SymbolicRuntimeCode ops)) = length ops -- | The length of the code including any constructor args. -- This can return an abstract value codelen :: ContractCode -> Expr EWord codelen c@(InitCode {}) = bufLength $ toBuf c-codelen (RuntimeCode ops) = Lit . num $ length ops+codelen (RuntimeCode (ConcreteRuntimeCode ops)) = Lit . num $ BS.length ops+codelen (RuntimeCode (SymbolicRuntimeCode ops)) = Lit . num $ length ops toBuf :: ContractCode -> Expr Buf toBuf (InitCode ops args) = ConcreteBuf ops <> args-toBuf (RuntimeCode ops) = Expr.fromList ops+toBuf (RuntimeCode (ConcreteRuntimeCode ops)) = ConcreteBuf ops+toBuf (RuntimeCode (SymbolicRuntimeCode ops)) = Expr.fromList ops codeloc :: EVM CodeLocation@@ -2914,12 +2942,6 @@ let self = view (state . contract) vm loc = view (state . pc) vm pure (self, loc)--toWord64 :: W256 -> Maybe Word64-toWord64 n =- if n <= num (maxBound :: Word64)- then let (W256 (Word256 _ (Word128 _ n'))) = n in Just n'- else Nothing -- * Emacs setup
src/EVM/ABI.hs view
@@ -384,7 +384,9 @@ | (x, i) <- zip (map fromIntegral xs) [1..] ] asUInt :: Integral i => Int -> (i -> a) -> Get a-asUInt n f = (\(AbiUInt _ x) -> f (fromIntegral x)) <$> getAbi (AbiUIntType n)+asUInt n f = y <$> getAbi (AbiUIntType n)+ where y (AbiUInt _ x) = f (fromIntegral x)+ y _ = error "can't happen" getWord256 :: Get Word256 getWord256 = pack32 8 <$> replicateM 8 getWord32be@@ -405,13 +407,12 @@ genAbiValue :: AbiType -> Gen AbiValue genAbiValue = \case- AbiUIntType n -> genUInt n- AbiIntType n ->- do a <- genUInt n- let AbiUInt _ x = a- pure $ AbiInt n (signedWord (x - 2^(n-1)))+ AbiUIntType n -> AbiUInt n <$> genUInt n+ AbiIntType n -> do+ x <- genUInt n+ pure $ AbiInt n (signedWord (x - 2^(n-1))) AbiAddressType ->- (\(AbiUInt _ x) -> AbiAddress (fromIntegral x)) <$> genUInt 20+ AbiAddress . fromIntegral <$> genUInt 20 AbiBoolType -> elements [AbiBool False, AbiBool True] AbiBytesType n ->@@ -430,7 +431,8 @@ AbiTupleType ts -> AbiTuple <$> mapM genAbiValue ts where- genUInt n = AbiUInt n <$> arbitraryIntegralWithMax (2^n-1)+ genUInt :: Int -> Gen Word256+ genUInt n = arbitraryIntegralWithMax (2^n-1) :: Gen Word256 instance Arbitrary AbiType where arbitrary = oneof
src/EVM/Dapp.hs view
@@ -2,7 +2,7 @@ module EVM.Dapp where -import EVM (Trace, traceContract, traceOpIx, ContractCode(..), Contract(..), codehash, contractcode)+import EVM (Trace, traceContract, traceOpIx, ContractCode(..), Contract(..), codehash, contractcode, RuntimeCode (..)) import EVM.ABI (Event, AbiType, SolError) import EVM.Debug (srcMapCodePos) import EVM.Solidity@@ -68,7 +68,7 @@ let solcs = Map.elems solcByName astIds = astIdMap $ snd <$> toList (view sourceAsts sources)- immutables = filter ((/=) mempty . _immutableReferences) solcs+ immutables = filter ((/=) mempty . (view immutableReferences)) solcs in DappInfo { _dappRoot = root@@ -176,7 +176,11 @@ lookupCode :: ContractCode -> DappInfo -> Maybe SolcContract lookupCode (InitCode c _) a = snd <$> preview (dappSolcByHash . ix (keccak' (stripBytecodeMetadata c))) a-lookupCode (RuntimeCode c) a = let+lookupCode (RuntimeCode (ConcreteRuntimeCode c)) a =+ case snd <$> preview (dappSolcByHash . ix (keccak' (stripBytecodeMetadata c))) a of+ Just x -> return x+ Nothing -> snd <$> find (compareCode c . fst) (view dappSolcByCode a)+lookupCode (RuntimeCode (SymbolicRuntimeCode c)) a = let code = BS.pack $ mapMaybe unlitByte $ V.toList c in case snd <$> preview (dappSolcByHash . ix (keccak' (stripBytecodeMetadata code))) a of Just x -> return x
src/EVM/Dev.hs view
@@ -7,7 +7,7 @@ -} module EVM.Dev where -import Data.ByteString hiding (putStrLn, writeFile, zip)+import Data.ByteString hiding (writeFile, zip) import Control.Monad.State.Strict hiding (state) import Data.Maybe (fromJust) import System.Directory@@ -30,7 +30,6 @@ import System.Exit (exitFailure) import qualified EVM.Fetch as Fetch import qualified EVM.FeeSchedule as FeeSchedule-import qualified Data.Vector as V checkEquiv :: (Typeable a) => Expr a -> Expr a -> IO () checkEquiv a b = withSolvers Z3 1 Nothing $ \s -> do@@ -363,7 +362,7 @@ initVm :: ByteString -> VM initVm bs = vm where- contractCode = RuntimeCode $ V.fromList $ LitByte <$> unpack bs+ contractCode = RuntimeCode (ConcreteRuntimeCode bs) c = Contract { _contractcode = contractCode , _balance = 0
src/EVM/Exec.hs view
@@ -45,7 +45,7 @@ , vmoptTxAccessList = mempty , vmoptAllowFFI = False }) & set (env . contracts . at ethrunAddress)- (Just (initialContract (RuntimeCode mempty)))+ (Just (initialContract (RuntimeCode (ConcreteRuntimeCode "")))) exec :: MonadState VM m => m VMResult exec =
src/EVM/Expr.hs view
@@ -8,7 +8,7 @@ module EVM.Expr where import Prelude hiding (LT, GT)-import Data.Bits+import Data.Bits hiding (And, Xor) import Data.DoubleWord (Int256, Word256(Word256), Word128(Word128)) import Data.Int (Int32) import Data.Word@@ -266,13 +266,16 @@ -- Attempts to read a concrete word from a buffer by reading 32 individual bytes and joining them together -- returns an abstract ReadWord expression if a concrete word cannot be constructed readWordFromBytes :: Expr EWord -> Expr Buf -> Expr EWord+readWordFromBytes (Lit idx) (ConcreteBuf bs) =+ case toInt idx of+ Nothing -> Lit 0+ Just i -> Lit $ word $ padRight 32 $ BS.take 32 $ BS.drop i bs readWordFromBytes i@(Lit idx) buf = let bytes = [readByte (Lit i') buf | i' <- [idx .. idx + 31]] in if Prelude.and . (fmap isLitByte) $ bytes then Lit (bytesToW256 . mapMaybe unlitByte $ bytes) else ReadWord i buf readWordFromBytes idx buf = ReadWord idx buf- {- | Copies a slice of src into dst.
src/EVM/Facts.hs view
@@ -54,7 +54,6 @@ import qualified Data.ByteString.Char8 as Char8 import qualified Data.Map as Map import qualified Data.Set as Set-import qualified Data.Vector as V -- We treat everything as ASCII byte strings because -- we only use hex digits (and the letter 'x').@@ -159,7 +158,7 @@ apply1 vm fact = case fact of CodeFact {..} -> flip execState vm $ do- assign (env . contracts . at addr) (Just (EVM.initialContract (EVM.RuntimeCode (V.fromList $ LitByte <$> BS.unpack blob))))+ assign (env . contracts . at addr) (Just (EVM.initialContract (EVM.RuntimeCode (EVM.ConcreteRuntimeCode blob)))) when (view (state . contract) vm == addr) $ EVM.loadContract addr StorageFact {..} -> vm & over (env . storage) (writeStorage (litAddr addr) (Lit which) (Lit what))@@ -172,7 +171,7 @@ apply2 vm fact = case fact of CodeFact {..} -> flip execState vm $ do- assign (cache . fetchedContracts . at addr) (Just (EVM.initialContract (EVM.RuntimeCode (V.fromList $ LitByte <$> BS.unpack blob))))+ assign (cache . fetchedContracts . at addr) (Just (EVM.initialContract (EVM.RuntimeCode (EVM.ConcreteRuntimeCode blob)))) when (view (state . contract) vm == addr) $ EVM.loadContract addr StorageFact {..} -> let store = view (cache . fetchedStorage) vm
src/EVM/Fetch.hs view
@@ -6,7 +6,7 @@ import Prelude hiding (Word) import EVM.ABI-import EVM.Types (Addr, W256, hexText, Expr(Lit, LitByte), Expr(..), Prop(..), (.&&), (./=))+import EVM.Types (Addr, W256, hexText, Expr(Lit), Expr(..), Prop(..), (.&&), (./=)) import EVM.SMT import EVM (EVM, Contract, Block, initialContract, nonce, balance, external) import qualified EVM.FeeSchedule as FeeSchedule@@ -29,7 +29,6 @@ import System.Process import qualified Network.Wreq.Session as Session-import qualified Data.Vector as V import Numeric.Natural (Natural) -- | Abstract representation of an RPC fetch request@@ -143,7 +142,7 @@ theBalance <- MaybeT $ fetch (QueryBalance addr) return $- initialContract (EVM.RuntimeCode (V.fromList $ LitByte <$> BS.unpack theCode))+ initialContract (EVM.RuntimeCode (EVM.ConcreteRuntimeCode theCode)) & set nonce theNonce & set balance theBalance & set external True@@ -203,7 +202,7 @@ -- we generate a new array to the fetched contract here EVM.PleaseFetchContract addr continue -> do contract <- case info of- Nothing -> return $ Just $ initialContract (EVM.RuntimeCode mempty)+ Nothing -> return $ Just $ initialContract (EVM.RuntimeCode (EVM.ConcreteRuntimeCode "")) Just (n, url) -> fetchContractFrom n url addr case contract of Just x -> return $ continue x
− src/EVM/Flatten.hs
@@ -1,466 +0,0 @@-module EVM.Flatten (flatten) where---- This module concatenates all the imported dependencies--- of a given source file, so that you can paste the result--- into Remix or the Etherscan contract verification page.------ The concatenated files are stripped of import directives--- and compiler version pragmas are merged into just one.------ This module is mostly independent from the rest of Hevm,--- using only the source code metadata support modules.--import EVM.Dapp (DappInfo, dappSources)-import EVM.Types (regexMatches)-import EVM.Solidity (sourceAsts)-import EVM.Demand (demand)---- We query and alter the Solidity code using the compiler's AST.--- The AST is a deep JSON structure, so we use Aeson and Lens.-import Control.Lens (preview, view, universe)-import Data.Aeson (Value (String))-import Data.Aeson.Lens (key, _String, _Array, _Integer)---- We use the FGL graph library for the topological sort.--- (We use four FGL functions and they're all in different modules!)-import qualified Data.Graph.Inductive.Graph as Fgl-import qualified Data.Graph.Inductive.PatriciaTree as Fgl-import qualified Data.Graph.Inductive.Query.BFS as Fgl-import qualified Data.Graph.Inductive.Query.DFS as Fgl---- The Solidity version pragmas can be arbitrary SemVer ranges,--- so we use this library to parse them.-import Data.SemVer (SemVerRange, parseSemVerRange)-import qualified Data.SemVer as SemVer--import Control.Monad (forM)-import Data.ByteString (ByteString)-import Data.Foldable (foldl', toList)-import Data.List (sort, nub, (\\))-import Data.Map (Map, (!), (!?))-import Data.Maybe (mapMaybe, isJust, catMaybes, fromMaybe)-import Data.Text (Text, unpack, pack, intercalate)-import Data.Text.Encoding (encodeUtf8, decodeUtf8)-import Text.Read (readMaybe)--import qualified Data.Map as Map-import qualified Data.Text as Text-import qualified Data.ByteString as BS---- Define an alias for FGL graphs with text nodes and unlabeled edges.-type FileGraph = Fgl.Gr Text ()---- | Get field either inside 'attributes' object (combined-json format)--- or directly.-getAttribute :: Text -> Value -> Maybe Value-getAttribute s v = case preview (key "attributes" . key s) v of- Nothing -> preview (key s) v- Just r -> Just r---- Given the AST of a source file, resolve all its imported paths.-importsFrom :: Value -> [Text]-importsFrom ast =- let- -- We use the astonishing `universe` function from Lens- -- to get a lazy list of every node in the AST structure.- allNodes :: [Value]- allNodes = universe ast-- -- Given some subvalue in the AST, we check if it's an import,- -- and if so, return its resolved import path.- resolveImport :: Value -> Maybe Text- resolveImport node =- case preview (key "nodeType") node of- Just (String "ImportDirective") -> view _String <$> getAttribute "absolutePath" node- _ ->- case preview (key "name") node of- Just (String "ImportDirective") ->- view _String <$> getAttribute "absolutePath" node- _ ->- Nothing-- -- Now we just try to resolve import paths at all subnodes.- in mapMaybe resolveImport allNodes--flatten :: DappInfo -> Text -> IO ()-flatten dapp target = do- let- -- The nodes and edges are defined below.- graph :: FileGraph- graph = Fgl.mkGraph nodes edges-- -- The graph nodes are ints with source paths as labels.- nodes :: [(Int, Text)]- nodes = zip [1..] (Map.keys asts)-- -- The graph edges are defined by module imports.- edges =- [ (indices ! s, indices ! t, ()) -- Edge from S to T- | (s, v) <- Map.toList asts -- for every file S- , t <- importsFrom v ] -- and every T imported by S.-- -- We can look up the node index for a source file path.- indices :: Map Text Int- indices = Map.fromList [(v, k) | (k, v) <- nodes]-- -- The JSON ASTs are indexed by source file path.- asts :: Map Text Value- asts = view (dappSources . sourceAsts) dapp-- topScopeIds :: [Integer]- topScopeIds = mconcat $ fmap f $ Map.elems asts- where- id' = preview (key "id" . _Integer)- f ast =- [ fromJust' "no id for SourceUnit" $ id' node- | node <- universe ast- , nodeIs "SourceUnit" node- ]-- contractsAndStructsToRename :: Map Integer Text- contractsAndStructsToRename =- Map.fromList- $ indexed [ x | x <- xs, (snd x) `elem` xs' ]- where- xs = concatMap f $ Map.elems asts- xs' = repeated $ fmap snd xs- scope x = getAttribute "scope" x >>= preview _Integer- name x = getAttribute "name" x >>= preview _String- id' = preview (key "id" . _Integer)- p x = (nodeIs "ContractDefinition" x || nodeIs "StructDefinition" x)- && (fromJust' "no contract/struct scope" $ scope x) `elem` topScopeIds- f ast =- [ ( fromJust' "no id for top scoped contract or struct" $ id' node- , fromJust' "no id for top scoped contract or struct" $ name node- )- | node <- universe ast- , p node- ]-- contractStructs :: [(Integer, (Integer, Text))]- contractStructs = mconcat $ fmap f $ Map.elems asts- where- scope x = getAttribute "scope" x >>= preview _Integer- cname x = getAttribute "canonicalName" x >>= preview _String- id' = preview (key "id" . _Integer)- p x = (nodeIs "StructDefinition" x)- && (fromJust' "nested struct" $ scope x) `Map.member` contractsAndStructsToRename- f ast =- [ let- id'' = fromJust' "no id for nested struct" $ id' node- cname' = fromJust'- ("no canonical name of nested struct with id:" ++ show id'') $ cname node- ref = fromJust'- ("no scope of nested struct with id:" ++ show id'') $ scope node- in- (id'', (ref, cname'))- | node <- universe ast- , p node- ]-- -- We use the target source file to make a relevant subgraph- -- with only files transitively depended on from the target.- case Map.lookup target indices of- Nothing ->- error "didn't find contract AST"- Just root -> do- let- -- Restrict the graph to only the needed nodes,- -- discovered via breadth-first search from the target.- subgraph :: Fgl.Gr Text ()- subgraph = Fgl.subgraph (Fgl.bfs root graph) graph-- -- Now put the source file paths in the right order- -- by sorting topologically.- ordered :: [Text]- ordered = reverse (Fgl.topsort' subgraph)-- -- Take the highest Solidity version from all pragmas.- pragma :: Text- pragma = maximalPragma (Map.elems (Map.filterWithKey (\k _ -> k `elem` ordered) asts))-- license :: Text- license = joinLicenses (Map.elems (Map.filterWithKey (\k _ -> k `elem` ordered) asts))- -- Read the source files in order and strip unwanted directives.- -- Also add an informative comment with the original source file path.- sources <-- forM ordered $ \path -> do- src <- BS.readFile (unpack path)- pure $ mconcat- [ "////// ", encodeUtf8 path, "\n"- -- Fold over a list of source transforms- , fst- (prefixContractAst- contractsAndStructsToRename- contractStructs- (stripImportsAndPragmas (stripLicense src) (asts ! path))- (asts ! path))- , "\n"- ]-- -- Force all evaluation before any printing happens, to avoid- -- partial output.- demand target; demand pragma; demand sources-- -- Finally print the whole concatenation.- putStrLn $ "// hevm: flattened sources of " <> unpack target- putStrLn (unpack license)- putStrLn (unpack pragma)- BS.putStr (mconcat sources)--joinLicenses :: [Value] -> Text-joinLicenses asts =- case nub $ mapMaybe (\ast -> getAttribute "license" ast >>= preview _String) asts of- [] -> ""- x -> "// SPDX-License-Identifier: " <> intercalate " AND " x---- | Construct a new Solidity version pragma for the highest mentioned version--- given a list of source file ASTs.-maximalPragma :: [Value] -> Text-maximalPragma asts = (- case mapMaybe versions asts of- [] -> "" -- allow for no pragma- xs ->- "pragma solidity "- <> pack (show (rangeIntersection xs))- <> ";\n"- )- <> (- mconcat . nub . sort . fmap (\ast ->- mconcat $ fmap- (\xs -> "pragma "- <> intercalate " " [x | String x <- xs]- <> ";\n")- (otherPragmas ast)- )- ) asts--- where- isVersionPragma :: [Value] -> Bool- isVersionPragma (String "solidity" : _) = True- isVersionPragma _ = False-- pragmaComponents :: Value -> [[Value]]- pragmaComponents ast = components- where- ps :: [Value]- ps = filter (nodeIs "PragmaDirective") (universe ast)-- components :: [[Value]]- components = catMaybes $- fmap- ((fmap toList) . (\x -> getAttribute "literals" x >>= preview _Array))- ps-- -- Simple way to combine many SemVer ranges. We don't actually- -- optimize these boolean expressions, so the resulting pragma- -- might be redundant, like ">=0.4.23 >=0.5.0 <0.6.0".- rangeIntersection :: [SemVerRange] -> SemVerRange- rangeIntersection = foldr1 SemVer.And . nub . sort-- -- Get the semantic version range from a source file's pragma,- -- or nothing if no pragma present.- versions :: Value -> Maybe SemVerRange- versions ast = fmap grok components- where- components :: Maybe [Value]- components =- case filter isVersionPragma (pragmaComponents ast) of- [_:xs] -> Just xs- [] -> Nothing- x -> error $ "multiple version pragmas" ++ show x-- grok :: [Value] -> SemVerRange- grok xs =- let- rangeText = mconcat [x | String x <- xs]- in- case parseSemVerRange rangeText of- Right r -> r- Left _ ->- error ("failed to parse SemVer range " ++ show rangeText)-- otherPragmas :: Value -> [[Value]]- otherPragmas = (filter (not . isVersionPragma)) . pragmaComponents--nodeIs :: Text -> Value -> Bool-nodeIs t x = isSourceNode && hasRightName- where- isSourceNode =- isJust (preview (key "src") x)- hasRightName =- Just t == preview (key "name" . _String) x- || Just t == preview (key "nodeType" . _String) x---- | Removes all lines containing "SPDX-License-Identifier"-stripLicense :: ByteString -> (ByteString, Int)-stripLicense bs =- (encodeUtf8 $ Text.unlines (lines' \\ licenseLines), - sum (((1 +) . Text.length) <$> licenseLines))- where lines' = Text.lines $ decodeUtf8 bs- licenseLines = filter (regexMatches "SPDX-License-Identifier") lines'---- | (bytes, offset) where offset is added or incremeneted as text is--- inserted or removed from the source file-stripImportsAndPragmas :: (ByteString, Int) -> Value -> (ByteString, Int)-stripImportsAndPragmas bso ast = stripAstNodes bso ast p- where- p x = nodeIs "ImportDirective" x || nodeIs "PragmaDirective" x--stripAstNodes :: (ByteString, Int)-> Value -> (Value -> Bool) -> (ByteString, Int)-stripAstNodes bso ast p =- cutRanges [sourceRange node | node <- universe ast, p node]-- where- -- Removes a set of non-overlapping ranges from a bytestring- -- by commenting them out.- cutRanges :: [(Int, Int)] -> (ByteString, Int)- cutRanges (sort -> rs) = foldl' f bso rs- where- f (bs', n) (i, j) =- ( cut bs' (i + n) (j + n)- , n + length ("/* */" :: String))-- -- Comments out the bytes between two indices from a bytestring.- cut :: ByteString -> Int -> Int -> ByteString- cut x i j =- let (a, b) = BS.splitAt i x- in a <> "/* " <> BS.take (j - i) b <> " */" <> BS.drop (j - i) b--readAs :: Read a => Text -> Maybe a-readAs = readMaybe . Text.unpack--prefixContractAst :: Map Integer Text -> [(Integer, (Integer, Text))] -> (ByteString, Int) -> Value -> (ByteString, Int)-prefixContractAst castr cs bso ast = prefixAstNodes- where- bs = fst bso- refDec x = getAttribute "referencedDeclaration" x >>= preview _Integer- name x = getAttribute "name" x >>= preview _String- id' = preview (key "id" . _Integer)-- -- Is node top level defined type (contract/interface/struct)- p x = (nodeIs "ContractDefinition" x || nodeIs "StructDefinition" x)- && (fromJust' "id of any" $ id' x) `Map.member` castr-- -- Is node identifier that is referencing top level defined type- p' x =- (nodeIs "Identifier" x || nodeIs "UserDefinedTypeName" x)- && (isJust $ refDec x) && (fromJust' "refDec of ident/userdef" $ refDec x) `Map.member` castr-- -- Is node identifier that is referencing a struct nested in a top level- -- defined contract/interface- p'' x =- (nodeIs "Identifier" x || nodeIs "UserDefinedTypeName" x)- && (isJust $ name x)- && (- let- refs = fmap fst cs- i = fromJust' "no id for ident/userdef" $ id' x- ref = fromJust' ("no refDec for ident/userdef: " ++ show i) $ refDec x- n = fromJust' ("no name for ident/userdef: " ++ show i) $ name x- cn = fromJust'- ("no match for lookup in nested structs: "- ++ show i- ++ " -> "- ++ show ref- ) $ lookup ref cs- in- -- XXX: comparing canonical name with name of nested structs- -- might not be super great- ref `elem` refs && n == snd cn- )-- p''' x = p x || p' x || p'' x-- prefixAstNodes :: (ByteString, Int)- prefixAstNodes =- cutRanges [sourceId node | node <- universe ast, p''' node]-- -- Parses the `id` and `attributes.referencedDeclaration` field of an AST node- -- into a pair of byte indices.- sourceId :: Value -> (Int, Integer)- sourceId v =- if (not $ p v || p' v) && p'' v then (- let- ref = fromJust' "refDec of nested struct ref" $ refDec v- cn = fromJust' "no match for lookup in nested structs" $ lookup ref cs- in- (end, fst cn)- ) else- fromJust' "internal error: no id found for contract reference" x-- where- (start, end) = sourceRange v- f :: Text -> Maybe (Int, Integer)- f t | t `elem` ["ContractDefinition", "StructDefinition"] =- let- name' = encodeUtf8 $ fromJust' "no name for contract/struct" $ name v- bs' = snd $ BS.splitAt (start + snd bso) bs- pos = start- + (BS.length $ fst $ BS.breakSubstring name' bs')- + (BS.length name')- in- fmap ((,) pos) $ id' v- | t `elem` ["UserDefinedTypeName", "Identifier"] =- fmap ((,) end) $ refDec v- | otherwise =- error $ "internal error: not a contract reference: " ++ show t-- x :: Maybe (Int, Integer)- x = case preview (key "nodeType" . _String) v of- Just t -> f t- Nothing -> case preview (key "name" . _String) v of- Just t -> f t- Nothing ->- error "internal error: not a contract reference"-- -- Prefix a set of non-overlapping ranges from a bytestring- -- by commenting them out.- cutRanges :: [(Int, Integer)] -> (ByteString, Int)- cutRanges (sort -> rs) = foldl' f bso rs- where- f (bs', n) (i, t) =- let- t' = "_" <> (castr ! t)- in- ( prefix t' bs' (i + n)- , n + Text.length t' )-- -- Comments out the bytes between two indices from a bytestring.- prefix :: Text -> ByteString -> Int -> ByteString- prefix t x i =- let (a, b) = BS.splitAt i x- in a <> encodeUtf8 t <> b---- Parses the `src` field of an AST node into a pair of byte indices.-sourceRange :: Value -> (Int, Int)-sourceRange v =- case preview (key "src" . _String) v of- Just (Text.splitOn ":" -> [readAs -> Just i, readAs -> Just n, _]) ->- (i, i + n)- _ ->- error "internal error: no source position for AST node"--fromJust' :: String -> Maybe a -> a-fromJust' msg = \case- Just x -> x- Nothing -> error msg--repeated :: Eq a => [a] -> [a]-repeated = fmap fst $ foldl' f ([], [])- where- f (acc, seen) x =- ( if (x `elem` seen) && (not $ x `elem` acc)- then x : acc- else acc- , x : seen- )--indexed :: [(Integer, Text)] -> [(Integer, Text)]-indexed = fst . foldl' f ([], Map.empty) -- (zip (fmap snd xs) $ replicate (length xs) 0) xs- where- f (acc, seen) (id', n) =- let- count = (fromMaybe 0 $ seen !? n) + 1- in- ((id', pack $ show count) : acc, Map.insert n count seen)
src/EVM/Format.hs view
@@ -6,8 +6,10 @@ ( formatExpr , contractNamePart , contractPathPart+ , showError , showTree , showTraceTree+ , showValues , prettyvmresult , showCall , showWordExact@@ -31,7 +33,7 @@ import EVM (VM, cheatCode, traceForest, traceData, Error (..)) import EVM (Trace, TraceData (..), Query (..), FrameContext (..)) import EVM.Types (maybeLitWord, W256 (..), num, word, Expr(..), EType(..))-import EVM.Types (Addr, ByteStringS(..))+import EVM.Types (Addr, ByteStringS(..), Error(..)) import EVM.ABI (AbiValue (..), Event (..), AbiType (..), SolError (..)) import EVM.ABI (Indexed (NotIndexed), getAbiSeq) import EVM.ABI (parseTypeName, formatString)@@ -48,7 +50,7 @@ import Data.ByteString.Lazy (toStrict, fromStrict) import Data.DoubleWord (signedWord) import Data.Foldable (toList)-import Data.Maybe (catMaybes, fromMaybe)+import Data.Maybe (catMaybes, fromMaybe, fromJust) import Data.Text (Text, pack, unpack, intercalate) import Data.Text (dropEnd, splitOn) import Data.Text.Encoding (decodeUtf8, decodeUtf8')@@ -68,20 +70,17 @@ deriving (Show) showDec :: Signedness -> W256 -> Text-showDec signed (W256 w) =- let+showDec signed (W256 w)+ | i == num cheatCode = "<hevm cheat address>"+ | (i :: Integer) == 2 ^ (256 :: Integer) - 1 = "MAX_UINT256"+ | otherwise = Text.pack (show (i :: Integer))+ where i = case signed of Signed -> num (signedWord w) Unsigned -> num w- in- if i == num cheatCode- then "<hevm cheat address>"- else if (i :: Integer) == 2 ^ (256 :: Integer) - 1- then "MAX_UINT256"- else Text.pack (show (i :: Integer)) showWordExact :: W256 -> Text-showWordExact w = humanizeInteger w+showWordExact w = humanizeInteger (toInteger w) showWordExplanation :: W256 -> DappInfo -> Text showWordExplanation w _ | w > 0xffffffff = showDec Unsigned w@@ -318,7 +317,7 @@ let calltype = if target == context then "call " else "delegatecall "- Lit hash' = hash -- FIXME: irrefutable pattern, handle symbolic+ hash' = fromJust $ maybeLitWord hash in case preview (dappSolcByHash . ix hash' . _2) dapp of Nothing -> calltype@@ -372,18 +371,27 @@ contractPathPart :: Text -> Text contractPathPart x = Text.split (== ':') x !! 0 +prettyError :: EVM.Types.Error -> String+prettyError= \case+ Invalid -> "Invalid Opcode"+ EVM.Types.IllegalOverflow -> "Illegal Overflow"+ SelfDestruct -> "Self Destruct"+ EVM.Types.StackLimitExceeded -> "Stack limit exceeded"+ EVM.Types.InvalidMemoryAccess -> "Invalid memory access"+ EVM.Types.BadJumpDestination -> "Bad jump destination"+ TmpErr err -> "Temp error: " <> err++ prettyvmresult :: (?context :: DappContext) => Expr End -> String prettyvmresult (EVM.Types.Revert _ (ConcreteBuf "")) = "Revert" prettyvmresult (EVM.Types.Revert _ msg) = "Revert: " ++ (unpack $ showError msg)-prettyvmresult (EVM.Types.Invalid _) = "Invalid Opcode" prettyvmresult (EVM.Types.Return _ (ConcreteBuf msg) _) = if BS.null msg then "Stop" else "Return: " <> show (ByteStringS msg) prettyvmresult (EVM.Types.Return _ _ _) = "Return: <symbolic>"-prettyvmresult (EVM.Types.IllegalOverflow _) = "Illegal Overflow"-prettyvmresult (EVM.Types.SelfDestruct _) = "Self Destruct"+prettyvmresult (Failure _ err) = prettyError err prettyvmresult e = error "Internal Error: Invalid Result: " <> show e indent :: Int -> Text -> Text
src/EVM/SMT.hs view
@@ -25,7 +25,6 @@ import Data.Word import Numeric (readHex) import Data.ByteString (ByteString)-import Data.Maybe (fromMaybe) import qualified Data.ByteString as BS import qualified Data.List as List@@ -785,10 +784,10 @@ t -> error $ "Internal Error: cannot parse " <> t <> " into an Expr" getVars :: (TS.Text -> Expr EWord) -> SolverInstance -> [TS.Text] -> IO (Map (Expr EWord) W256)-getVars parseFn inst names = Map.mapKeys parseFn <$> foldM getVar mempty names+getVars parseFn inst names = Map.mapKeys parseFn <$> foldM getOne mempty names where- getVar :: Map TS.Text W256 -> TS.Text -> IO (Map TS.Text W256)- getVar acc name = do+ getOne :: Map TS.Text W256 -> TS.Text -> IO (Map TS.Text W256)+ getOne acc name = do raw <- getValue inst (T.fromStrict name) let parsed = case parseCommentFreeFileMsg getValueRes (T.toStrict raw) of
src/EVM/Solidity.hs view
@@ -47,6 +47,7 @@ , sourceFiles , sourceLines , sourceAsts+ , immutableReferences , stripBytecodeMetadata , stripBytecodeMetadataSym , signature@@ -94,6 +95,7 @@ import System.Process import Text.Read (readMaybe) +import qualified Data.Aeson.Key as Key import qualified Data.ByteString as BS import qualified Data.ByteString.Base16 as BS16 import qualified Data.HashMap.Strict as HMap@@ -131,7 +133,9 @@ instance Read SlotType where readsPrec _ ('m':'a':'p':'p':'i':'n':'g':'(':s) =- let (lhs:rhs) = Text.splitOn " => " (pack s)+ let (lhs,rhs) = case Text.splitOn " => " (pack s) of+ (l:r) -> (l,r)+ _ -> error "could not parse storage item" first = fromJust $ parseTypeName mempty lhs target = fromJust $ parseTypeName mempty (Text.replace ")" "" (last rhs)) rest = fmap (fromJust . (parseTypeName mempty . (Text.replace "mapping(" ""))) (take (length rhs - 1) rhs)@@ -303,35 +307,35 @@ yul :: Text -> Text -> IO (Maybe ByteString) yul contract src = do (json, path) <- yul' src- let (Just f) = json ^?! key "contracts" ^? key path- (Just c) = f ^? key (if Text.null contract then "object" else contract)+ let f = (json ^?! key "contracts") ^?! key (Key.fromText path)+ c = f ^?! key (Key.fromText $ if Text.null contract then "object" else contract) bytecode = c ^?! key "evm" ^?! key "bytecode" ^?! key "object" . _String pure $ toCode <$> (Just bytecode) yulRuntime :: Text -> Text -> IO (Maybe ByteString) yulRuntime contract src = do (json, path) <- yul' src- let (Just f) = json ^?! key "contracts" ^? key path- (Just c) = f ^? key (if Text.null contract then "object" else contract)+ let f = (json ^?! key "contracts") ^?! key (Key.fromText path)+ c = f ^?! key (Key.fromText $ if Text.null contract then "object" else contract) bytecode = c ^?! key "evm" ^?! key "deployedBytecode" ^?! key "object" . _String pure $ toCode <$> (Just bytecode) solidity :: Text -> Text -> IO (Maybe ByteString) solidity contract src = do (json, path) <- solidity' src- let Just (sol, _, _) = readJSON json+ let (sol, _, _) = fromJust $ readJSON json return (sol ^? ix (path <> ":" <> contract) . creationCode) solcRuntime :: Text -> Text -> IO (Maybe ByteString) solcRuntime contract src = do (json, path) <- solidity' src- let Just (sol, _, _) = readJSON json+ let (sol, _, _) = fromJust $ readJSON json return (sol ^? ix (path <> ":" <> contract) . runtimeCode) functionAbi :: Text -> IO Method functionAbi f = do (json, path) <- solidity' ("contract ABI { function " <> f <> " public {}}")- let Just (sol, _, _) = readJSON json+ let (sol, _, _) = fromJust $ readJSON json case Map.toList $ sol ^?! ix (path <> ":ABI") . abiMap of [(_,b)] -> return b _ -> error "hevm internal error: unexpected abi format"@@ -347,11 +351,11 @@ -- deprecate me soon readCombinedJSON :: Text -> Maybe (Map Text SolcContract, Map Text Value, [(Text, Maybe ByteString)]) readCombinedJSON json = do- contracts <- f <$> (json ^? key "contracts" . _Object)+ contracts <- f . KeyMap.toHashMapText <$> (json ^? key "contracts" . _Object) sources <- toList . fmap (view _String) <$> json ^? key "sourceList" . _Array return (contracts, Map.fromList (HMap.toList asts), [ (x, Nothing) | x <- sources]) where- asts = fromMaybe (error "JSON lacks abstract syntax trees.") (json ^? key "sources" . _Object)+ asts = KeyMap.toHashMapText $ fromMaybe (error "JSON lacks abstract syntax trees.") (json ^? key "sources" . _Object) f x = Map.fromList . HMap.toList $ HMap.mapWithKey g x g s x = let@@ -378,9 +382,9 @@ readStdJSON :: Text -> Maybe (Map Text SolcContract, Map Text Value, [(Text, Maybe ByteString)]) readStdJSON json = do- contracts <- json ^? key "contracts" ._Object+ contracts <- KeyMap.toHashMapText <$> json ^? key "contracts" ._Object -- TODO: support the general case of "urls" and "content" in the standard json- sources <- json ^? key "sources" . _Object+ sources <- KeyMap.toHashMapText <$> json ^? key "sources" . _Object let asts = force "JSON lacks abstract syntax trees." . preview (key "ast") <$> sources contractMap = f contracts contents src = (src, encodeUtf8 <$> HMap.lookup src (mconcat $ Map.elems $ snd <$> contractMap))@@ -388,7 +392,7 @@ where f :: (AsValue s) => HMap.HashMap Text s -> (Map Text (SolcContract, (HMap.HashMap Text Text))) f x = Map.fromList . (concatMap g) . HMap.toList $ x- g (s, x) = h s <$> HMap.toList (view _Object x)+ g (s, x) = h s <$> HMap.toList (KeyMap.toHashMapText (view _Object x)) h :: Text -> (Text, Value) -> (Text, (SolcContract, HMap.HashMap Text Text)) h s (c, x) = let@@ -399,7 +403,7 @@ theCreationCode = toCode $ fromMaybe "" $ creation ^? key "object" . _String srcContents :: Maybe (HMap.HashMap Text Text) srcContents = do metadata <- x ^? key "metadata" . _String- srcs <- metadata ^? key "sources" . _Object+ srcs <- KeyMap.toHashMapText <$> metadata ^? key "sources" . _Object return $ (view (key "content" . _String)) <$> (HMap.filter (isJust . preview (key "content")) srcs) abis = force ("abi key not found in " <> show x) $ toList <$> x ^? key "abi" . _Array@@ -498,7 +502,7 @@ do name <- item ^? key "label" . _String offset <- item ^? key "offset" . _Number >>= toBoundedInteger slot <- item ^? key "slot" . _String- typ <- item ^? key "type" . _String+ typ <- Key.fromText <$> item ^? key "type" . _String slotType <- types ^?! key typ ^? key "label" . _String return (name, StorageItem (read $ Text.unpack slotType) offset (read $ Text.unpack slot))) @@ -688,7 +692,7 @@ candidates = (flip Data.List.isInfixOf concretes) <$> bzzrs in case elemIndex True candidates of Nothing -> b- Just i -> let Just ind = infixIndex (bzzrs !! i) concretes+ Just i -> let ind = fromJust $ infixIndex (bzzrs !! i) concretes in take ind b infixIndex :: (Eq a) => [a] -> [a] -> Maybe Int
src/EVM/SymExec.hs view
@@ -173,7 +173,7 @@ ConcreteS -> ConcreteStore mempty caller' = Caller 0 value' = CallValue 0- code' = RuntimeCode $ fromJust $ Expr.toList (ConcreteBuf contractCode)+ code' = RuntimeCode (ConcreteRuntimeCode contractCode) vm' = loadSymVM code' store caller' value' calldata' calldataProps precond = case maybepre of Nothing -> []@@ -346,14 +346,14 @@ Nothing -> error "Internal Error: vm in intermediate state after call to runFully" Just (VMSuccess buf) -> Return asserts buf (view (env . EVM.storage) vm) Just (VMFailure e) -> case e of- UnrecognizedOpcode _ -> Invalid asserts- SelfDestruction -> SelfDestruct asserts- EVM.StackLimitExceeded -> EVM.Types.StackLimitExceeded asserts- EVM.IllegalOverflow -> EVM.Types.IllegalOverflow asserts+ UnrecognizedOpcode _ -> Failure asserts Invalid+ SelfDestruction -> Failure asserts SelfDestruct+ EVM.StackLimitExceeded -> Failure asserts EVM.Types.StackLimitExceeded+ EVM.IllegalOverflow -> Failure asserts EVM.Types.IllegalOverflow EVM.Revert buf -> EVM.Types.Revert asserts buf- EVM.InvalidMemoryAccess -> EVM.Types.InvalidMemoryAccess asserts- EVM.BadJumpDestination -> EVM.Types.BadJumpDestination asserts- e' -> EVM.Types.TmpErr asserts $ show e'+ EVM.InvalidMemoryAccess -> Failure asserts EVM.Types.InvalidMemoryAccess+ EVM.BadJumpDestination -> Failure asserts EVM.Types.BadJumpDestination+ e' -> Failure asserts $ EVM.Types.TmpErr (show e') -- | Converts a given top level expr into a list of final states and the associated path conditions for each state flattenExpr :: Expr End -> [([Prop], Expr End)]@@ -362,15 +362,10 @@ go :: [Prop] -> Expr End -> [([Prop], Expr End)] go pcs = \case ITE c t f -> go (PNeg ((PEq c (Lit 0))) : pcs) t <> go (PEq c (Lit 0) : pcs) f- e@(Invalid _) -> [(pcs, e)]- e@(SelfDestruct _) -> [(pcs, e)] e@(Revert _ _) -> [(pcs, e)] e@(Return _ _ _) -> [(pcs, e)]- e@(EVM.Types.IllegalOverflow _) -> [(pcs, e)]- e@(EVM.Types.StackLimitExceeded _ ) -> [(pcs, e)]- e@(EVM.Types.InvalidMemoryAccess _) -> [(pcs, e)]- e@(EVM.Types.BadJumpDestination _) -> [(pcs, e)]- TmpErr _ s -> error s+ Failure _ (TmpErr s) -> error s+ e@(Failure _ _) -> [(pcs, e)] GVar _ -> error "cannot flatten an Expr containing a GVar" -- | Strips unreachable branches from a given expr@@ -413,6 +408,7 @@ Unsat -> pure ([query], Nothing) r -> error $ "Invalid solver result: " <> show r + -- | Evaluate the provided proposition down to its most concrete result evalProp :: Prop -> Prop evalProp = \case@@ -450,15 +446,9 @@ extractProps :: Expr End -> [Prop] extractProps = \case ITE _ _ _ -> []- Invalid asserts -> asserts- SelfDestruct asserts -> asserts Revert asserts _ -> asserts Return asserts _ _ -> asserts- EVM.Types.IllegalOverflow asserts -> asserts- EVM.Types.StackLimitExceeded asserts -> asserts- EVM.Types.InvalidMemoryAccess asserts -> asserts- EVM.Types.BadJumpDestination asserts -> asserts- TmpErr asserts _ -> asserts+ Failure asserts _ -> asserts GVar _ -> error "cannot extract props from a GVar" @@ -538,14 +528,13 @@ (Revert _ a, Revert _ b) -> if a==b then PBool False else a ./= b (Revert _ _, _) -> PBool True (_, Revert _ _) -> PBool True- (Invalid _, Invalid _) -> PBool False- (Invalid _, _ ) -> PBool True- (_, Invalid _) -> PBool True- (EVM.Types.StackLimitExceeded _, EVM.Types.StackLimitExceeded _ ) -> PBool False- (EVM.Types.StackLimitExceeded _, _) -> PBool True- (_, EVM.Types.StackLimitExceeded _) -> PBool True- (a, b) -> if a == b then PBool False- else error $ "Unimplemented, see TODO about EVM failures and TmpExpr. Left: " <> show a <> " Right: " <> show b+ (Failure _ erra, Failure _ errb) -> if erra==errb then PBool False else PBool True+ (GVar _, _) -> error "Expressions cannot contain global vars"+ (_ , GVar _) -> error "Expressions cannot contain global vars"+ (Failure _ (TmpErr s), _) -> error $ "Unhandled error: " <> s+ (_, Failure _ (TmpErr s)) -> error $ "Unhandled error: " <> s+ (ITE _ _ _, _ ) -> error "Expressions must be flattened"+ (_, ITE _ _ _) -> error "Expressions must be flattened" -- if the SMT solver can find a common input that satisfies BOTH sets of path conditions -- AND the output differs, then we are in trouble. We do this for _every_ pair of paths, which
src/EVM/TTY.hs view
@@ -41,7 +41,7 @@ import Data.Aeson.Lens import Data.ByteString (ByteString)-import Data.Maybe (isJust, fromJust, fromMaybe)+import Data.Maybe (isJust, fromJust, fromMaybe, isNothing) import Data.Map (Map, insert, lookupLT, singleton, filter) import Data.Text (Text, pack) import Data.Text.Encoding (decodeUtf8)@@ -184,7 +184,7 @@ -- Stepper wants to make a query and wait for the results? Stepper.IOAct q -> do- zoom uiVm (StateT (runStateT q)) >>= interpret mode . k+ Brick.zoom uiVm (StateT (runStateT q)) >>= interpret mode . k -- Stepper wants to modify the VM. Stepper.EVM m -> do@@ -317,13 +317,13 @@ ,?maxIter :: Maybe Integer) => UiVmState -> StepMode- -> EventM n (Next UiState)+ -> EventM n UiState () takeStep ui mode = liftIO nxt >>= \case- (Stopped (), ui') ->- continue (ViewVm ui')- (Continue steps, ui') -> do- continue (ViewVm (ui' & set uiStepper steps))+ (Stopped (), _) ->+ pure ()+ (Continue steps, ui') ->+ put (ViewVm (ui' & set uiStepper steps)) where m = interpret mode (view uiStepper ui) nxt = runStateT m ui@@ -331,128 +331,140 @@ backstepUntil :: (?fetcher :: Fetcher ,?maxIter :: Maybe Integer)- => (UiVmState -> Pred VM) -> UiVmState -> EventM n (Next UiState)-backstepUntil p s =- case view uiStep s of- 0 -> continue (ViewVm s)- n -> do- s1 <- backstep s- let- -- find a previous vm that satisfies the predicate- snapshots' = Data.Map.filter (p s1 . fst) (view uiSnapshots s1)- case lookupLT n snapshots' of- -- If no such vm exists, go to the beginning- Nothing ->- let- (step', (vm', stepper')) = fromJust $ lookupLT (n - 1) (view uiSnapshots s)- s2 = s1- & set uiVm vm'- & set (uiVm . cache) (view (uiVm . cache) s1)- & set uiStep step'- & set uiStepper stepper'- in takeStep s2 (Step 0)- -- step until the predicate doesn't hold- Just (step', (vm', stepper')) ->- let- s2 = s1- & set uiVm vm'- & set (uiVm . cache) (view (uiVm . cache) s1)- & set uiStep step'- & set uiStepper stepper'- in takeStep s2 (StepUntil (not . p s1))+ => (UiVmState -> Pred VM) -> EventM n UiState ()+backstepUntil p = get >>= \case+ ViewVm s ->+ case view uiStep s of+ 0 -> pure ()+ n -> do+ s1 <- liftIO $ backstep s+ let+ -- find a previous vm that satisfies the predicate+ snapshots' = Data.Map.filter (p s1 . fst) (view uiSnapshots s1)+ case lookupLT n snapshots' of+ -- If no such vm exists, go to the beginning+ Nothing ->+ let+ (step', (vm', stepper')) = fromJust $ lookupLT (n - 1) (view uiSnapshots s)+ s2 = s1+ & set uiVm vm'+ & set (uiVm . cache) (view (uiVm . cache) s1)+ & set uiStep step'+ & set uiStepper stepper'+ in takeStep s2 (Step 0)+ -- step until the predicate doesn't hold+ Just (step', (vm', stepper')) ->+ let+ s2 = s1+ & set uiVm vm'+ & set (uiVm . cache) (view (uiVm . cache) s1)+ & set uiStep step'+ & set uiStepper stepper'+ in takeStep s2 (StepUntil (not . p s1))+ _ -> pure () backstep :: (?fetcher :: Fetcher ,?maxIter :: Maybe Integer)- => UiVmState -> EventM n UiVmState-backstep s = case view uiStep s of- -- We're already at the first step; ignore command.- 0 -> return s- -- To step backwards, we revert to the previous snapshot- -- and execute n - 1 `mod` snapshotInterval steps from there.+ => UiVmState -> IO UiVmState+backstep s =+ case view uiStep s of+ -- We're already at the first step; ignore command.+ 0 -> pure s+ -- To step backwards, we revert to the previous snapshot+ -- and execute n - 1 `mod` snapshotInterval steps from there. - -- We keep the current cache so we don't have to redo- -- any blocking queries, and also the memory view.- n ->- let- (step, (vm, stepper)) = fromJust $ lookupLT n (view uiSnapshots s)- s1 = s- & set uiVm vm- & set (uiVm . cache) (view (uiVm . cache) s)- & set uiStep step- & set uiStepper stepper- stepsToTake = n - step - 1+ -- We keep the current cache so we don't have to redo+ -- any blocking queries, and also the memory view.+ n ->+ let+ (step, (vm, stepper)) = fromJust $ lookupLT n (view uiSnapshots s)+ s1 = s+ & set uiVm vm+ & set (uiVm . cache) (view (uiVm . cache) s)+ & set uiStep step+ & set uiStepper stepper+ stepsToTake = n - step - 1 - in- liftIO $ runStateT (interpret (Step stepsToTake) stepper) s1 >>= \case- (Continue steps, ui') -> return $ ui' & set uiStepper steps- _ -> error "unexpected end"+ in+ runStateT (interpret (Step stepsToTake) stepper) s1 >>= \case+ (Continue steps, ui') -> pure $ ui' & set uiStepper steps+ _ -> error "unexpected end" appEvent :: (?fetcher::Fetcher, ?maxIter :: Maybe Integer) =>- UiState -> BrickEvent Name e ->- EventM Name (Next UiState)+ EventM Name UiState () -- Contracts: Down - list down-appEvent (ViewContracts s) (VtyEvent e@(V.EvKey V.KDown [])) = do- s' <- handleEventLensed s- browserContractList- handleListEvent- e- continue (ViewContracts s')+appEvent (VtyEvent e@(V.EvKey V.KDown [])) = get >>= \case+ ViewContracts _s -> do+ Brick.zoom+ (_ViewContracts . browserContractList)+ (handleListEvent e)+ pure ()+ _ -> pure () -- Contracts: Up - list up-appEvent (ViewContracts s) (VtyEvent e@(V.EvKey V.KUp [])) = do- s' <- handleEventLensed s- browserContractList- handleListEvent- e- continue (ViewContracts s')+-- Page: Up - scroll+appEvent (VtyEvent e@(V.EvKey V.KUp [])) = get >>= \case+ ViewContracts _s -> do+ Brick.zoom+ (_ViewContracts . browserContractList)+ (handleListEvent e)+ _ -> pure () -- Vm Overview: Esc - return to test picker or exit-appEvent st@(ViewVm s) (VtyEvent (V.EvKey V.KEsc [])) =- let opts = view uiTestOpts s- dapp' = dapp (view uiTestOpts s)- tests = concatMap- (debuggableTests opts)- (view dappUnitTests dapp')- in case tests of- [] -> halt st- ts ->- continue . ViewPicker $- UiTestPickerState- { _testPickerList =- list- TestPickerPane- (Vec.fromList- ts)- 1- , _testPickerDapp = dapp'- , _testOpts = opts- }+-- Any: Esc - return to Vm Overview or Exit+appEvent (VtyEvent (V.EvKey V.KEsc [])) = get >>= \case+ ViewVm s -> do+ let opts = s ^. uiTestOpts+ dapp' = dapp opts+ tests = concatMap (debuggableTests opts) (dapp' ^. dappUnitTests)+ case tests of+ [] -> halt+ ts ->+ put $ ViewPicker $ UiTestPickerState+ { _testPickerList = list TestPickerPane (Vec.fromList ts) 1+ , _testPickerDapp = dapp'+ , _testOpts = opts+ }+ ViewHelp s -> put (ViewVm s)+ ViewContracts s -> put (ViewVm $ s ^. browserVm)+ _ -> halt -- Vm Overview: Enter - open contracts view-appEvent (ViewVm s) (VtyEvent (V.EvKey V.KEnter [])) =- continue . ViewContracts $ UiBrowserState- { _browserContractList =- list- BrowserPane- (Vec.fromList (Map.toList (view (uiVm . env . contracts) s)))- 2- , _browserVm = s- }+-- UnitTest Picker: Enter - select from list+appEvent (VtyEvent (V.EvKey V.KEnter [])) = get >>= \case+ ViewVm s ->+ put . ViewContracts $ UiBrowserState+ { _browserContractList =+ list+ BrowserPane+ (Vec.fromList (Map.toList (view (uiVm . env . contracts) s)))+ 2+ , _browserVm = s+ }+ ViewPicker s ->+ case listSelectedElement (view testPickerList s) of+ Nothing -> error "nothing selected"+ Just (_, x) -> do+ let initVm = initialUiVmStateForTest (view testOpts s) x+ put (ViewVm initVm)+ _ -> pure () -- Vm Overview: m - toggle memory pane-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'm') [])) =- continue (ViewVm (over uiShowMemory not s))+appEvent (VtyEvent (V.EvKey (V.KChar 'm') [])) = get >>= \case+ ViewVm s -> put (ViewVm $ over uiShowMemory not s)+ _ -> pure () -- Vm Overview: h - open help view-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'h') []))- = continue . ViewHelp $ s+appEvent (VtyEvent (V.EvKey (V.KChar 'h') [])) = get >>= \case+ ViewVm s -> put (ViewHelp s)+ _ -> pure () -- Vm Overview: spacebar - read input-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar ' ') [])) =+appEvent (VtyEvent (V.EvKey (V.KChar ' ') [])) = let loop = do Readline.getInputLine "% " >>= \case@@ -461,153 +473,126 @@ Readline.getInputLine "% " >>= \case Just hey' -> Readline.outputStrLn hey' Nothing -> pure ()- return (ViewVm s)- in- suspendAndResume $+ in do+ s <- get+ suspendAndResume $ do Readline.runInputT Readline.defaultSettings loop+ pure s -- todo refactor to zipper step forward -- Vm Overview: n - step-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'n') [])) =- if isJust $ view (uiVm . result) s- then continue (ViewVm s)- else takeStep s (Step 1)+appEvent (VtyEvent (V.EvKey (V.KChar 'n') [])) = get >>= \case+ ViewVm s ->+ when (isNothing (s ^. uiVm . result)) $+ takeStep s (Step 1)+ _ -> pure () -- Vm Overview: N - step-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'N') [])) =- if isJust $ view (uiVm . result) s- then continue (ViewVm s)- else takeStep s- (StepUntil (isNextSourcePosition s))+appEvent (VtyEvent (V.EvKey (V.KChar 'N') [])) = get >>= \case+ ViewVm s ->+ when (isNothing (s ^. uiVm . result)) $+ takeStep s (StepUntil (isNextSourcePosition s))+ _ -> pure () -- Vm Overview: C-n - step-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'n') [V.MCtrl])) =- if isJust $ view (uiVm . result) s- then continue (ViewVm s)- else takeStep s- (StepUntil (isNextSourcePositionWithoutEntering s))+appEvent (VtyEvent (V.EvKey (V.KChar 'n') [V.MCtrl])) = get >>= \case+ ViewVm s ->+ when (isNothing (s ^. uiVm . result)) $+ takeStep s (StepUntil (isNextSourcePositionWithoutEntering s))+ _ -> pure () -- Vm Overview: e - step-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'e') [])) =- if isJust $ view (uiVm . result) s- then continue (ViewVm s)- else takeStep s- (StepUntil (isExecutionHalted s))+appEvent (VtyEvent (V.EvKey (V.KChar 'e') [])) = get >>= \case+ ViewVm s ->+ when (isNothing (s ^. uiVm . result)) $+ takeStep s (StepUntil (isExecutionHalted s))+ _ -> pure () -- Vm Overview: a - step-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'a') [])) =- -- We keep the current cache so we don't have to redo- -- any blocking queries.- let- (vm, stepper) = fromJust (Map.lookup 0 (view uiSnapshots s))- s' = s- & set uiVm vm- & set (uiVm . cache) (view (uiVm . cache) s)- & set uiStep 0- & set uiStepper stepper+appEvent (VtyEvent (V.EvKey (V.KChar 'a') [])) = get >>= \case+ ViewVm s ->+ -- We keep the current cache so we don't have to redo+ -- any blocking queries.+ let+ (vm, stepper) = fromJust (Map.lookup 0 (view uiSnapshots s))+ s' = s+ & set uiVm vm+ & set (uiVm . cache) (view (uiVm . cache) s)+ & set uiStep 0+ & set uiStepper stepper - in takeStep s' (Step 0)+ in takeStep s' (Step 0)+ _ -> pure () -- Vm Overview: p - backstep-appEvent st@(ViewVm s) (VtyEvent (V.EvKey (V.KChar 'p') [])) =- case view uiStep s of- 0 ->- -- We're already at the first step; ignore command.- continue st- n -> do- -- To step backwards, we revert to the previous snapshot- -- and execute n - 1 `mod` snapshotInterval steps from there.+appEvent (VtyEvent (V.EvKey (V.KChar 'p') [])) = get >>= \case+ ViewVm s ->+ case view uiStep s of+ 0 ->+ -- We're already at the first step; ignore command.+ pure ()+ n -> do+ -- To step backwards, we revert to the previous snapshot+ -- and execute n - 1 `mod` snapshotInterval steps from there. - -- We keep the current cache so we don't have to redo- -- any blocking queries, and also the memory view.- let- (step, (vm, stepper)) = fromJust $ lookupLT n (view uiSnapshots s)- s1 = s- & set uiVm vm -- set the vm to the one from the snapshot- & set (uiVm . cache) (view (uiVm . cache) s) -- persist the cache- & set uiStep step- & set uiStepper stepper- stepsToTake = n - step - 1+ -- We keep the current cache so we don't have to redo+ -- any blocking queries, and also the memory view.+ let+ (step, (vm, stepper)) = fromJust $ lookupLT n (view uiSnapshots s)+ s1 = s+ & set uiVm vm -- set the vm to the one from the snapshot+ & set (uiVm . cache) (view (uiVm . cache) s) -- persist the cache+ & set uiStep step+ & set uiStepper stepper+ stepsToTake = n - step - 1 - takeStep s1 (Step stepsToTake)+ takeStep s1 (Step stepsToTake)+ _ -> pure () -- Vm Overview: P - backstep to previous source-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'P') [])) =- backstepUntil isNextSourcePosition s+appEvent (VtyEvent (V.EvKey (V.KChar 'P') [])) =+ backstepUntil isNextSourcePosition -- Vm Overview: c-p - backstep to previous source avoiding CALL and CREATE-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar 'p') [V.MCtrl])) =- backstepUntil isNextSourcePositionWithoutEntering s+appEvent (VtyEvent (V.EvKey (V.KChar 'p') [V.MCtrl])) =+ backstepUntil isNextSourcePositionWithoutEntering -- Vm Overview: 0 - choose no jump-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar '0') [])) =- case view (uiVm . result) s of- Just (VMFailure (Choose (PleaseChoosePath _ contin))) ->- takeStep (s & set uiStepper (Stepper.evm (contin True) >> (view uiStepper s)))- (Step 1)- _ -> continue (ViewVm s)+appEvent (VtyEvent (V.EvKey (V.KChar '0') [])) = get >>= \case+ ViewVm s ->+ case view (uiVm . result) s of+ Just (VMFailure (Choose (PleaseChoosePath _ contin))) ->+ takeStep (s & set uiStepper (Stepper.evm (contin True) >> (view uiStepper s)))+ (Step 1)+ _ -> pure ()+ _ -> pure () -- Vm Overview: 1 - choose jump-appEvent (ViewVm s) (VtyEvent (V.EvKey (V.KChar '1') [])) =- case view (uiVm . result) s of- Just (VMFailure (Choose (PleaseChoosePath _ contin))) ->- takeStep (s & set uiStepper (Stepper.evm (contin False) >> (view uiStepper s)))- (Step 1)- _ -> continue (ViewVm s)----- Any: Esc - return to Vm Overview or Exit-appEvent s (VtyEvent (V.EvKey V.KEsc [])) =- case s of- (ViewHelp x) -> overview x- (ViewContracts x) -> overview $ view browserVm x- _ -> halt s- where- overview = continue . ViewVm---- UnitTest Picker: Enter - select from list-appEvent (ViewPicker s) (VtyEvent (V.EvKey V.KEnter [])) =- case listSelectedElement (view testPickerList s) of- Nothing -> error "nothing selected"- Just (_, x) -> do- let initVm = initialUiVmStateForTest (view testOpts s) x- continue . ViewVm $ initVm---- UnitTest Picker: (main) - render list-appEvent (ViewPicker s) (VtyEvent e) = do- s' <- handleEventLensed s- testPickerList- handleListEvent- e- continue (ViewPicker s')---- Page: Down - scroll-appEvent (ViewVm s) (VtyEvent (V.EvKey V.KDown [])) =- if view uiShowMemory s then- vScrollBy (viewportScroll TracePane) 1 >> continue (ViewVm s)- else- if isJust $ view (uiVm . result) s- then continue (ViewVm s)- else takeStep s- (StepUntil (isNewTraceAdded s))---- Page: Up - scroll-appEvent (ViewVm s) (VtyEvent (V.EvKey V.KUp [])) =- if view uiShowMemory s then- vScrollBy (viewportScroll TracePane) (-1) >> continue (ViewVm s)- else- backstepUntil isNewTraceAdded s+appEvent (VtyEvent (V.EvKey (V.KChar '1') [])) = get >>= \case+ ViewVm s ->+ case view (uiVm . result) s of+ Just (VMFailure (Choose (PleaseChoosePath _ contin))) ->+ takeStep (s & set uiStepper (Stepper.evm (contin False) >> (view uiStepper s)))+ (Step 1)+ _ -> pure ()+ _ -> pure () -- Page: C-f - Page down-appEvent s (VtyEvent (V.EvKey (V.KChar 'f') [V.MCtrl])) =- vScrollPage (viewportScroll TracePane) Down >> continue s+appEvent (VtyEvent (V.EvKey (V.KChar 'f') [V.MCtrl])) =+ vScrollPage (viewportScroll TracePane) Down -- Page: C-b - Page up-appEvent s (VtyEvent (V.EvKey (V.KChar 'b') [V.MCtrl])) =- vScrollPage (viewportScroll TracePane) Up >> continue s+appEvent (VtyEvent (V.EvKey (V.KChar 'b') [V.MCtrl])) =+ vScrollPage (viewportScroll TracePane) Up +-- UnitTest Picker: (main) - render list+appEvent (VtyEvent e) = do+ Brick.zoom+ (_ViewPicker . testPickerList)+ (handleListEvent e)+ -- Default-appEvent s _ = continue s+appEvent _ = pure () app :: UnitTestOptions -> App UiState () Name app UnitTestOptions{..} =@@ -617,7 +602,7 @@ { appDraw = drawUi , appChooseCursor = neverShowCursor , appHandleEvent = appEvent- , appStartEvent = return+ , appStartEvent = pure () , appAttrMap = const (attrMap V.defAttr myTheme) } @@ -630,9 +615,8 @@ cd = case test of SymbolicTest _ -> symCalldata theTestName types [] (AbstractBuf "txdata") _ -> (error "unreachable", error "unreachable")- Just (test, types) = find (\(test',_) -> extractSig test' == theTestName) $ unitTestMethods testContract- Just testContract =- view (dappSolcByName . at theContractName) dapp+ (test, types) = fromJust $ find (\(test',_) -> extractSig test' == theTestName) $ unitTestMethods testContract+ testContract = fromJust $ view (dappSolcByName . at theContractName) dapp vm0 = initialUnitTestVm opts testContract script = do@@ -763,7 +747,7 @@ ] where dapp' = dapp (view (browserVm . uiTestOpts) ui)- Just (_, (_, c)) = listSelectedElement (view browserContractList ui)+ (_, (_, c)) = fromJust $ listSelectedElement (view browserContractList ui) -- currentContract = view (dappSolcByHash . ix ) dapp maybeHash ch = fromJust (error "Internal error: cannot find concrete codehash for partially symbolic code") (maybeLitWord (view codehash ch)) @@ -1051,8 +1035,8 @@ opWidget :: (Integral a, Show a) => (a, Op) -> Widget n opWidget = txt . pack . opString -selectedAttr :: AttrName; selectedAttr = "selected"-dimAttr :: AttrName; dimAttr = "dim"-wordAttr :: AttrName; wordAttr = "word"-boldAttr :: AttrName; boldAttr = "bold"-activeAttr :: AttrName; activeAttr = "active"+selectedAttr :: AttrName; selectedAttr = attrName "selected"+dimAttr :: AttrName; dimAttr = attrName "dim"+wordAttr :: AttrName; wordAttr = attrName "word"+boldAttr :: AttrName; boldAttr = attrName "bold"+activeAttr :: AttrName; activeAttr = attrName "active"
src/EVM/Transaction.hs view
@@ -15,7 +15,7 @@ import Data.Aeson (FromJSON (..)) import Data.ByteString (ByteString) import Data.Map (Map)-import Data.Maybe (fromMaybe, isNothing)+import Data.Maybe (fromMaybe, isNothing, fromJust) import qualified Data.Aeson as JSON import qualified Data.Aeson.Types as JSON@@ -78,9 +78,9 @@ to' = case txToAddr tx of Just a -> BS $ word160Bytes a Nothing -> BS mempty- Just maxFee = txMaxFeePerGas tx- Just maxPrio = txMaxPriorityFeeGas tx- Just gasPrice = txGasPrice tx+ maxFee = fromJust $ txMaxFeePerGas tx+ maxPrio = fromJust $ txMaxPriorityFeeGas tx+ gasPrice = fromJust $ txGasPrice tx accessList = txAccessList tx rlpAccessList = EVM.RLP.List $ map (\accessEntry -> EVM.RLP.List [BS $ word160Bytes (accessAddress accessEntry),@@ -163,7 +163,7 @@ toAddr <- addrFieldMaybe val "to" v <- wordField val "v" value <- wordField val "value"- txType <- fmap read <$> (val JSON..:? "type")+ txType <- fmap (read :: String -> Int) <$> (val JSON..:? "type") case txType of Just 0x00 -> return $ Transaction tdata gasLimit gasPrice nonce r s toAddr v value LegacyTransaction [] Nothing Nothing Just 0x01 -> do@@ -184,7 +184,7 @@ touchAccount a = Map.insertWith (flip const) a newAccount newAccount :: EVM.Contract-newAccount = initialContract $ EVM.RuntimeCode mempty+newAccount = initialContract $ EVM.RuntimeCode (EVM.ConcreteRuntimeCode "") -- | Increments origin nonce and pays gas deposit setupTx :: Addr -> Addr -> W256 -> Word64 -> Map Addr EVM.Contract -> Map Addr EVM.Contract
src/EVM/Traversals.hs view
@@ -66,16 +66,10 @@ -- control flow - e@(Invalid a) -> f e <> (foldl (foldProp f) mempty a)- e@(StackLimitExceeded a) -> f e <> (foldl (foldProp f) mempty a)- e@(InvalidMemoryAccess a) -> f e <> (foldl (foldProp f) mempty a)- e@(BadJumpDestination a) -> f e <> (foldl (foldProp f) mempty a)- e@(SelfDestruct a) -> f e <> (foldl (foldProp f) mempty a)- e@(IllegalOverflow a) -> f e <> (foldl (foldProp f) mempty a) e@(Revert a b) -> f e <> (foldl (foldProp f) mempty a) <> (go b) e@(Return a b c) -> f e <> (foldl (foldProp f) mempty a) <> (go b) <> (go c) e@(ITE a b c) -> f e <> (go a) <> (go b) <> (go c)- e@(TmpErr a _) -> f e <> (foldl (foldProp f) mempty a)+ e@(Failure a _) -> f e <> (foldl (foldProp f) mempty a) -- integers @@ -314,24 +308,9 @@ -- control flow - Invalid a -> do- a' <- mapM (mapPropM f) a- f (Invalid a')- SelfDestruct a -> do- a' <- mapM (mapPropM f) a- f (SelfDestruct a')- IllegalOverflow a -> do- a' <- mapM (mapPropM f) a- f (IllegalOverflow a')- InvalidMemoryAccess a -> do- a' <- mapM (mapPropM f) a- f (InvalidMemoryAccess a')- StackLimitExceeded a -> do- a' <- mapM (mapPropM f) a- f (StackLimitExceeded a')- BadJumpDestination a -> do+ Failure a b -> do a' <- mapM (mapPropM f) a- f (BadJumpDestination a')+ f (Failure a' b) Revert a b -> do a' <- mapM (mapPropM f) a b' <- mapExprM f b@@ -347,10 +326,6 @@ b' <- mapExprM f b c' <- mapExprM f c f (ITE a' b' c')-- TmpErr a b -> do- a' <- mapM (mapPropM f) a- f (TmpErr a' b) -- integers
src/EVM/Types.hs view
@@ -5,6 +5,8 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DefaultSignatures #-} +{-# OPTIONS_GHC -Wno-error=inline-rule-shadowing #-}+ module EVM.Types where import Prelude hiding (Word, LT, GT)@@ -115,6 +117,17 @@ | End deriving (Typeable) +-- EVM errors+data Error+ = Invalid+ | IllegalOverflow+ | StackLimitExceeded+ | InvalidMemoryAccess+ | BadJumpDestination+ | SelfDestruct+ | TmpErr String+ deriving (Show, Eq, Ord)+ -- Variables refering to a global environment data GVar (a :: EType) where BufVar :: Int -> GVar Buf@@ -152,17 +165,11 @@ -> Expr EWord -- control flow - Invalid :: [Prop] -> Expr End- IllegalOverflow :: [Prop] -> Expr End- SelfDestruct :: [Prop] -> Expr End- StackLimitExceeded :: [Prop] -> Expr End- InvalidMemoryAccess :: [Prop] -> Expr End- BadJumpDestination :: [Prop] -> Expr End Revert :: [Prop] -> Expr Buf -> Expr End+ Failure :: [Prop] -> Error -> Expr End Return :: [Prop] -> Expr Buf -> Expr Storage -> Expr End ITE :: Expr EWord -> Expr End -> Expr End -> Expr End- TmpErr :: [Prop] -> String -> Expr End -- TODO this is a crutch to help us not deal with all EVM failure modes in Expr- -- should be removed once EVM failure modes are handled in Expr+ -- integers Add :: Expr EWord -> Expr EWord -> Expr EWord@@ -657,6 +664,18 @@ packNibbles [] = mempty packNibbles (n1:n2:ns) = BS.singleton (toByte n1 n2) <> packNibbles ns packNibbles _ = error "can't pack odd number of nibbles"++toWord64 :: W256 -> Maybe Word64+toWord64 n =+ if n <= num (maxBound :: Word64)+ then let (W256 (Word256 _ (Word128 _ n'))) = n in Just n'+ else Nothing++toInt :: W256 -> Maybe Int+toInt n =+ if n <= num (maxBound :: Int)+ then let (W256 (Word256 _ (Word128 _ n'))) = n in Just (fromIntegral n')+ else Nothing -- Keccak hashing
src/EVM/UnitTest.hs view
@@ -17,7 +17,7 @@ import EVM.Solidity import qualified EVM.SymExec as SymExec import EVM.SymExec (defaultVeriOpts, symCalldata, verify, isQed, extractCex, runExpr, subModel, VeriOpts)-import EVM.Types+import EVM.Types hiding (Failure) import EVM.Transaction (initTx) import EVM.RLP import qualified EVM.Facts as Facts@@ -244,7 +244,9 @@ res <- Stepper.execFully case res of Right (ConcreteBuf r) ->- let AbiBool failed = decodeAbiValue AbiBoolType (BSLazy.fromStrict r)+ let failed = case decodeAbiValue AbiBoolType (BSLazy.fromStrict r) of+ AbiBool f -> f+ _ -> error "fix me with better types" in pure (shouldFail == failed) c -> error $ "internal error: unexpected failure code: " <> show c @@ -501,7 +503,11 @@ decodeCalls :: BSLazy.ByteString -> [ExploreTx] decodeCalls b = fromMaybe (error "could not decode replay data") $ do List v <- rlpdecode $ BSLazy.toStrict b- return $ flip fmap v $ \(List [BS caller', BS target, BS cd, BS ts]) -> (num (word caller'), num (word target), cd, word ts)+ pure $ unList <$> v+ where+ unList (List [BS caller', BS target, BS cd, BS ts]) =+ (num (word caller'), num (word target), cd, word ts)+ unList _ = error "fix me with better types" -- | Runs an invariant test, calls the invariant before execution begins initialExplorationStepper :: UnitTestOptions -> ABIMethod -> [ExploreTx] -> [Addr] -> Int -> Stepper (Bool, RLP)@@ -523,7 +529,8 @@ vm <- get let cs = view (env . contracts) vm noCode c = case view contractcode c of- RuntimeCode c' -> null c'+ RuntimeCode (ConcreteRuntimeCode "") -> True+ RuntimeCode (SymbolicRuntimeCode c') -> null c' _ -> False mutable m = view methodMutability m `elem` [NonPayable, Payable] knownAbis :: Map Addr SolcContract@@ -585,7 +592,7 @@ getTargetContracts :: UnitTestOptions -> Stepper [Addr] getTargetContracts UnitTestOptions{..} = do vm <- Stepper.evm get- let Just contract' = currentContract vm+ let contract' = fromJust $ currentContract vm theAbi = view abiMap $ fromJust $ lookupCode (view contractcode contract') dapp setUp = abiKeccak (encodeUtf8 "targetContracts()") case Map.lookup setUp theAbi of@@ -595,9 +602,16 @@ res <- Stepper.execFully case res of Right (ConcreteBuf r) ->- let AbiTuple vs = decodeAbiValue (AbiTupleType (Vector.fromList [AbiArrayDynamicType AbiAddressType])) (BSLazy.fromStrict r)- [AbiArrayDynamic AbiAddressType targets] = Vector.toList vs- in return $ fmap (\(AbiAddress a) -> a) (Vector.toList targets)+ let vs = case decodeAbiValue (AbiTupleType (Vector.fromList [AbiArrayDynamicType AbiAddressType])) (BSLazy.fromStrict r) of+ AbiTuple v -> v+ _ -> error "fix me with better types"+ targets = case Vector.toList vs of+ [AbiArrayDynamic AbiAddressType ts] ->+ let unAbiAddress (AbiAddress a) = a+ unAbiAddress _ = error "fix me with better types"+ in unAbiAddress <$> Vector.toList ts+ _ -> error "fix me with better types"+ in pure targets _ -> error "internal error: unexpected failure code" exploreRun :: UnitTestOptions -> VM -> ABIMethod -> [ExploreTx] -> IO (Text, Either Text Text, VM)@@ -903,7 +917,9 @@ log_unnamed = Just $ showValue (head ts) args log_named =- let [key, val] = take 2 (textValues ts args)+ let (key, val) = case take 2 (textValues ts args) of+ [k, v] -> (k, v)+ _ -> error "shouldn't happen" in Just $ unquote key <> ": " <> val showDecimal dec val = pack $ show $ Decimal (num dec) val@@ -938,7 +954,7 @@ constraints %= (<> cdProps) assign (state . caller) (litAddr testCaller) assign (state . gas) testGasCall- origin' <- fromMaybe (initialContract (RuntimeCode mempty)) <$> use (env . contracts . at testOrigin)+ origin' <- fromMaybe (initialContract (RuntimeCode (ConcreteRuntimeCode ""))) <$> use (env . contracts . at testOrigin) let originBal = view balance origin' when (originBal < testGasprice * (num testGasCall)) $ error "insufficient balance for gas cost" vm <- get@@ -974,7 +990,7 @@ , vmoptAllowFFI = ffiAllowed } creator =- initialContract (RuntimeCode mempty)+ initialContract (RuntimeCode (ConcreteRuntimeCode "")) & set nonce 1 & set balance testBalanceCreate in vm
− src/EVM/VMTest.hs
@@ -1,374 +0,0 @@-{-# Language CPP #-}-{-# LANGUAGE TupleSections #-}--module EVM.VMTest- ( Case- , BlockchainCase-- , parseBCSuite-- , initTx- , setupTx- , vmForCase- , checkExpectation- ) where--import Prelude hiding (Word)--import qualified EVM-import EVM (contractcode, storage, origStorage, balance, nonce, initialContract, StorageBase(..))-import EVM.Expr (litCode, litAddr)-import qualified EVM.Concrete as EVM-import qualified EVM.FeeSchedule--import EVM.Transaction-import EVM.Types--import Control.Arrow ((***), (&&&))-import Control.Lens-import Control.Monad--import GHC.Stack--import Data.Aeson ((.:), (.:?), FromJSON (..))-import Data.Map (Map)-import Data.Maybe (fromMaybe, isNothing)-import Data.Witherable (Filterable, catMaybes)--import qualified Data.Map as Map-import qualified Data.Aeson as JSON-import qualified Data.Aeson.Types as JSON-import qualified Data.ByteString.Lazy as Lazy-import qualified Data.Vector as V-import Data.Word (Word64)--type Storage = Map W256 W256--data Which = Pre | Post--data Block = Block- { blockCoinbase :: Addr- , blockDifficulty :: W256- , blockGasLimit :: Word64- , blockBaseFee :: W256- , blockNumber :: W256- , blockTimestamp :: W256- , blockTxs :: [Transaction]- } deriving Show--data Case = Case- { testVmOpts :: EVM.VMOpts- , checkContracts :: Map Addr (EVM.Contract, Storage)- , testExpectation :: Map Addr (EVM.Contract, Storage)- } deriving Show--data BlockchainCase = BlockchainCase- { blockchainBlocks :: [Block]- , blockchainPre :: Map Addr (EVM.Contract, Storage)- , blockchainPost :: Map Addr (EVM.Contract, Storage)- , blockchainNetwork :: String- } deriving Show--splitEithers :: (Filterable f) => f (Either a b) -> (f a, f b)-splitEithers =- (catMaybes *** catMaybes)- . (fmap fst &&& fmap snd)- . (fmap (preview _Left &&& preview _Right))--checkStateFail :: Bool -> Case -> EVM.VM -> (Bool, Bool, Bool, Bool, Bool) -> IO Bool-checkStateFail diff x vm (okState, okMoney, okNonce, okData, okCode) = do- let- printContracts :: Map Addr (EVM.Contract, Storage) -> IO ()- printContracts cs = putStrLn $ Map.foldrWithKey (\k (c, s) acc ->- acc ++ show k ++ " : "- ++ (show . toInteger $ (view nonce c)) ++ " "- ++ (show . toInteger $ (view balance c)) ++ " "- ++ (printStorage s)- ++ "\n") "" cs-- reason = map fst (filter (not . snd)- [ ("bad-state", okMoney || okNonce || okData || okCode || okState)- , ("bad-balance", not okMoney || okNonce || okData || okCode || okState)- , ("bad-nonce", not okNonce || okMoney || okData || okCode || okState)- , ("bad-storage", not okData || okMoney || okNonce || okCode || okState)- , ("bad-code", not okCode || okMoney || okNonce || okData || okState)- ])- check = checkContracts x- expected = testExpectation x- actual = Map.map (,mempty) $ view (EVM.env . EVM.contracts) vm -- . to (fmap (clearZeroStorage.clearOrigStorage))) vm- printStorage = show -- TODO: fixme-- putStr (unwords reason)- when (diff && (not okState)) $ do- putStrLn "\nPre balance/state: "- printContracts check- putStrLn "\nExpected balance/state: "- printContracts expected- putStrLn "\nActual balance/state: "- printContracts actual- return okState--checkExpectation :: HasCallStack => Bool -> Case -> EVM.VM -> IO Bool-checkExpectation diff x vm = do- let expectation = testExpectation x- (okState, b2, b3, b4, b5) = checkExpectedContracts vm expectation- putStrLn $ show expectation- unless okState $ void $ checkStateFail- diff x vm (okState, b2, b3, b4, b5)- return okState---- quotient account state by nullness-(~=) :: Map Addr (EVM.Contract, Storage) -> Map Addr (EVM.Contract, Storage) -> Bool-(~=) cs1 cs2 =- let nullAccount = EVM.initialContract (EVM.RuntimeCode mempty)- padNewAccounts cs ks = Map.union cs $ Map.fromList [(k, (nullAccount, mempty)) | k <- ks]- padded_cs1 = padNewAccounts cs1 (Map.keys cs2)- padded_cs2 = padNewAccounts cs2 (Map.keys cs1)- in and $ zipWith (===) (Map.elems padded_cs1) (Map.elems padded_cs2)--(===) :: (EVM.Contract, Storage) -> (EVM.Contract, Storage) -> Bool-(c1, s1) === (c2, s2) =- codeEqual && storageEqual && (c1 ^. balance == c2 ^. balance) && (c1 ^. nonce == c2 ^. nonce)- where- storageEqual = s1 == s2- codeEqual = case (c1 ^. contractcode, c2 ^. contractcode) of- (EVM.RuntimeCode a', EVM.RuntimeCode b') -> a' == b'- _ -> error "unexpected code"--checkExpectedContracts :: HasCallStack => EVM.VM -> Map Addr (EVM.Contract, Storage) -> (Bool, Bool, Bool, Bool, Bool)-checkExpectedContracts vm expected =- let cs = zipWithStorages $ vm ^. EVM.env . EVM.contracts -- . to (fmap (clearZeroStorage.clearOrigStorage))- expectedCs = clearStorage <$> expected- in ( (expectedCs ~= cs)- , (clearBalance <$> expectedCs) ~= (clearBalance <$> cs)- , (clearNonce <$> expectedCs) ~= (clearNonce <$> cs)- , (clearStorage <$> expectedCs) ~= (clearStorage <$> cs)- , (clearCode <$> expectedCs) ~= (clearCode <$> cs)- )- where- zipWithStorages = Map.mapWithKey (\addr c -> (c, lookupStorage addr))- lookupStorage _ =- case vm ^. EVM.env . EVM.storage of- ConcreteStore _ -> mempty -- clearZeroStorage $ fromMaybe mempty $ Map.lookup (num addr) s- EmptyStore -> mempty- AbstractStore -> mempty -- error "AbstractStore, should this be handled?"- SStore {} -> mempty -- error "SStore, should this be handled?"- GVar _ -> error "unexpected global variable"--clearStorage :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)-clearStorage (c, _) = (c, mempty)--clearBalance :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)-clearBalance (c, s) = (set balance 0 c, s)--clearNonce :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)-clearNonce (c, s) = (set nonce 0 c, s)--clearCode :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)-clearCode (c, s) = (set contractcode (EVM.RuntimeCode mempty) c, s)----newtype ContractWithStorage = ContractWithStorage { unContractWithStorage :: (EVM.Contract, Storage) }--instance FromJSON ContractWithStorage where- parseJSON (JSON.Object v) = do- code <- (EVM.RuntimeCode . V.fromList . litCode <$> (hexText <$> v .: "code"))- storage' <- v .: "storage"- balance' <- v .: "balance"- nonce' <- v .: "nonce"- let c = EVM.initialContract code- & balance .~ balance'- & nonce .~ nonce'- return $ ContractWithStorage (c, storage')-- parseJSON invalid =- JSON.typeMismatch "Contract" invalid--instance FromJSON BlockchainCase where- parseJSON (JSON.Object v) = BlockchainCase- <$> v .: "blocks"- <*> parseContracts Pre v- <*> parseContracts Post v- <*> v .: "network"- parseJSON invalid =- JSON.typeMismatch "GeneralState test case" invalid--instance FromJSON Block where- parseJSON (JSON.Object v) = do- v' <- v .: "blockHeader"- txs <- v .: "transactions"- coinbase <- addrField v' "coinbase"- difficulty <- wordField v' "difficulty"- gasLimit <- word64Field v' "gasLimit"- number <- wordField v' "number"- baseFee <- fmap read <$> v' .:? "baseFeePerGas"- timestamp <- wordField v' "timestamp"- return $ Block coinbase difficulty gasLimit (fromMaybe 0 baseFee) number timestamp txs- parseJSON invalid =- JSON.typeMismatch "Block" invalid--parseContracts ::- Which -> JSON.Object -> JSON.Parser (Map Addr (EVM.Contract, Storage))-parseContracts w v =- (Map.map unContractWithStorage) <$> (v .: which >>= parseJSON)- where which = case w of- Pre -> "pre"- Post -> "postState"--parseBCSuite ::- Lazy.ByteString -> Either String (Map String Case)-parseBCSuite x = case (JSON.eitherDecode' x) :: Either String (Map String BlockchainCase) of- Left e -> Left e- Right bcCases -> let allCases = fromBlockchainCase <$> bcCases- keepError (Left e) = errorFatal e- keepError _ = True- filteredCases = Map.filter keepError allCases- (erroredCases, parsedCases) = splitEithers filteredCases- in if Map.size erroredCases > 0- then Left ("errored case: " ++ (show erroredCases))- else if Map.size parsedCases == 0- then Left "No cases to check."- else Right parsedCases---data BlockchainError- = TooManyBlocks- | TooManyTxs- | NoTxs- | SignatureUnverified- | InvalidTx- | OldNetwork- | FailedCreate- deriving Show--errorFatal :: BlockchainError -> Bool-errorFatal TooManyBlocks = True-errorFatal TooManyTxs = True-errorFatal SignatureUnverified = True-errorFatal InvalidTx = True-errorFatal _ = False--fromBlockchainCase :: BlockchainCase -> Either BlockchainError Case-fromBlockchainCase (BlockchainCase blocks preState postState network) =- case (blocks, network) of- ([block], "London") -> case blockTxs block of- [tx] -> fromBlockchainCase' block tx preState postState- [] -> Left NoTxs- _ -> Left TooManyTxs- ([_], _) -> Left OldNetwork- (_, _) -> Left TooManyBlocks--fromBlockchainCase' :: Block -> Transaction- -> Map Addr (EVM.Contract, Storage) -> Map Addr (EVM.Contract, Storage)- -> Either BlockchainError Case-fromBlockchainCase' block tx preState postState =- let isCreate = isNothing (txToAddr tx) in- case (sender 1 tx, checkTx tx block preState) of- (Nothing, _) -> Left SignatureUnverified- (_, Nothing) -> Left (if isCreate then FailedCreate else InvalidTx)- (Just origin, Just checkState) -> Right $ Case- (EVM.VMOpts- { vmoptContract = EVM.initialContract theCode- , vmoptCalldata = (cd, [])- , vmoptValue = Lit (txValue tx)- , vmoptAddress = toAddr- , vmoptCaller = litAddr origin- , vmoptStorageBase = Concrete- , vmoptOrigin = origin- , vmoptGas = txGasLimit tx - fromIntegral (txGasCost feeSchedule tx)- , vmoptBaseFee = blockBaseFee block- , vmoptPriorityFee = priorityFee tx (blockBaseFee block)- , vmoptGaslimit = txGasLimit tx- , vmoptNumber = blockNumber block- , vmoptTimestamp = Lit $ blockTimestamp block- , vmoptCoinbase = blockCoinbase block- , vmoptPrevRandao = blockDifficulty block- , vmoptMaxCodeSize = 24576- , vmoptBlockGaslimit = blockGasLimit block- , vmoptGasprice = effectiveGasPrice- , vmoptSchedule = feeSchedule- , vmoptChainId = 1- , vmoptCreate = isCreate- , vmoptTxAccessList = txAccessMap tx- , vmoptAllowFFI = False- })- checkState- postState- where- toAddr = fromMaybe (EVM.createAddress origin senderNonce) (txToAddr tx)- senderNonce = view (accountAt origin . nonce) (Map.map fst preState)- feeSchedule = EVM.FeeSchedule.berlin- toCode = Map.lookup toAddr preState- theCode = if isCreate- then EVM.InitCode (txData tx) mempty- else maybe (EVM.RuntimeCode mempty) (view contractcode) (fst <$> toCode)- effectiveGasPrice = effectiveprice tx (blockBaseFee block)- cd = if isCreate- then mempty- else ConcreteBuf $ txData tx--effectiveprice :: Transaction -> W256 -> W256-effectiveprice tx baseFee = priorityFee tx baseFee + baseFee--priorityFee :: Transaction -> W256 -> W256-priorityFee tx baseFee = let- (txPrioMax, txMaxFee) = case txType tx of- EIP1559Transaction ->- let Just maxPrio = txMaxPriorityFeeGas tx- Just maxFee = txMaxFeePerGas tx- in (maxPrio, maxFee)- _ ->- let Just gasPrice = txGasPrice tx- in (gasPrice, gasPrice)- in min txPrioMax (txMaxFee - baseFee)--maxBaseFee :: Transaction -> W256-maxBaseFee tx =- case txType tx of- EIP1559Transaction ->- let Just maxFee = txMaxFeePerGas tx- in maxFee- _ ->- let Just gasPrice = txGasPrice tx- in gasPrice---validateTx :: Transaction -> Block -> Map Addr (EVM.Contract, Storage) -> Maybe ()-validateTx tx block cs = do- let cs' = Map.map fst cs- origin <- sender 1 tx- originBalance <- (view balance) <$> view (at origin) cs'- originNonce <- (view nonce) <$> view (at origin) cs'- let gasDeposit = (effectiveprice tx (blockBaseFee block)) * (num $ txGasLimit tx)- if gasDeposit + (txValue tx) <= originBalance- && txNonce tx == originNonce && blockBaseFee block <= maxBaseFee tx- then Just ()- else Nothing--checkTx :: Transaction -> Block -> Map Addr (EVM.Contract, Storage) -> Maybe (Map Addr (EVM.Contract, Storage))-checkTx tx block prestate = do- origin <- sender 1 tx- validateTx tx block prestate- let isCreate = isNothing (txToAddr tx)- senderNonce = view (accountAt origin . nonce) (Map.map fst prestate)- toAddr = fromMaybe (EVM.createAddress origin senderNonce) (txToAddr tx)- prevCode = view (accountAt toAddr . contractcode) (Map.map fst prestate)- prevNonce = view (accountAt toAddr . nonce) (Map.map fst prestate)- if isCreate && ((case prevCode of {EVM.RuntimeCode b -> not (null b); _ -> True}) || (prevNonce /= 0))- then mzero- else- return prestate--vmForCase :: Case -> EVM.VM-vmForCase x =- let- a = checkContracts x- cs = Map.map fst a- st = Map.mapKeys num $ Map.map snd a- vm = EVM.makeVm (testVmOpts x)- & set (EVM.env . EVM.contracts) cs- & set (EVM.env . EVM.storage) (ConcreteStore st)- & set (EVM.env . EVM.origStorage) st- in- initTx vm
+ test/BlockchainTests.hs view
@@ -0,0 +1,466 @@+{-# LANGUAGE ImportQualifiedPost #-}+{-# LANGUAGE TupleSections #-}++module Main where++import Prelude hiding (Word)++import EVM qualified+import EVM (contractcode, storage, origStorage, balance, nonce, initialContract, StorageBase(..))+import EVM.Concrete qualified as EVM+import EVM.Dapp (emptyDapp)+import EVM.Expr (litAddr)+import EVM.FeeSchedule qualified+import EVM.Fetch qualified+import EVM.Stepper qualified+import EVM.SMT (withSolvers, Solver(Z3))+import EVM.Transaction+import EVM.TTY qualified as TTY+import EVM.Types++import Control.Arrow ((***), (&&&))+import Control.Lens+import Control.Monad+import Control.Monad.State.Strict (execStateT)+import Data.Aeson ((.:), (.:?), FromJSON (..))+import Data.Aeson qualified as JSON+import Data.Aeson.Types qualified as JSON+import Data.ByteString qualified as BS+import Data.ByteString.Lazy qualified as Lazy+import Data.ByteString.Lazy qualified as LazyByteString+import Data.List (isInfixOf)+import Data.Map (Map)+import Data.Map qualified as Map+import Data.Maybe (fromJust, fromMaybe, isNothing, isJust)+import Data.Word (Word64)+import System.Environment (lookupEnv, getEnv)+import System.FilePath.Find qualified as Find+import System.FilePath.Posix (makeRelative, (</>))+import Witherable (Filterable, catMaybes)++import Test.Tasty+import Test.Tasty.ExpectedFailure+import Test.Tasty.HUnit++type Storage = Map W256 W256++data Which = Pre | Post++data Block = Block+ { blockCoinbase :: Addr+ , blockDifficulty :: W256+ , blockGasLimit :: Word64+ , blockBaseFee :: W256+ , blockNumber :: W256+ , blockTimestamp :: W256+ , blockTxs :: [Transaction]+ } deriving Show++data Case = Case+ { testVmOpts :: EVM.VMOpts+ , checkContracts :: Map Addr (EVM.Contract, Storage)+ , testExpectation :: Map Addr (EVM.Contract, Storage)+ } deriving Show++data BlockchainCase = BlockchainCase+ { blockchainBlocks :: [Block]+ , blockchainPre :: Map Addr (EVM.Contract, Storage)+ , blockchainPost :: Map Addr (EVM.Contract, Storage)+ , blockchainNetwork :: String+ } deriving Show++main :: IO ()+main = do+ tests <- prepareTests+ defaultMain tests++prepareTests :: IO TestTree+prepareTests = do+ repo <- getEnv "HEVM_ETHEREUM_TESTS_REPO"+ let testsDir = "BlockchainTests/GeneralStateTests"+ let dir = repo </> testsDir+ jsonFiles <- Find.find Find.always (Find.extension Find.==? ".json") dir+ putStrLn "Loading and parsing json files from ethereum-tests..."+ isCI <- isJust <$> lookupEnv "CI"+ let problematicTests = if isCI then commonProblematicTests <> ciProblematicTests else commonProblematicTests+ let ignoredFiles = if isCI then ciIgnoredFiles else []+ groups <- mapM (\f -> testGroup (makeRelative repo f) <$> (if any (`isInfixOf` f) ignoredFiles then pure [] else testsFromFile f problematicTests)) jsonFiles+ putStrLn "Loaded."+ pure $ testGroup "ethereum-tests" groups++testsFromFile :: String -> Map String (TestTree -> TestTree) -> IO [TestTree]+testsFromFile file problematicTests = do+ parsed <- parseBCSuite <$> LazyByteString.readFile file+ case parsed of+ Left "No cases to check." -> pure [] -- error "no-cases ok"+ Left _err -> pure [] -- error err+ Right allTests -> pure $+ (\(name, x) -> testCase' name $ runVMTest False (name, x)) <$> Map.toList allTests+ where+ testCase' name assertion =+ case Map.lookup name problematicTests of+ Just f -> f (testCase name assertion)+ Nothing -> testCase name assertion++-- CI has issues with some heaver tests, disable in bulk+ciIgnoredFiles :: [String]+ciIgnoredFiles =+ [ "BlockchainTests/GeneralStateTests/VMTests/vmPerformance"+ , "BlockchainTests/GeneralStateTests/stQuadraticComplexityTest"+ , "BlockchainTests/GeneralStateTests/stStaticCall"+ ]++commonProblematicTests :: Map String (TestTree -> TestTree)+commonProblematicTests = Map.fromList+ [ ("twoOps_d0g0v0_London", expectFailBecause "TODO: regression")+ , ("sar_2^256-1_0_d0g0v0_London", expectFailBecause "TODO: regression")+ , ("shiftCombinations_d0g0v0_London", expectFailBecause "TODO: regression")+ , ("shiftSignedCombinations_d0g0v0_London", expectFailBecause "TODO: regression")+ , ("bufferSrcOffset_d14g0v0_London", expectFailBecause "TODO: regression")+ , ("bufferSrcOffset_d38g0v0_London", expectFailBecause "TODO: regression")+ , ("loopMul_d0g0v0_London", ignoreTestBecause "hevm is too slow")+ , ("loopMul_d1g0v0_London", ignoreTestBecause "hevm is too slow")+ , ("loopMul_d2g0v0_London", ignoreTestBecause "hevm is too slow")+ , ("CALLBlake2f_MaxRounds_d0g0v0_London", ignoreTestBecause "very slow, bypasses timeout due time spent in FFI")+ ]++ciProblematicTests :: Map String (TestTree -> TestTree)+ciProblematicTests = Map.fromList+ [ ("Return50000_d0g1v0_London", ignoreTest)+ , ("Return50000_2_d0g1v0_London", ignoreTest)+ , ("randomStatetest177_d0g0v0_London", ignoreTest)+ , ("static_Call50000_d0g0v0_London", ignoreTest)+ , ("static_Call50000_d1g0v0_London", ignoreTest)+ , ("static_Call50000bytesContract50_1_d1g0v0_London", ignoreTest)+ , ("static_Call50000bytesContract50_2_d1g0v0_London", ignoreTest)+ , ("static_Return50000_2_d0g0v0_London", ignoreTest)+ , ("loopExp_d10g0v0_London", ignoreTest)+ , ("loopExp_d11g0v0_London", ignoreTest)+ , ("loopExp_d12g0v0_London", ignoreTest)+ , ("loopExp_d13g0v0_London", ignoreTest)+ , ("loopExp_d14g0v0_London", ignoreTest)+ , ("loopExp_d8g0v0_London", ignoreTest)+ , ("loopExp_d9g0v0_London", ignoreTest)+ ]++runVMTest :: Bool -> (String, Case) -> IO ()+runVMTest diffmode (_name, x) =+ do+ let vm0 = vmForCase x+ result <- execStateT (EVM.Stepper.interpret (EVM.Fetch.zero 0 (Just 0)) . void $ EVM.Stepper.execFully) vm0+ maybeReason <- checkExpectation diffmode x result+ case maybeReason of+ Just reason -> assertFailure reason+ Nothing -> pure ()++-- | Example usage:+-- | $ cabal new-repl ethereum-tests+-- | ghci> debugVMTest "BlockchainTests/GeneralStateTests/VMTests/vmArithmeticTest/twoOps.json" "twoOps_d0g0v0_London"+debugVMTest :: String -> String -> IO ()+debugVMTest file test = do+ repo <- getEnv "HEVM_ETHEREUM_TESTS_REPO"+ Right allTests <- parseBCSuite <$> LazyByteString.readFile (repo </> file)+ let x = case filter (\(name, _) -> name == test) $ Map.toList allTests of+ [(_, x')] -> x'+ _ -> error "test not found"+ let vm0 = vmForCase x+ result <- withSolvers Z3 0 Nothing $ \solvers ->+ TTY.runFromVM solvers Nothing Nothing emptyDapp vm0+ void $ checkExpectation True x result++splitEithers :: (Filterable f) => f (Either a b) -> (f a, f b)+splitEithers =+ (catMaybes *** catMaybes)+ . (fmap fst &&& fmap snd)+ . (fmap (preview _Left &&& preview _Right))++checkStateFail :: Bool -> Case -> EVM.VM -> (Bool, Bool, Bool, Bool) -> IO String+checkStateFail diff x vm (okMoney, okNonce, okData, okCode) = do+ let+ printContracts :: Map Addr (EVM.Contract, Storage) -> IO ()+ printContracts cs = putStrLn $ Map.foldrWithKey (\k (c, s) acc ->+ acc ++ show k ++ " : "+ ++ (show . toInteger $ (view nonce c)) ++ " "+ ++ (show . toInteger $ (view balance c)) ++ " "+ ++ (printStorage s)+ ++ "\n") "" cs++ reason = map fst (filter (not . snd)+ [ ("bad-state", okMoney || okNonce || okData || okCode)+ , ("bad-balance", not okMoney || okNonce || okData || okCode)+ , ("bad-nonce", not okNonce || okMoney || okData || okCode)+ , ("bad-storage", not okData || okMoney || okNonce || okCode)+ , ("bad-code", not okCode || okMoney || okNonce || okData)+ ])+ check = checkContracts x+ expected = testExpectation x+ actual = Map.map (,mempty) $ view (EVM.env . EVM.contracts) vm -- . to (fmap (clearZeroStorage.clearOrigStorage))) vm+ printStorage = show -- TODO: fixme++ when diff $ do+ putStr (unwords reason)+ putStrLn "\nPre balance/state: "+ printContracts check+ putStrLn "\nExpected balance/state: "+ printContracts expected+ putStrLn "\nActual balance/state: "+ printContracts actual+ pure (unwords reason)++checkExpectation :: Bool -> Case -> EVM.VM -> IO (Maybe String)+checkExpectation diff x vm = do+ let expectation = testExpectation x+ (okState, b2, b3, b4, b5) = checkExpectedContracts vm expectation+ if okState then+ pure Nothing+ else+ Just <$> checkStateFail diff x vm (b2, b3, b4, b5)++-- quotient account state by nullness+(~=) :: Map Addr (EVM.Contract, Storage) -> Map Addr (EVM.Contract, Storage) -> Bool+(~=) cs1 cs2 =+ let nullAccount = EVM.initialContract (EVM.RuntimeCode (EVM.ConcreteRuntimeCode ""))+ padNewAccounts cs ks = Map.union cs $ Map.fromList [(k, (nullAccount, mempty)) | k <- ks]+ padded_cs1 = padNewAccounts cs1 (Map.keys cs2)+ padded_cs2 = padNewAccounts cs2 (Map.keys cs1)+ in and $ zipWith (===) (Map.elems padded_cs1) (Map.elems padded_cs2)++(===) :: (EVM.Contract, Storage) -> (EVM.Contract, Storage) -> Bool+(c1, s1) === (c2, s2) =+ codeEqual && storageEqual && (c1 ^. balance == c2 ^. balance) && (c1 ^. nonce == c2 ^. nonce)+ where+ storageEqual = s1 == s2+ codeEqual = case (c1 ^. contractcode, c2 ^. contractcode) of+ (EVM.RuntimeCode a', EVM.RuntimeCode b') -> a' == b'+ _ -> error "unexpected code"++checkExpectedContracts :: EVM.VM -> Map Addr (EVM.Contract, Storage) -> (Bool, Bool, Bool, Bool, Bool)+checkExpectedContracts vm expected =+ let cs = zipWithStorages $ vm ^. EVM.env . EVM.contracts -- . to (fmap (clearZeroStorage.clearOrigStorage))+ expectedCs = clearStorage <$> expected+ in ( (expectedCs ~= cs)+ , (clearBalance <$> expectedCs) ~= (clearBalance <$> cs)+ , (clearNonce <$> expectedCs) ~= (clearNonce <$> cs)+ , (clearStorage <$> expectedCs) ~= (clearStorage <$> cs)+ , (clearCode <$> expectedCs) ~= (clearCode <$> cs)+ )+ where+ zipWithStorages = Map.mapWithKey (\addr c -> (c, lookupStorage addr))+ lookupStorage _ =+ case vm ^. EVM.env . EVM.storage of+ ConcreteStore _ -> mempty -- clearZeroStorage $ fromMaybe mempty $ Map.lookup (num addr) s+ EmptyStore -> mempty+ AbstractStore -> mempty -- error "AbstractStore, should this be handled?"+ SStore {} -> mempty -- error "SStore, should this be handled?"+ GVar _ -> error "unexpected global variable"++clearStorage :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)+clearStorage (c, _) = (c, mempty)++clearBalance :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)+clearBalance (c, s) = (set balance 0 c, s)++clearNonce :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)+clearNonce (c, s) = (set nonce 0 c, s)++clearCode :: (EVM.Contract, Storage) -> (EVM.Contract, Storage)+clearCode (c, s) = (set contractcode (EVM.RuntimeCode (EVM.ConcreteRuntimeCode "")) c, s)++newtype ContractWithStorage = ContractWithStorage { unContractWithStorage :: (EVM.Contract, Storage) }++instance FromJSON ContractWithStorage where+ parseJSON (JSON.Object v) = do+ code <- (EVM.RuntimeCode . EVM.ConcreteRuntimeCode <$> (hexText <$> v .: "code"))+ storage' <- v .: "storage"+ balance' <- v .: "balance"+ nonce' <- v .: "nonce"+ let c = EVM.initialContract code+ & balance .~ balance'+ & nonce .~ nonce'+ return $ ContractWithStorage (c, storage')++ parseJSON invalid =+ JSON.typeMismatch "Contract" invalid++instance FromJSON BlockchainCase where+ parseJSON (JSON.Object v) = BlockchainCase+ <$> v .: "blocks"+ <*> parseContracts Pre v+ <*> parseContracts Post v+ <*> v .: "network"+ parseJSON invalid =+ JSON.typeMismatch "GeneralState test case" invalid++instance FromJSON Block where+ parseJSON (JSON.Object v) = do+ v' <- v .: "blockHeader"+ txs <- v .: "transactions"+ coinbase <- addrField v' "coinbase"+ difficulty <- wordField v' "difficulty"+ gasLimit <- word64Field v' "gasLimit"+ number <- wordField v' "number"+ baseFee <- fmap read <$> v' .:? "baseFeePerGas"+ timestamp <- wordField v' "timestamp"+ return $ Block coinbase difficulty gasLimit (fromMaybe 0 baseFee) number timestamp txs+ parseJSON invalid =+ JSON.typeMismatch "Block" invalid++parseContracts ::+ Which -> JSON.Object -> JSON.Parser (Map Addr (EVM.Contract, Storage))+parseContracts w v =+ (Map.map unContractWithStorage) <$> (v .: which >>= parseJSON)+ where which = case w of+ Pre -> "pre"+ Post -> "postState"++parseBCSuite ::+ Lazy.ByteString -> Either String (Map String Case)+parseBCSuite x = case (JSON.eitherDecode' x) :: Either String (Map String BlockchainCase) of+ Left e -> Left e+ Right bcCases -> let allCases = fromBlockchainCase <$> bcCases+ keepError (Left e) = errorFatal e+ keepError _ = True+ filteredCases = Map.filter keepError allCases+ (erroredCases, parsedCases) = splitEithers filteredCases+ in if Map.size erroredCases > 0+ then Left ("errored case: " ++ (show erroredCases))+ else if Map.size parsedCases == 0+ then Left "No cases to check."+ else Right parsedCases+++data BlockchainError+ = TooManyBlocks+ | TooManyTxs+ | NoTxs+ | SignatureUnverified+ | InvalidTx+ | OldNetwork+ | FailedCreate+ deriving Show++errorFatal :: BlockchainError -> Bool+errorFatal TooManyBlocks = True+errorFatal TooManyTxs = True+errorFatal SignatureUnverified = True+errorFatal InvalidTx = True+errorFatal _ = False++fromBlockchainCase :: BlockchainCase -> Either BlockchainError Case+fromBlockchainCase (BlockchainCase blocks preState postState network) =+ case (blocks, network) of+ ([block], "London") -> case blockTxs block of+ [tx] -> fromBlockchainCase' block tx preState postState+ [] -> Left NoTxs+ _ -> Left TooManyTxs+ ([_], _) -> Left OldNetwork+ (_, _) -> Left TooManyBlocks++fromBlockchainCase' :: Block -> Transaction+ -> Map Addr (EVM.Contract, Storage) -> Map Addr (EVM.Contract, Storage)+ -> Either BlockchainError Case+fromBlockchainCase' block tx preState postState =+ let isCreate = isNothing (txToAddr tx) in+ case (sender 1 tx, checkTx tx block preState) of+ (Nothing, _) -> Left SignatureUnverified+ (_, Nothing) -> Left (if isCreate then FailedCreate else InvalidTx)+ (Just origin, Just checkState) -> Right $ Case+ (EVM.VMOpts+ { vmoptContract = EVM.initialContract theCode+ , vmoptCalldata = (cd, [])+ , vmoptValue = Lit (txValue tx)+ , vmoptAddress = toAddr+ , vmoptCaller = litAddr origin+ , vmoptStorageBase = Concrete+ , vmoptOrigin = origin+ , vmoptGas = txGasLimit tx - fromIntegral (txGasCost feeSchedule tx)+ , vmoptBaseFee = blockBaseFee block+ , vmoptPriorityFee = priorityFee tx (blockBaseFee block)+ , vmoptGaslimit = txGasLimit tx+ , vmoptNumber = blockNumber block+ , vmoptTimestamp = Lit $ blockTimestamp block+ , vmoptCoinbase = blockCoinbase block+ , vmoptPrevRandao = blockDifficulty block+ , vmoptMaxCodeSize = 24576+ , vmoptBlockGaslimit = blockGasLimit block+ , vmoptGasprice = effectiveGasPrice+ , vmoptSchedule = feeSchedule+ , vmoptChainId = 1+ , vmoptCreate = isCreate+ , vmoptTxAccessList = txAccessMap tx+ , vmoptAllowFFI = False+ })+ checkState+ postState+ where+ toAddr = fromMaybe (EVM.createAddress origin senderNonce) (txToAddr tx)+ senderNonce = view (accountAt origin . nonce) (Map.map fst preState)+ feeSchedule = EVM.FeeSchedule.berlin+ toCode = Map.lookup toAddr preState+ theCode = if isCreate+ then EVM.InitCode (txData tx) mempty+ else maybe (EVM.RuntimeCode (EVM.ConcreteRuntimeCode "")) (view contractcode . fst) toCode+ effectiveGasPrice = effectiveprice tx (blockBaseFee block)+ cd = if isCreate+ then mempty+ else ConcreteBuf $ txData tx++effectiveprice :: Transaction -> W256 -> W256+effectiveprice tx baseFee = priorityFee tx baseFee + baseFee++priorityFee :: Transaction -> W256 -> W256+priorityFee tx baseFee = let+ (txPrioMax, txMaxFee) = case txType tx of+ EIP1559Transaction ->+ let maxPrio = fromJust $ txMaxPriorityFeeGas tx+ maxFee = fromJust $ txMaxFeePerGas tx+ in (maxPrio, maxFee)+ _ ->+ let gasPrice = fromJust $ txGasPrice tx+ in (gasPrice, gasPrice)+ in min txPrioMax (txMaxFee - baseFee)++maxBaseFee :: Transaction -> W256+maxBaseFee tx =+ case txType tx of+ EIP1559Transaction -> fromJust $ txMaxFeePerGas tx+ _ -> fromJust $ txGasPrice tx++validateTx :: Transaction -> Block -> Map Addr (EVM.Contract, Storage) -> Maybe ()+validateTx tx block cs = do+ let cs' = Map.map fst cs+ origin <- sender 1 tx+ originBalance <- (view balance) <$> view (at origin) cs'+ originNonce <- (view nonce) <$> view (at origin) cs'+ let gasDeposit = (effectiveprice tx (blockBaseFee block)) * (num $ txGasLimit tx)+ if gasDeposit + (txValue tx) <= originBalance+ && txNonce tx == originNonce && blockBaseFee block <= maxBaseFee tx+ then Just ()+ else Nothing++checkTx :: Transaction -> Block -> Map Addr (EVM.Contract, Storage) -> Maybe (Map Addr (EVM.Contract, Storage))+checkTx tx block prestate = do+ origin <- sender 1 tx+ validateTx tx block prestate+ let isCreate = isNothing (txToAddr tx)+ senderNonce = view (accountAt origin . nonce) (Map.map fst prestate)+ toAddr = fromMaybe (EVM.createAddress origin senderNonce) (txToAddr tx)+ prevCode = view (accountAt toAddr . contractcode) (Map.map fst prestate)+ prevNonce = view (accountAt toAddr . nonce) (Map.map fst prestate)+ if isCreate && ((case prevCode of {EVM.RuntimeCode (EVM.ConcreteRuntimeCode b) -> not (BS.null b); _ -> True}) || (prevNonce /= 0))+ then mzero+ else+ return prestate++vmForCase :: Case -> EVM.VM+vmForCase x =+ let+ a = checkContracts x+ cs = Map.map fst a+ st = Map.mapKeys num $ Map.map snd a+ vm = EVM.makeVm (testVmOpts x)+ & set (EVM.env . EVM.contracts) cs+ & set (EVM.env . EVM.storage) (ConcreteStore st)+ & set (EVM.env . EVM.origStorage) st+ in+ initTx vm
test/rpc.hs view
@@ -75,10 +75,14 @@ postVm <- withSolvers Z3 1 Nothing $ \solvers -> execStateT (Stepper.interpret (Fetch.oracle solvers (Just (BlockNumber blockNum, testRpc))) . void $ Stepper.execFully) vm let- (ConcreteStore postStore) = view (env . storage) postVm+ postStore = case view (env . storage) postVm of+ ConcreteStore s -> s+ _ -> error "ConcreteStore expected" wethStore = fromJust $ Map.lookup 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 postStore receiverBal = fromJust $ Map.lookup (keccak' (word256Bytes 0xdead <> word256Bytes 0x3)) wethStore- (Just (VMSuccess msg)) = view result postVm+ msg = case view result postVm of+ Just (VMSuccess m) -> m+ _ -> error "VMSuccess expected" assertEqual "should succeed" msg (ConcreteBuf $ word256Bytes 0x1) assertEqual "should revert" receiverBal (W256 $ 2595433725034301 + wad)
test/test.hs view
@@ -7,7 +7,7 @@ import Data.Text (Text) import Data.ByteString (ByteString)-import Data.Bits+import Data.Bits hiding (And, Xor) import System.Directory import GHC.Natural import Control.Monad@@ -19,19 +19,18 @@ import Prelude hiding (fail, LT, GT) import qualified Data.ByteString as BS-import qualified Data.ByteString.Lazy as BS (fromStrict) import qualified Data.ByteString.Base16 as Hex import Data.Maybe import Data.Typeable import Data.List (elemIndex) import Data.DoubleWord import Test.Tasty-import Test.Tasty.QuickCheck+import Test.Tasty.QuickCheck hiding (Failure) import Test.QuickCheck.Instances.Text() import Test.QuickCheck.Instances.Natural() import Test.QuickCheck.Instances.ByteString() import Test.Tasty.HUnit-import Test.Tasty.Runners+import Test.Tasty.Runners hiding (Failure) import Test.Tasty.ExpectedFailure import Control.Monad.State.Strict (execState, runState)@@ -329,7 +328,9 @@ -- traceM ("encoding: " ++ (show y) ++ " : " ++ show (abiValueType y)) Just encoded <- runStatements [i| x = abi.encode(a);|] [y] AbiBytesDynamicType- let AbiTuple (Vector.toList -> [solidityEncoded]) = decodeAbiValue (AbiTupleType $ Vector.fromList [AbiBytesDynamicType]) (BS.fromStrict encoded)+ let solidityEncoded = case decodeAbiValue (AbiTupleType $ Vector.fromList [AbiBytesDynamicType]) (BS.fromStrict encoded) of+ AbiTuple (Vector.toList -> [e]) -> e+ _ -> error "AbiTuple expected" let hevmEncoded = encodeAbiValue (AbiTuple $ Vector.fromList [y]) -- traceM ("encoded (solidity): " ++ show solidityEncoded) -- traceM ("encoded (hevm): " ++ show (AbiBytesDynamic hevmEncoded))@@ -340,7 +341,9 @@ -- traceM ("encoding: " ++ (show x') ++ ", " ++ (show y') ++ " : " ++ show (abiValueType x') ++ ", " ++ show (abiValueType y')) Just encoded <- runStatements [i| x = abi.encode(a, b);|] [x', y'] AbiBytesDynamicType- let AbiTuple (Vector.toList -> [solidityEncoded]) = decodeAbiValue (AbiTupleType $ Vector.fromList [AbiBytesDynamicType]) (BS.fromStrict encoded)+ let solidityEncoded = case decodeAbiValue (AbiTupleType $ Vector.fromList [AbiBytesDynamicType]) (BS.fromStrict encoded) of+ AbiTuple (Vector.toList -> [e]) -> e+ _ -> error "AbiTuple expected" let hevmEncoded = encodeAbiValue (AbiTuple $ Vector.fromList [x',y']) -- traceM ("encoded (solidity): " ++ show solidityEncoded) -- traceM ("encoded (hevm): " ++ show (AbiBytesDynamic hevmEncoded))@@ -421,9 +424,9 @@ |] (json, path') <- solidity' srccode- let Just (solc', _, _) = readJSON json+ let (solc', _, _) = fromJust $ readJSON json initCode :: ByteString- Just initCode = solc' ^? ix (path' <> ":A") . creationCode+ initCode = fromJust $ solc' ^? ix (path' <> ":A") . creationCode -- add constructor arguments assertEqual "constructor args screwed up metadata stripping" (stripBytecodeMetadata (initCode <> encodeAbiValue (AbiUInt 256 1))) (stripBytecodeMetadata initCode) ]@@ -1036,11 +1039,15 @@ } } |]- let pre preVM = let [x, y] = getStaticAbiArgs 2 preVM+ let pre preVM = let (x, y) = case getStaticAbiArgs 2 preVM of+ [x', y'] -> (x', y')+ _ -> error "expected 2 args" in (x .<= Expr.add x y) .&& view (state . callvalue) preVM .== Lit 0 post prestate leaf =- let [x, y] = getStaticAbiArgs 2 prestate+ let (x, y) = case getStaticAbiArgs 2 prestate of+ [x', y'] -> (x', y')+ _ -> error "expected 2 args" in case leaf of Return _ b _ -> (ReadWord (Lit 0) b) .== (Add x y) _ -> PBool True@@ -1057,12 +1064,16 @@ } } |]- let pre preVM = let [x, y] = getStaticAbiArgs 2 preVM+ let pre preVM = let (x, y) = case getStaticAbiArgs 2 preVM of+ [x', y'] -> (x', y')+ _ -> error "expected 2 args" in (x .<= Expr.add x y) .&& (x .== y) .&& view (state . callvalue) preVM .== Lit 0 post prestate leaf =- let [_, y] = getStaticAbiArgs 2 prestate+ let (_, y) = case getStaticAbiArgs 2 prestate of+ [x', y'] -> (x', y')+ _ -> error "expected 2 args" in case leaf of Return _ b _ -> (ReadWord (Lit 0) b) .== (Mul (Lit 2) y) _ -> PBool True@@ -1085,7 +1096,9 @@ |] let pre vm = Lit 0 .== view (state . callvalue) vm post prestate leaf =- let [y] = getStaticAbiArgs 1 prestate+ let y = case getStaticAbiArgs 1 prestate of+ [y'] -> y'+ _ -> error "expected 1 arg" this = Expr.litAddr $ view (state . codeContract) prestate prex = Expr.readStorage' this (Lit 0) (view (env . storage) prestate) in case leaf of@@ -1137,7 +1150,9 @@ |] let pre vm = (Lit 0) .== view (state . callvalue) vm post prestate poststate =- let [x,y] = getStaticAbiArgs 2 prestate+ let (x,y) = case getStaticAbiArgs 2 prestate of+ [x',y'] -> (x',y')+ _ -> error "expected 2 args" this = Expr.litAddr $ view (state . codeContract) prestate prestore = view (env . storage) prestate prex = Expr.readStorage' this x prestore@@ -1169,7 +1184,9 @@ |] let pre vm = (Lit 0) .== view (state . callvalue) vm post prestate poststate =- let [x,y] = getStaticAbiArgs 2 prestate+ let (x,y) = case getStaticAbiArgs 2 prestate of+ [x',y'] -> (x',y')+ _ -> error "expected 2 args" this = Expr.litAddr $ view (state . codeContract) prestate prestore = view (env . storage) prestate prex = Expr.readStorage' this x prestore@@ -1613,7 +1630,7 @@ let vm = vm0 & set (state . callvalue) (Lit 0) & over (env . contracts)- (Map.insert aAddr (initialContract (RuntimeCode (fromJust $ Expr.toList $ ConcreteBuf a))))+ (Map.insert aAddr (initialContract (RuntimeCode (ConcreteRuntimeCode a)))) -- NOTE: this used to as follows, but there is no _storage field in Contract record -- (Map.insert aAddr (initialContract (RuntimeCode $ ConcreteBuffer a) & -- set EVM.storage (EVM.Symbolic [] store)))@@ -2124,7 +2141,7 @@ case runState exec (vmForEthrunCreation x) of (VMSuccess (ConcreteBuf targetCode), vm1) -> do let target = view (state . contract) vm1- vm2 = execState (replaceCodeOfSelf (RuntimeCode (fromJust $ Expr.toList $ ConcreteBuf targetCode))) vm1+ vm2 = execState (replaceCodeOfSelf (RuntimeCode (ConcreteRuntimeCode targetCode))) vm1 return $ snd $ flip runState vm2 (do resetState assign (state . gas) 0xffffffffffffffff -- kludge@@ -2188,7 +2205,9 @@ -- includes shaving off 4 byte function sig decodeAbiValues :: [AbiType] -> ByteString -> [AbiValue] decodeAbiValues types bs =- let AbiTuple xy = decodeAbiValue (AbiTupleType $ Vector.fromList types) (BS.fromStrict (BS.drop 4 bs))+ let xy = case decodeAbiValue (AbiTupleType $ Vector.fromList types) (BS.fromStrict (BS.drop 4 bs)) of+ AbiTuple xy' -> xy'+ _ -> error "AbiTuple expected" in Vector.toList xy newtype Bytes = Bytes ByteString@@ -2270,13 +2289,14 @@ genNat = fmap fromIntegral (arbitrary :: Gen Natural) genName :: Gen Text-genName = fmap T.pack $ listOf1 (oneof . (fmap pure) $ ['a'..'z'] <> ['A'..'Z'])+-- In order not to generate SMT reserved words, we prepend with "esc_"+genName = fmap (T.pack . ("esc_" <> )) $ listOf1 (oneof . (fmap pure) $ ['a'..'z'] <> ['A'..'Z']) genEnd :: Int -> Gen (Expr End) genEnd 0 = oneof- [ pure $ Invalid []- , pure $ EVM.Types.IllegalOverflow []- , pure $ SelfDestruct []+ [ pure $ Failure [] Invalid+ , pure $ Failure [] EVM.Types.IllegalOverflow+ , pure $ Failure [] SelfDestruct ] genEnd sz = oneof [ fmap (EVM.Types.Revert []) subBuf