From c6c4b44af0137ccfdab8197a7dd1e4ae69114edb Mon Sep 17 00:00:00 2001 From: Mate Soos Date: Thu, 28 Nov 2024 13:04:28 +0100 Subject: [PATCH] Fixing up prank Related to #608 --- src/EVM.hs | 52 +++++++++++++++++++++++------------------------- src/EVM/Types.hs | 4 ++-- test/test.hs | 2 +- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/EVM.hs b/src/EVM.hs index a5a83930c..77a30bade 100644 --- a/src/EVM.hs +++ b/src/EVM.hs @@ -83,6 +83,8 @@ blankState = do , gas = initialGas , returndata = mempty , static = False + , overrideCaller = Nothing + , resetCaller = True } -- | An "external" view of a contract's bytecode, appropriate for @@ -145,6 +147,8 @@ makeVm o = do , gas = o.gas , returndata = mempty , static = False + , overrideCaller = Nothing + , resetCaller = True } , env = env , cache = cache @@ -153,8 +157,6 @@ makeVm o = do , iterations = mempty , config = RuntimeConfig { allowFFI = o.allowFFI - , resetCaller = True - , overrideCaller = Nothing , baseState = o.baseState } , forks = Seq.singleton (ForkState env block cache "") @@ -866,17 +868,16 @@ exec1 = do forceAddr xTo' "unable to determine a call target" $ \xTo -> case gasTryFrom xGas of Left _ -> vmError IllegalOverflow - Right gas -> + Right gas -> do + overrideC <- use $ #state % #overrideCaller delegateCall this gas xTo xTo xValue xInOffset xInSize xOutOffset xOutSize xs $ \callee -> do - let from' = fromMaybe self vm.config.overrideCaller + let from' = fromMaybe self overrideC zoom #state $ do assign #callvalue xValue assign #caller from' assign #contract callee - do - resetCaller <- use (#config % #resetCaller) - when (resetCaller) $ assign (#config % #overrideCaller) Nothing + assign #overrideCaller Nothing touchAccount from' touchAccount callee transfer from' callee xValue @@ -889,14 +890,13 @@ exec1 = do forceAddr xTo' "unable to determine a call target" $ \xTo -> case gasTryFrom xGas of Left _ -> vmError IllegalOverflow - Right gas -> + Right gas -> do + overrideC <- use $ #state % #overrideCaller delegateCall this gas xTo self xValue xInOffset xInSize xOutOffset xOutSize xs $ \_ -> do zoom #state $ do assign #callvalue xValue - assign #caller $ fromMaybe self vm.config.overrideCaller - do - resetCaller <- use (#config % #resetCaller) - when (resetCaller) $ assign (#config % #overrideCaller) Nothing + assign #caller $ fromMaybe self overrideC + assign #overrideCaller Nothing touchAccount self _ -> underrun @@ -978,17 +978,16 @@ exec1 = do Just xTo' -> case gasTryFrom xGas of Left _ -> vmError IllegalOverflow - Right gas -> + Right gas -> do + overrideC <- use $ #state % #overrideCaller delegateCall this gas xTo' xTo' (Lit 0) xInOffset xInSize xOutOffset xOutSize xs $ \callee -> do zoom #state $ do assign #callvalue (Lit 0) - assign #caller $ fromMaybe self (vm.config.overrideCaller) + assign #caller $ fromMaybe self overrideC assign #contract callee assign #static True - do - resetCaller <- use (#config % #resetCaller) - when (resetCaller) $ assign (#config % #overrideCaller) Nothing + assign #overrideCaller Nothing touchAccount self touchAccount callee _ -> @@ -1101,7 +1100,9 @@ callChecks this xGas xContext xTo xValue xInOffset xInSize xOutOffset xOutSize x accessMemoryRange xOutOffset xOutSize $ do availableGas <- use (#state % #gas) let recipientExists = accountExists xContext vm - let from = fromMaybe vm.state.contract vm.config.overrideCaller + let from = fromMaybe vm.state.contract vm.state.overrideCaller + resetCaller <- use $ #state % #resetCaller + when resetCaller $ assign (#state % #overrideCaller) Nothing fromBal <- preuse $ #env % #contracts % ix from % #balance costOfCall fees recipientExists xValue availableGas xGas xTo $ \cost gas' -> do let checkCallDepth = @@ -1145,9 +1146,6 @@ callChecks this xGas xContext xTo xValue xInOffset xInSize xOutOffset xOutSize x partial $ UnexpectedSymbolicArg pc (getOpName state) "Attempting to transfer eth from a symbolic address that is not present in the state" (wrap [from]) GVar _ -> internalError "Unexpected GVar" - - - precompiledContract :: (?op :: Word8, VMOps t) => Contract @@ -1799,8 +1797,9 @@ cheatActions = Map.fromList \sig input -> case decodeStaticArgs 0 1 input of [addr] -> case wordToAddr addr of Just a -> do - assign (#config % #overrideCaller) (Just a) doStop + assign (#state % #overrideCaller) (Just a) + assign (#state % #resetCaller) True Nothing -> vmError (BadCheatCode "prank(address), could not decode address provided" sig) _ -> vmError (BadCheatCode "prank(address) parameter decoding failed" sig) @@ -1808,17 +1807,16 @@ cheatActions = Map.fromList \sig input -> case decodeStaticArgs 0 1 input of [addr] -> case wordToAddr addr of Just a -> do - assign (#config % #overrideCaller) (Just a) - assign (#config % #resetCaller) False doStop + assign (#state % #overrideCaller) (Just a) + assign (#state % #resetCaller) False Nothing -> vmError (BadCheatCode "startPrank(address), could not decode address provided" sig) _ -> vmError (BadCheatCode "startPrank(address) parameter decoding failed" sig) , action "stopPrank()" $ \_ _ -> do - assign (#config % #overrideCaller) Nothing - assign (#config % #resetCaller) True doStop + assign (#state % #overrideCaller) Nothing , action "createFork(string)" $ \sig input -> case decodeBuf [AbiStringType] input of @@ -1993,7 +1991,6 @@ delegateCall this gasGiven xTo xContext xValue xInOffset xInSize xOutOffset xOut pushTrace (FrameTrace newContext) next vm1 <- get - pushTo #frames $ Frame { state = vm1.state { stack = xs } , context = newContext @@ -2014,6 +2011,7 @@ delegateCall this gasGiven xTo xContext xValue xInOffset xInSize xOutOffset xOut assign #memorySize 0 assign #returndata mempty assign #calldata calldata + assign #overrideCaller Nothing continue xTo -- -- * Contract creation diff --git a/src/EVM/Types.hs b/src/EVM/Types.hs index d03f2ee94..90f3426c7 100644 --- a/src/EVM/Types.hs +++ b/src/EVM/Types.hs @@ -665,8 +665,6 @@ data BaseState -- | Configuration options that need to be consulted at runtime data RuntimeConfig = RuntimeConfig { allowFFI :: Bool - , overrideCaller :: Maybe (Expr EAddr) - , resetCaller :: Bool , baseState :: BaseState } deriving (Show) @@ -728,6 +726,8 @@ data FrameState (t :: VMType) s = FrameState , gas :: !(Gas t) , returndata :: Expr Buf , static :: Bool + , overrideCaller :: Maybe (Expr EAddr) + , resetCaller :: Bool } deriving (Generic) diff --git a/test/test.hs b/test/test.hs index b428670cd..7a0c3df8a 100644 --- a/test/test.hs +++ b/test/test.hs @@ -1231,7 +1231,7 @@ tests = testGroup "hevm" Right e <- reachableUserAsserts c (Just $ Sig "f(address,uint256)" [AbiAddressType, AbiUIntType 256]) assertBoolM "The expression is not partial" $ Expr.containsNode isPartial e , - test "vm.prank underflow" $ do + test "vm.prank-underflow" $ do Just c <- solcRuntime "C" [i| interface Vm {