diff --git a/crates/revive-strategy/src/cheatcodes/mod.rs b/crates/revive-strategy/src/cheatcodes/mod.rs index 274ae7f072935..7b08fd80ef3d0 100644 --- a/crates/revive-strategy/src/cheatcodes/mod.rs +++ b/crates/revive-strategy/src/cheatcodes/mod.rs @@ -447,8 +447,15 @@ impl CheatcodeInspectorStrategyRunner for PvmCheatcodeInspectorStrategyRunner { return Err(precompile_error(target)); } + let target_balance = ccx + .ecx + .journaled_state + .load_account(*target) + .map(|acc| acc.info.balance) + .unwrap_or_default(); + let ctx = get_context_ref_mut(ccx.state.strategy.context.as_mut()); - ctx.externalities.etch_call(target, newRuntimeBytecode)?; + ctx.externalities.etch_call(target, newRuntimeBytecode, target_balance)?; cheatcode.dyn_apply(ccx, executor) } diff --git a/crates/revive-strategy/src/state.rs b/crates/revive-strategy/src/state.rs index f731adfaa42bb..7574964eff523 100644 --- a/crates/revive-strategy/src/state.rs +++ b/crates/revive-strategy/src/state.rs @@ -146,7 +146,18 @@ impl TestEnv { }); } - pub fn etch_call(&mut self, target: &Address, new_runtime_code: &Bytes) -> Result { + pub fn etch_call( + &mut self, + target: &Address, + new_runtime_code: &Bytes, + target_balance: U256, + ) -> Result { + let balance_to_set = if target_balance.is_zero() { + sp_core::U256::from(u128::MAX) + } else { + sp_core::U256::from_little_endian(&target_balance.as_le_bytes()).min(u128::MAX.into()) + }; + self.0.lock().unwrap().externalities.execute_with(|| { let target_address = H160::from_slice(target.as_slice()); let target_account = @@ -192,6 +203,10 @@ impl TestEnv { &H160::from_slice(target.as_slice()), contract_info, ); + + Pallet::::set_evm_balance(&target_address, balance_to_set) + .expect("failed to fund etched contract"); + Ok::<(), Error>(()) })?; Ok(Default::default()) diff --git a/testdata/default/revive/EtchTest.t.sol b/testdata/default/revive/EtchTest.t.sol index 691146fb6d0ee..fc37f2a8b21a5 100644 --- a/testdata/default/revive/EtchTest.t.sol +++ b/testdata/default/revive/EtchTest.t.sol @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + import "ds-test/test.sol"; import "cheats/Vm.sol"; import "../../default/logs/console.sol"; @@ -8,6 +11,14 @@ contract Adder { } } +contract StorageWriter { + uint256 public value; + + function setValue(uint256 _value) public { + value = _value; + } +} + contract NestedAdder { uint256 public inner_a; uint256 public inner_b; @@ -125,4 +136,12 @@ contract EtchTest is DSTest { uint256 nested_call_result2 = (new NestedAdder(1, 2)).nested_call(address(target2)); assertEq(nested_call_result2, 3); } + + function testEtchContractCanWriteStorage() public { + bytes memory writerCode = vm.getDeployedCode("revive/EtchTest.t.sol:StorageWriter"); + address target = address(0xBEEF); + vm.etch(target, writerCode); + StorageWriter(target).setValue(42); + assertEq(StorageWriter(target).value(), 42); + } }