Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/abi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ Additional bindings can be generated by doing the following:
2. update the [build script](./build.rs)'s `MultiAbigen::new` call;
3. build the crate once with `cargo build -p foundry-abi`, generating the bindings for the first time;
4. export the newly-generated bindings at the root of the crate, in [`lib.rs`](./src/lib.rs).

New cheatcodes can be added by doing the following:

1. add its Solidity definition(s) in [`HEVM.sol`](./abi/HEVM.sol), bindings should regenerate automatically;
2. implement it in [`foundry-evm`](../evm/src/executor/inspector/cheatcodes/);
3. update the [`Vm.sol`](../../testdata/cheats/Vm.sol) test interface;
4. add tests in [`testdata`](../../testdata/cheats/);
5. open a PR to [`forge-std`](https://github.com/foundry-rs/forge-std) to add it to the `Vm` interface.
5 changes: 3 additions & 2 deletions crates/abi/abi/HEVM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,14 @@ startBroadcast(uint256)
stopBroadcast()

projectRoot()(string)
openFile(string)
readFile(string)(string)
readFileBinary(string)(bytes)
readLine(string)(string)
writeFile(string,string)
writeFileBinary(string,bytes)
openFile(string)
readLine(string)(string)
writeLine(string,string)
copyFile(string,string)
closeFile(string)
removeFile(string)
createDir(string, bool)
Expand Down
58 changes: 58 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.

39 changes: 14 additions & 25 deletions crates/cli/src/forge/cmd/script/multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use ethers::{
signers::LocalWallet,
};
use eyre::{ContextCompat, WrapErr};
use foundry_cli::utils::now;
use foundry_common::{fs, get_http_provider};
use foundry_config::Config;
use futures::future::join_all;
use serde::{Deserialize, Serialize};
use std::{
io::BufWriter,
io::{BufWriter, Write},
path::{Path, PathBuf},
sync::Arc,
time::{SystemTime, UNIX_EPOCH},
};
use tracing::log::trace;

Expand All @@ -31,11 +31,8 @@ pub struct MultiChainSequence {

impl Drop for MultiChainSequence {
fn drop(&mut self) {
self.deployments.iter_mut().for_each(|sequence| {
sequence.sort_receipts();
});

self.save().expect("not able to save multi deployment sequence");
self.deployments.iter_mut().for_each(|sequence| sequence.sort_receipts());
self.save().expect("could not save multi deployment sequence");
}
}

Expand All @@ -50,14 +47,7 @@ impl MultiChainSequence {
let path =
MultiChainSequence::get_path(&log_folder.join("multi"), sig, target, broadcasted)?;

Ok(MultiChainSequence {
deployments,
path,
timestamp: SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Wrong system time.")
.as_secs(),
})
Ok(MultiChainSequence { deployments, path, timestamp: now().as_secs() })
}

/// Saves to ./broadcast/multi/contract_filename[-timestamp]/sig.json
Expand Down Expand Up @@ -85,8 +75,7 @@ impl MultiChainSequence {
let filename = sig
.split_once('(')
.wrap_err_with(|| format!("Failed to compute file name: Signature {sig} is invalid."))?
.0
.to_string();
.0;
out.push(format!("{filename}.json"));

Ok(out)
Expand All @@ -100,20 +89,20 @@ impl MultiChainSequence {

/// Saves the transactions as file if it's a standalone deployment.
pub fn save(&mut self) -> eyre::Result<()> {
self.timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
let path = self.path.to_string_lossy();
self.timestamp = now().as_secs();

//../Contract-latest/run.json
serde_json::to_writer_pretty(BufWriter::new(fs::create_file(&self.path)?), &self)?;
let mut writer = BufWriter::new(fs::create_file(&self.path)?);
serde_json::to_writer_pretty(&mut writer, &self)?;
writer.flush()?;

//../Contract-[timestamp]/run.json
let path = self.path.to_string_lossy();
let file = PathBuf::from(&path.replace("-latest", &format!("-{}", self.timestamp)));
fs::create_dir_all(file.parent().unwrap())?;
fs::copy(&self.path, &file)?;

fs::create_dir_all(file.parent().expect("to have a file."))?;

serde_json::to_writer_pretty(BufWriter::new(fs::create_file(file)?), &self)?;

println!("\nTransactions saved to: {path}\n");
println!("\nTransactions saved to: {}\n", self.path.display());

Ok(())
}
Expand Down
70 changes: 29 additions & 41 deletions crates/cli/src/forge/cmd/script/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ use ethers::{
types::transaction::eip2718::TypedTransaction,
};
use eyre::{ContextCompat, WrapErr};
use foundry_cli::utils::now;
use foundry_common::{fs, shell, SELECTOR_LEN};
use foundry_config::Config;
use serde::{Deserialize, Serialize};
use std::{
collections::{HashMap, VecDeque},
io::BufWriter,
io::{BufWriter, Write},
path::{Path, PathBuf},
time::{SystemTime, UNIX_EPOCH},
};
use tracing::trace;
use yansi::Paint;
Expand Down Expand Up @@ -102,10 +102,7 @@ impl ScriptSequence {
pending: vec![],
path,
sensitive_path,
timestamp: SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Wrong system time.")
.as_secs(),
timestamp: now().as_secs(),
libraries: vec![],
chain,
multi: is_multi,
Expand Down Expand Up @@ -152,43 +149,34 @@ impl ScriptSequence {

/// Saves the transactions as file if it's a standalone deployment.
pub fn save(&mut self) -> eyre::Result<()> {
if !self.multi && !self.transactions.is_empty() {
self.timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

let sensitive_script_sequence: SensitiveScriptSequence = self.into();

let path = self.path.to_string_lossy();
let sensitive_path = self.sensitive_path.to_string_lossy();

// broadcast folder writes
//../run-latest.json
serde_json::to_writer_pretty(BufWriter::new(fs::create_file(&self.path)?), &self)?;
//../run-[timestamp].json
serde_json::to_writer_pretty(
BufWriter::new(fs::create_file(
path.replace("latest.json", &format!("{}.json", self.timestamp)),
)?),
&self,
)?;

// cache folder writes
//../run-latest.json
serde_json::to_writer_pretty(
BufWriter::new(fs::create_file(&self.sensitive_path)?),
&sensitive_script_sequence,
)?;
//../run-[timestamp].json
serde_json::to_writer_pretty(
BufWriter::new(fs::create_file(
sensitive_path.replace("latest.json", &format!("{}.json", self.timestamp)),
)?),
&sensitive_script_sequence,
)?;

shell::println(format!("\nTransactions saved to: {path}\n"))?;
shell::println(format!("Sensitive values saved to: {sensitive_path}\n"))?;
if self.multi || self.transactions.is_empty() {
return Ok(())
}

self.timestamp = now().as_secs();
let ts_name = format!("run-{}.json", self.timestamp);

let sensitive_script_sequence: SensitiveScriptSequence = self.into();

// broadcast folder writes
//../run-latest.json
let mut writer = BufWriter::new(fs::create_file(&self.path)?);
serde_json::to_writer_pretty(&mut writer, &self)?;
writer.flush()?;
//../run-[timestamp].json
fs::copy(&self.path, self.path.with_file_name(&ts_name))?;

// cache folder writes
//../run-latest.json
let mut writer = BufWriter::new(fs::create_file(&self.sensitive_path)?);
serde_json::to_writer_pretty(&mut writer, &sensitive_script_sequence)?;
writer.flush()?;
//../run-[timestamp].json
fs::copy(&self.sensitive_path, self.sensitive_path.with_file_name(&ts_name))?;

shell::println(format!("\nTransactions saved to: {}\n", self.path.display()))?;
shell::println(format!("Sensitive values saved to: {}\n", self.sensitive_path.display()))?;

Ok(())
}

Expand Down
7 changes: 6 additions & 1 deletion crates/cli/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::{
path::{Path, PathBuf},
process::{Command, Output, Stdio},
str::FromStr,
time::Duration,
time::{Duration, SystemTime, UNIX_EPOCH},
};
use tracing_error::ErrorLayer;
use tracing_subscriber::prelude::*;
Expand Down Expand Up @@ -153,6 +153,11 @@ pub fn parse_delay(delay: &str) -> Result<Duration> {
Ok(delay)
}

/// Returns the current time as a [`Duration`] since the Unix epoch.
pub fn now() -> Duration {
SystemTime::now().duration_since(UNIX_EPOCH).expect("time went backwards")
}

/// Runs the `future` in a new [`tokio::runtime::Runtime`]
#[allow(unused)]
pub fn block_on<F: Future>(future: F) -> F::Output {
Expand Down
Loading