Skip to content
Closed
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
3 changes: 2 additions & 1 deletion cli/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use std::{
use clap::{IntoApp, Parser};
use clap_complete::generate;

use crate::utils::read_secret;
use crate::{cmd::Cmd, utils::read_secret};
use eyre::WrapErr;
use futures::join;

Expand Down Expand Up @@ -307,6 +307,7 @@ async fn main() -> eyre::Result<()> {
eyre::bail!("No wallet or sender address provided.")
}
}
Subcommands::Run(cmd) => cmd.run()?,
Subcommands::PublishTx { eth, raw_tx, cast_async } => {
let provider = Provider::try_from(eth.rpc_url()?)?;
let cast = Cast::new(&provider);
Expand Down
40 changes: 40 additions & 0 deletions cli/src/cmd/cast/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//! Subcommands for cast
//!
//! All subcommands should respect the `foundry_config::Config`.
//! If a subcommand accepts values that are supported by the `Config`, then the subcommand should
//! implement `figment::Provider` which allows the subcommand to override the config's defaults, see
//! [`foundry_config::Config`].
//!
//! See [`BuildArgs`] for a reference implementation.
//! And [`RunArgs`] for how to merge `Providers`.
//!
//! # Example
//!
//! create a `clap` subcommand into a `figment::Provider` and integrate it in the
//! `foundry_config::Config`:
//!
//! ```rust
//! use crate::{cmd::build::BuildArgs, opts::evm::EvmArgs};
//! use clap::Parser;
//! use foundry_config::{figment::Figment, *};
//!
//! // A new clap subcommand that accepts both `EvmArgs` and `BuildArgs`
//! #[derive(Debug, Clone, Parser)]
//! pub struct MyArgs {
//! #[clap(flatten)]
//! evm_opts: EvmArgs,
//! #[clap(flatten)]
//! opts: BuildArgs,
//! }
//!
//! // add `Figment` and `Config` converters
//! foundry_config::impl_figment_convert!(MyArgs, opts, evm_opts);
//! let args = MyArgs::parse_from(["build"]);
//!
//! let figment: Figment = From::from(&args);
//! let evm_opts = figment.extract::<EvmOpts>().unwrap();
//!
//! let config: Config = From::from(&args);
//! ```

pub mod run;
103 changes: 103 additions & 0 deletions cli/src/cmd/cast/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use crate::cmd::{forge::build::BuildArgs, Cmd};
use clap::Parser;

use forge::ContractRunner;
use foundry_utils::IntoFunction;

use ethers::types::{Address, Bytes, U256};
use sputnik::ExitReason;

use crate::opts::evm::EvmArgs;
use ansi_term::Colour;
use evm_adapters::{
evm_opts::{BackendKind, EvmOpts},
sputnik::helpers::vm,
Evm,
};
use foundry_config::{figment::Figment, Config};

// Loads project's figment and merges the build cli arguments into it
foundry_config::impl_figment_convert!(RunArgs, opts, evm_opts);

#[derive(Debug, Clone, Parser)]
pub struct RunArgs {
#[clap(help = "the bytecode to execute")]
pub bytecode: String,

#[clap(flatten)]
pub evm_opts: EvmArgs,

#[clap(flatten)]
opts: BuildArgs,
}

impl Cmd for RunArgs {
type Output = ();

fn run(self) -> eyre::Result<Self::Output> {
// Keeping it like this for simplicity.
#[cfg(not(feature = "sputnik-evm"))]
unimplemented!("`exec` does not work with EVMs other than Sputnik yet");

let figment: Figment = From::from(&self);
let mut evm_opts = figment.extract::<EvmOpts>()?;
let config = Config::from_provider(figment).sanitized();
let evm_version = config.evm_version;
if evm_opts.debug {
evm_opts.verbosity = 3;
}

let mut cfg = crate::utils::sputnik_cfg(&evm_version);
cfg.create_contract_limit = None;
let vicinity = evm_opts.vicinity()?;
let backend = evm_opts.backend(&vicinity)?;

// Parse bytecode string
let bytecode_vec = self.bytecode.strip_prefix("0x").unwrap_or(&self.bytecode);
let parsed_bytecode = Bytes::from(hex::decode(bytecode_vec)?);

// Create the evm executor
let mut evm = vm();

// Deploy our bytecode
let custVal = U256::from(0);
let (addr, _, _, _) = evm.deploy(Address::zero(), parsed_bytecode, custVal).unwrap();

// Configure EVM
evm.gas_limit = u64::MAX;

// TODO: support arbitrary input
// let sig = ethers::utils::id("foo()").to_vec();

// Call the address with an empty input
let (retBytes, retReason, retU64, retVecStr) =
evm.call_raw(Address::zero(), addr, Default::default(), custVal, true)?;

// Match on the return exit reason
match retReason {
ExitReason::Succeed(s) => {
println!("{}", Colour::Green.paint(format!("SUCCESS [{:?}]", s)));
println!("");
println!("==== Execution Return Bytes ====");
println!("{}", retBytes);
}
ExitReason::Error(e) => {
println!("{}", Colour::Red.paint(format!("ERROR [{:?}]", e)));
}
ExitReason::Revert(r) => {
println!("{}", Colour::Yellow.paint(format!("REVERT [{:?}]", r)));
}
ExitReason::Fatal(f) => {
println!("{}", Colour::Red.paint(format!("FATAL [{:?}]", f)));
}
}

Ok(())
}
}

impl RunArgs {
pub fn build(&self, _: Config, _: &EvmOpts) -> eyre::Result<()> {
Ok(())
}
}
File renamed without changes.
6 changes: 3 additions & 3 deletions cli/src/cmd/build.rs → cli/src/cmd/forge/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::path::PathBuf;

use crate::{cmd::Cmd, opts::forge::CompilerArgs};

use crate::cmd::watch::WatchArgs;
use crate::cmd::forge::watch::WatchArgs;
use clap::{Parser, ValueHint};
use ethers::solc::remappings::Remapping;
use foundry_config::{
Expand Down Expand Up @@ -184,7 +184,7 @@ impl Cmd for BuildArgs {
type Output = ProjectCompileOutput;
fn run(self) -> eyre::Result<Self::Output> {
let project = self.project()?;
super::compile(&project, self.names, self.sizes)
crate::cmd::compile(&project, self.names, self.sizes)
}
}

Expand All @@ -207,7 +207,7 @@ impl BuildArgs {
/// Returns the [`watchexec::InitConfig`] and [`watchexec::RuntimeConfig`] necessary to
/// bootstrap a new [`watchexe::Watchexec`] loop.
pub(crate) fn watchexec_config(&self) -> eyre::Result<(InitConfig, RuntimeConfig)> {
use crate::cmd::watch;
use crate::cmd::forge::watch;
let init = watch::init()?;
let mut runtime = watch::runtime(&self.watch)?;

Expand Down
2 changes: 1 addition & 1 deletion cli/src/cmd/config.rs → cli/src/cmd/forge/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! config command

use crate::{
cmd::{build::BuildArgs, Cmd},
cmd::{forge::build::BuildArgs, Cmd},
opts::evm::EvmArgs,
};
use clap::Parser;
Expand Down
6 changes: 3 additions & 3 deletions cli/src/cmd/create.rs → cli/src/cmd/forge/create.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Create command

use crate::{
cmd::{build::BuildArgs, Cmd},
cmd::{forge::build::BuildArgs, Cmd},
opts::{EthereumOpts, WalletType},
utils::parse_u256,
};
Expand Down Expand Up @@ -70,10 +70,10 @@ impl Cmd for CreateArgs {
fn run(self) -> Result<Self::Output> {
// Find Project & Compile
let project = self.opts.project()?;
let compiled = super::compile(&project, self.opts.names, self.opts.sizes)?;
let compiled = crate::cmd::compile(&project, self.opts.names, self.opts.sizes)?;

// Get ABI and BIN
let (abi, bin, _) = super::read_artifact(&project, compiled, self.contract.clone())?;
let (abi, bin, _) = crate::cmd::read_artifact(&project, compiled, self.contract.clone())?;

let bin = match bin.object {
BytecodeObject::Bytecode(_) => bin.object,
Expand Down
2 changes: 1 addition & 1 deletion cli/src/cmd/flatten.rs → cli/src/cmd/forge/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::path::PathBuf;

use ethers::solc::remappings::Remapping;

use crate::cmd::{build::BuildArgs, Cmd};
use crate::cmd::{forge::build::BuildArgs, Cmd};
use clap::{Parser, ValueHint};
use foundry_config::Config;

Expand Down
File renamed without changes.
13 changes: 8 additions & 5 deletions cli/src/cmd/init.rs → cli/src/cmd/forge/init.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! init command

use crate::{
cmd::{install::install, Cmd},
cmd::{forge::install::install, Cmd},
opts::forge::Dependency,
utils::p_println,
};
use clap::{Parser, ValueHint};
use foundry_config::Config;

use crate::cmd::{install::DependencyInstallOpts, remappings};
use crate::cmd::forge::{install::DependencyInstallOpts, remappings};
use ansi_term::Colour;
use ethers::solc::remappings::Remapping;
use std::{
Expand Down Expand Up @@ -102,10 +102,13 @@ impl Cmd for InitArgs {

// write the contract file
let contract_path = src.join("Contract.sol");
std::fs::write(contract_path, include_str!("../../../assets/ContractTemplate.sol"))?;
std::fs::write(contract_path, include_str!("../../../../assets/ContractTemplate.sol"))?;
// write the tests
let contract_path = test.join("Contract.t.sol");
std::fs::write(contract_path, include_str!("../../../assets/ContractTemplate.t.sol"))?;
std::fs::write(
contract_path,
include_str!("../../../../assets/ContractTemplate.t.sol"),
)?;

let dest = root.join(Config::FILE_NAME);
if !dest.exists() {
Expand Down Expand Up @@ -159,7 +162,7 @@ fn init_git_repo(root: &Path, no_commit: bool) -> eyre::Result<()> {

if !is_git.success() {
let gitignore_path = root.join(".gitignore");
std::fs::write(gitignore_path, include_str!("../../../assets/.gitignoreTemplate"))?;
std::fs::write(gitignore_path, include_str!("../../../../assets/.gitignoreTemplate"))?;

Command::new("git")
.arg("init")
Expand Down
4 changes: 2 additions & 2 deletions cli/src/cmd/inspect.rs → cli/src/cmd/forge/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{fmt, str::FromStr};

use crate::{
cmd::{
build::{self, BuildArgs},
forge::build::{self, BuildArgs},
Cmd,
},
opts::forge::CompilerArgs,
Expand Down Expand Up @@ -156,7 +156,7 @@ impl Cmd for InspectArgs {

// Build the project
let project = modified_build_args.project()?;
let outcome = super::suppress_compile(&project)?;
let outcome = crate::cmd::suppress_compile(&project)?;

// Find the artifact
let found_artifact = outcome.find(&contract);
Expand Down
File renamed without changes.
55 changes: 55 additions & 0 deletions cli/src/cmd/forge/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Subcommands for forge
//!
//! All subcommands should respect the `foundry_config::Config`.
//! If a subcommand accepts values that are supported by the `Config`, then the subcommand should
//! implement `figment::Provider` which allows the subcommand to override the config's defaults, see
//! [`foundry_config::Config`].
//!
//! See [`BuildArgs`] for a reference implementation.
//! And [`RunArgs`] for how to merge `Providers`.
//!
//! # Example
//!
//! create a `clap` subcommand into a `figment::Provider` and integrate it in the
//! `foundry_config::Config`:
//!
//! ```rust
//! use crate::{cmd::build::BuildArgs, opts::evm::EvmArgs};
//! use clap::Parser;
//! use foundry_config::{figment::Figment, *};
//!
//! // A new clap subcommand that accepts both `EvmArgs` and `BuildArgs`
//! #[derive(Debug, Clone, Parser)]
//! pub struct MyArgs {
//! #[clap(flatten)]
//! evm_opts: EvmArgs,
//! #[clap(flatten)]
//! opts: BuildArgs,
//! }
//!
//! // add `Figment` and `Config` converters
//! foundry_config::impl_figment_convert!(MyArgs, opts, evm_opts);
//! let args = MyArgs::parse_from(["build"]);
//!
//! let figment: Figment = From::from(&args);
//! let evm_opts = figment.extract::<EvmOpts>().unwrap();
//!
//! let config: Config = From::from(&args);
//! ```

pub mod bind;
pub mod build;
pub mod config;
pub mod create;
pub mod flatten;
pub mod fmt;
pub mod init;
pub mod inspect;
pub mod install;
pub mod remappings;
pub mod run;
pub mod snapshot;
pub mod test;
pub mod tree;
pub mod verify;
pub mod watch;
File renamed without changes.
2 changes: 1 addition & 1 deletion cli/src/cmd/run.rs → cli/src/cmd/forge/run.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::cmd::{build::BuildArgs, compile_files, Cmd};
use crate::cmd::{compile_files, forge::build::BuildArgs, Cmd};
use clap::{Parser, ValueHint};
use evm_adapters::sputnik::cheatcodes::{CONSOLE_ABI, HEVMCONSOLE_ABI, HEVM_ABI};

Expand Down
6 changes: 4 additions & 2 deletions cli/src/cmd/snapshot.rs → cli/src/cmd/forge/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

use crate::{
cmd::{
test,
test::{Test, TestOutcome},
forge::{
test,
test::{Test, TestOutcome},
},
Cmd,
},
utils,
Expand Down
4 changes: 2 additions & 2 deletions cli/src/cmd/test.rs → cli/src/cmd/forge/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Test command

use crate::{
cmd::{build::BuildArgs, Cmd},
cmd::{forge::build::BuildArgs, Cmd},
opts::evm::EvmArgs,
};
use ansi_term::Colour;
Expand Down Expand Up @@ -183,7 +183,7 @@ impl Cmd for TestArgs {

// Set up the project
let project = config.project()?;
let output = super::compile(&project, false, false)?;
let output = crate::cmd::compile(&project, false, false)?;

// prepare the test builder
let mut evm_cfg = crate::utils::sputnik_cfg(&config.evm_version);
Expand Down
2 changes: 1 addition & 1 deletion cli/src/cmd/tree.rs → cli/src/cmd/forge/tree.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! tree command

use crate::cmd::{build::BuildArgs, Cmd};
use crate::cmd::{forge::build::BuildArgs, Cmd};
use clap::Parser;
use ethers::solc::Graph;
use foundry_config::Config;
Expand Down
2 changes: 1 addition & 1 deletion cli/src/cmd/verify.rs → cli/src/cmd/forge/verify.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Verify contract source on etherscan

use crate::{
cmd::{build::BuildArgs, flatten::CoreFlattenArgs},
cmd::forge::{build::BuildArgs, flatten::CoreFlattenArgs},
opts::forge::ContractInfo,
};
use clap::Parser;
Expand Down
Loading