Skip to content

Commit

Permalink
fix(forge): set nonce as corrected before selecting a fork (foundry-r…
Browse files Browse the repository at this point in the history
…s#3225)

* set nonce as corrected

* forge fmt
  • Loading branch information
joshieDo authored and iFrostizz committed Nov 9, 2022
1 parent 3494c8f commit 5a2bf90
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 6 deletions.
14 changes: 12 additions & 2 deletions evm/src/executor/inspector/cheatcodes/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn apply<DB: DatabaseExt>(
create_select_fork(state, data, fork.0.clone(), Some(fork.1.as_u64()))
.map(|id| id.encode().into())
}
HEVMCalls::SelectFork(fork_id) => select_fork(data, fork_id.0),
HEVMCalls::SelectFork(fork_id) => select_fork(state, data, fork_id.0),
HEVMCalls::MakePersistent0(acc) => {
data.db.add_persistent_account(acc.0);
Ok(Default::default())
Expand Down Expand Up @@ -101,7 +101,14 @@ pub fn apply<DB: DatabaseExt>(
}

/// Selects the given fork id
fn select_fork<DB: DatabaseExt>(data: &mut EVMData<DB>, fork_id: U256) -> Result<Bytes, Bytes> {
fn select_fork<DB: DatabaseExt>(
state: &mut Cheatcodes,
data: &mut EVMData<DB>,
fork_id: U256,
) -> Result<Bytes, Bytes> {
// No need to correct since the sender's nonce does not get incremented when selecting a fork.
state.corrected_nonce = true;

data.db
.select_fork(fork_id, data.env, &mut data.journaled_state)
.map(|_| Default::default())
Expand All @@ -115,6 +122,9 @@ fn create_select_fork<DB: DatabaseExt>(
url_or_alias: String,
block: Option<u64>,
) -> Result<U256, Bytes> {
// No need to correct since the sender's nonce does not get incremented when selecting a fork.
state.corrected_nonce = true;

let fork = create_fork_request(state, url_or_alias, block, data)?;
data.db
.create_select_fork(fork, data.env, &mut data.journaled_state)
Expand Down
1 change: 1 addition & 0 deletions forge/tests/it/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ pub fn runner_with_config(mut config: Config) -> MultiContractRunner {

base_runner()
.with_cheats_config(CheatsConfig::new(&config, &EVM_OPTS))
.sender(config.sender)
.build(
&PROJECT.paths.root,
(*COMPILED).clone(),
Expand Down
33 changes: 29 additions & 4 deletions forge/tests/it/repros.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
//! Tests for reproducing issues

use crate::{config::*, test_helpers::filter::Filter};
use ethers::abi::Address;
use foundry_config::Config;
use std::str::FromStr;

/// A macro that tests a single pattern (".*/repros/<issue>")
macro_rules! test_repro {
($issue:expr) => {
test_repro!($issue, false)
test_repro!($issue, false, None)
};
($issue:expr, $should_fail:expr) => {
($issue:expr, $should_fail:expr, $sender:expr) => {
let pattern = concat!(".*repros/", $issue);
let filter = Filter::path(pattern);
let mut config = TestConfig::filter(filter).set_should_fail($should_fail);

let mut config = Config::default();
if let Some(sender) = $sender {
config.sender = sender;
}

let mut config = TestConfig::with_filter(runner_with_config(config), filter)
.set_should_fail($should_fail);
config.run();
};
}

macro_rules! test_repro_fail {
($issue:expr) => {
test_repro!($issue, true)
test_repro!($issue, true, None)
};
}

macro_rules! test_repro_with_sender {
($issue:expr, $sender:expr) => {
test_repro!($issue, false, Some($sender))
};
}

Expand Down Expand Up @@ -103,3 +119,12 @@ fn test_issue_3190() {
fn test_issue_3221() {
test_repro!("Issue3221");
}

// <https://github.com/foundry-rs/foundry/issues/3221>
#[test]
fn test_issue_3223() {
test_repro_with_sender!(
"Issue3223",
Address::from_str("0xF0959944122fb1ed4CfaBA645eA06EED30427BAA").unwrap()
);
}
34 changes: 34 additions & 0 deletions testdata/repros/Issue3223.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

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

// https://github.com/foundry-rs/foundry/issues/3223
contract Issue3223Test is DSTest {
Cheats constant vm = Cheats(HEVM_ADDRESS);
uint256 fork1;
uint256 fork2;

function setUp() public {
fork1 = vm.createFork("https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", 7475589);
fork2 = vm.createFork("https://api.avax-test.network/ext/bc/C/rpc", 12880747);
}

function testForkNonce() public {
address user = address(0xF0959944122fb1ed4CfaBA645eA06EED30427BAA);
assertEq(user, msg.sender);

vm.selectFork(fork2);
assertEq(vm.getNonce(user), 3);
vm.prank(user);
new Counter();

vm.selectFork(fork1);
assertEq(vm.getNonce(user), 3);
vm.prank(user);
new Counter();
}
}

contract Counter {}

0 comments on commit 5a2bf90

Please sign in to comment.