Skip to content

Commit

Permalink
feat(forge): blobbasefee cheatcode (#7598)
Browse files Browse the repository at this point in the history
* feat(forge): blobbasefee cheatcode

* updated comments

* nits

* moved test

* chore: add cancun test

---------

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
  • Loading branch information
kamuik16 and mattsse authored Apr 10, 2024
1 parent 4603195 commit f0ea57a
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 7 deletions.
40 changes: 40 additions & 0 deletions crates/cheatcodes/assets/cheatcodes.json

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

11 changes: 11 additions & 0 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,17 @@ interface Vm {
#[cheatcode(group = Evm, safety = Safe)]
function getBlockTimestamp() external view returns (uint256 timestamp);

/// Sets `block.blobbasefee`
#[cheatcode(group = Evm, safety = Unsafe)]
function blobBaseFee(uint256 newBlobBaseFee) external;

/// Gets the current `block.blobbasefee`.
/// You should use this instead of `block.blobbasefee` if you use `vm.blobBaseFee`, as `block.blobbasefee` is assumed to be constant across a transaction,
/// and as a result will get optimized out by the compiler.
/// See https://github.com/foundry-rs/foundry/issues/6180
#[cheatcode(group = Evm, safety = Safe)]
function getBlobBaseFee() external view returns (uint256 blobBaseFee);

// -------- Account State --------

/// Sets an address' balance.
Expand Down
20 changes: 20 additions & 0 deletions crates/cheatcodes/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,26 @@ impl Cheatcode for getBlockTimestampCall {
}
}

impl Cheatcode for blobBaseFeeCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newBlobBaseFee } = self;
ensure!(
ccx.ecx.spec_id() >= SpecId::CANCUN,
"`blobBaseFee` is not supported before the Cancun hard fork; \
see EIP-4844: https://eips.ethereum.org/EIPS/eip-4844"
);
ccx.ecx.env.block.set_blob_excess_gas_and_price((*newBlobBaseFee).to());
Ok(Default::default())
}
}

impl Cheatcode for getBlobBaseFeeCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.ecx.env.block.get_blob_excess_gas().unwrap_or(0).abi_encode())
}
}

impl Cheatcode for dealCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { account: address, newBalance: new_balance } = *self;
Expand Down
10 changes: 9 additions & 1 deletion crates/forge/tests/it/cheats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

use crate::{
config::*,
test_helpers::{ForgeTestData, RE_PATH_SEPARATOR, TEST_DATA_DEFAULT, TEST_DATA_MULTI_VERSION},
test_helpers::{
ForgeTestData, RE_PATH_SEPARATOR, TEST_DATA_CANCUN, TEST_DATA_DEFAULT,
TEST_DATA_MULTI_VERSION,
},
};
use foundry_config::{fs_permissions::PathPermission, FsPermissions};
use foundry_test_utils::Filter;
Expand Down Expand Up @@ -50,3 +53,8 @@ async fn test_cheats_local_default_isolated() {
async fn test_cheats_local_multi_version() {
test_cheats_local(&TEST_DATA_MULTI_VERSION).await
}

#[tokio::test(flavor = "multi_thread")]
async fn test_cheats_local_cancun() {
test_cheats_local(&TEST_DATA_CANCUN).await
}
23 changes: 17 additions & 6 deletions crates/forge/tests/it/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use alloy_primitives::U256;
use forge::{
inspectors::CheatsConfig, MultiContractRunner, MultiContractRunnerBuilder, TestOptions,
TestOptionsBuilder,
inspectors::CheatsConfig, revm::primitives::SpecId, MultiContractRunner,
MultiContractRunnerBuilder, TestOptions, TestOptionsBuilder,
};
use foundry_compilers::{
artifacts::{Libraries, Settings},
Expand Down Expand Up @@ -46,6 +46,11 @@ impl fmt::Display for ForgeTestProfile {
}

impl ForgeTestProfile {
/// Returns true if the profile is Cancun.
pub fn is_cancun(&self) -> bool {
matches!(self, Self::Cancun)
}

pub fn root(&self) -> PathBuf {
PathBuf::from(TESTDATA)
}
Expand Down Expand Up @@ -147,7 +152,7 @@ impl ForgeTestProfile {
"fork/Fork.t.sol:DssExecLib:0xfD88CeE74f7D78697775aBDAE53f9Da1559728E4".to_string(),
];

if matches!(self, Self::Cancun) {
if self.is_cancun() {
config.evm_version = EvmVersion::Cancun;
}

Expand All @@ -162,6 +167,7 @@ pub struct ForgeTestData {
pub test_opts: TestOptions,
pub evm_opts: EvmOpts,
pub config: Config,
pub profile: ForgeTestProfile,
}

impl ForgeTestData {
Expand All @@ -175,15 +181,20 @@ impl ForgeTestData {
let config = profile.config();
let evm_opts = profile.evm_opts();

Self { project, output, test_opts, evm_opts, config }
Self { project, output, test_opts, evm_opts, config, profile }
}

/// Builds a base runner
pub fn base_runner(&self) -> MultiContractRunnerBuilder {
init_tracing();
MultiContractRunnerBuilder::default()
let mut runner = MultiContractRunnerBuilder::default()
.sender(self.evm_opts.sender)
.with_test_options(self.test_opts.clone())
.with_test_options(self.test_opts.clone());
if self.profile.is_cancun() {
runner = runner.evm_spec(SpecId::CANCUN);
}

runner
}

/// Builds a non-tracing runner
Expand Down
14 changes: 14 additions & 0 deletions testdata/cancun/cheats/BlobBaseFee.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.25;

import "ds-test/test.sol";
import "cheats/Vm.sol";

contract BlobBaseFeeTest is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);

function test_blob_base_fee() public {
vm.blobBaseFee(6969);
assertEq(vm.getBlobBaseFee(), 6969);
}
}
2 changes: 2 additions & 0 deletions testdata/cheats/Vm.sol

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

0 comments on commit f0ea57a

Please sign in to comment.