Skip to content

Commit

Permalink
feat: cool cheatcode (foundry-rs#5830)
Browse files Browse the repository at this point in the history
* feat: `cool` cheatcode

* refactor: extract to a function, remove check
  • Loading branch information
ditto-eth authored Sep 14, 2023
1 parent a804703 commit ae89c92
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/abi/abi/HEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fee(uint256)
coinbase(address)
store(address,bytes32,bytes32)
load(address,bytes32)(bytes32)
cool(address)

setEnv(string,string)
envBool(string)(bool)
Expand Down
53 changes: 53 additions & 0 deletions crates/abi/src/bindings/hevm.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions crates/evm/src/executor/inspector/cheatcodes/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,18 @@ fn add_breakpoint(state: &mut Cheatcodes, caller: Address, inner: &str, add: boo
Ok(Bytes::new())
}

// mark the slots of an account and the account address as cold
fn cool_account<DB: DatabaseExt>(data: &mut EVMData<'_, DB>, address: Address) -> Result {
if let Some(account) = data.journaled_state.state.get_mut(&h160_to_b160(address)) {
if account.is_touched() {
account.unmark_touch();
}
account.storage.clear();
}

Ok(Bytes::new())
}

#[instrument(level = "error", name = "env", target = "evm::cheatcodes", skip_all)]
pub fn apply<DB: DatabaseExt>(
state: &mut Cheatcodes,
Expand Down Expand Up @@ -387,6 +399,7 @@ pub fn apply<DB: DatabaseExt>(
)?;
ru256_to_u256(val).encode().into()
}
HEVMCalls::Cool(inner) => cool_account(data, inner.0)?,
HEVMCalls::Breakpoint0(inner) => add_breakpoint(state, caller, &inner.0, true)?,
HEVMCalls::Breakpoint1(inner) => add_breakpoint(state, caller, &inner.0, inner.1)?,
HEVMCalls::Etch(inner) => {
Expand Down
60 changes: 60 additions & 0 deletions testdata/cheats/Cool.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: Unlicense
pragma solidity 0.8.18;

import "../lib/ds-test/src/test.sol";
import "./Vm.sol";

contract CoolTest is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);
uint256 public slot0 = 1;

function testCool_SLOAD_normal() public {
uint256 startGas;
uint256 endGas;
uint256 val;
uint256 beforeCoolGas;
uint256 noCoolGas;

startGas = gasleft();
val = slot0;
endGas = gasleft();
beforeCoolGas = startGas - endGas;

startGas = gasleft();
val = slot0;
endGas = gasleft();
noCoolGas = startGas - endGas;

assertGt(beforeCoolGas, noCoolGas);
}

function testCool_SLOAD() public {
uint256 startGas;
uint256 endGas;
uint256 val;
uint256 beforeCoolGas;
uint256 afterCoolGas;
uint256 noCoolGas;

startGas = gasleft();
val = slot0;
endGas = gasleft();
beforeCoolGas = startGas - endGas;

vm.cool(address(this));

startGas = gasleft();
val = slot0;
endGas = gasleft();
afterCoolGas = startGas - endGas;

assertEq(beforeCoolGas, afterCoolGas);

startGas = gasleft();
val = slot0;
endGas = gasleft();
noCoolGas = startGas - endGas;

assertGt(beforeCoolGas, noCoolGas);
}
}
3 changes: 3 additions & 0 deletions testdata/cheats/Vm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ interface Vm {
// Stores a value to an address' storage slot, (who, slot, value)
function store(address, bytes32, bytes32) external;

// Cools off a warm address and its storage slots
function cool(address) external;

// Signs data, (privateKey, digest) => (v, r, s)
function sign(uint256, bytes32) external returns (uint8, bytes32, bytes32);

Expand Down

0 comments on commit ae89c92

Please sign in to comment.