Skip to content

Commit

Permalink
fix(forge) Prefund test/script contracts before deployment (#6300)
Browse files Browse the repository at this point in the history
* Add test

* Prefund script/test contracts before construction

* Use correct sender for scripts

* ref -> basic_ref

---------

Co-authored-by: evalir <hi@enriqueortiz.dev>
  • Loading branch information
klkvr and Evalir authored Dec 7, 2023
1 parent 54b3695 commit 8a31bf1
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 15 deletions.
5 changes: 5 additions & 0 deletions crates/evm/evm/src/executors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ impl Executor {
Ok(self)
}

/// Gets the nonce of an account
pub fn get_nonce(&self, address: Address) -> DatabaseResult<u64> {
Ok(self.backend.basic_ref(address)?.map(|acc| acc.nonce).unwrap_or_default())
}

#[inline]
pub fn set_tracing(&mut self, tracing: bool) -> &mut Self {
self.inspector.tracing(tracing);
Expand Down
8 changes: 7 additions & 1 deletion crates/forge/bin/cmd/script/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ impl ScriptRunner {
.map(|traces| (TraceKind::Deployment, traces))
.collect();

let sender_nonce = self.executor.get_nonce(CALLER)?;
let address = CALLER.create(sender_nonce);

// Set the contracts initial balance before deployment, so it is available during the
// construction
self.executor.set_balance(address, self.initial_balance)?;

// Deploy an instance of the contract
let DeployResult {
address,
Expand All @@ -83,7 +90,6 @@ impl ScriptRunner {
.map_err(|err| eyre::eyre!("Failed to deploy script:\n{}", err))?;

traces.extend(constructor_traces.map(|traces| (TraceKind::Deployment, traces)));
self.executor.set_balance(address, self.initial_balance)?;

// Optionally call the `setUp` function
let (success, gas_used, labeled_addresses, transactions, debug, script_wallets) = if !setup
Expand Down
32 changes: 18 additions & 14 deletions crates/forge/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,22 +115,26 @@ impl<'a> ContractRunner<'a> {
}
}

// Deploy the test contract
let address =
match self.executor.deploy(self.sender, self.code.clone(), U256::ZERO, self.errors) {
Ok(d) => {
logs.extend(d.logs);
traces.extend(d.traces.map(|traces| (TraceKind::Deployment, traces)));
d.address
}
Err(e) => {
return Ok(TestSetup::from_evm_error_with(e, logs, traces, Default::default()))
}
};
let sender_nonce = self.executor.get_nonce(self.sender)?;
let address = self.sender.create(sender_nonce);

// Now we set the contracts initial balance, and we also reset `self.sender`s and `CALLER`s
// balance to the initial balance we want
// Set the contracts initial balance before deployment, so it is available during
// construction
self.executor.set_balance(address, self.initial_balance)?;

// Deploy the test contract
match self.executor.deploy(self.sender, self.code.clone(), U256::ZERO, self.errors) {
Ok(d) => {
logs.extend(d.logs);
traces.extend(d.traces.map(|traces| (TraceKind::Deployment, traces)));
d.address
}
Err(e) => {
return Ok(TestSetup::from_evm_error_with(e, logs, traces, Default::default()))
}
};

// Reset `self.sender`s and `CALLER`s balance to the initial balance we want
self.executor.set_balance(self.sender, self.initial_balance)?;
self.executor.set_balance(CALLER, self.initial_balance)?;

Expand Down
3 changes: 3 additions & 0 deletions crates/forge/tests/it/repros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ test_repro!(6170, false, None, |res| {
assert_eq!(test.reason, Some("log != expected log".to_string()));
});

// <https://github.com/foundry-rs/foundry/issues/6293>
test_repro!(6293);

// https://github.com/foundry-rs/foundry/issues/6180
test_repro!(6180);

Expand Down
19 changes: 19 additions & 0 deletions testdata/repros/Issue6293.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: Unlicense
pragma solidity 0.8.18;

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

// https://github.com/foundry-rs/foundry/issues/6293
contract Issue6293Test is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);

constructor() {
require(address(this).balance > 0);
payable(address(1)).call{value: 1}("");
}

function test() public {
assertGt(address(this).balance, 0);
}
}

0 comments on commit 8a31bf1

Please sign in to comment.