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
18 changes: 12 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,22 @@ debug = 0

# Speed up tests and dev build
[profile.dev.package]
# solc
ethers-solc.opt-level = 3
solang-parser.opt-level = 3
serde_json.opt-level = 3

# evm
revm.opt-level = 3
revm-primitives.opt-level = 3
revm-interpreter.opt-level = 3
revm-precompile.opt-level = 3
tiny-keccak.opt-level = 3
sha2.opt-level = 3
sha3.opt-level = 3
keccak.opt-level = 3
ruint.opt-level = 3
primitive-types.opt-level = 3
hashbrown.opt-level = 3

# keystores
scrypt.opt-level = 3
Expand All @@ -48,7 +56,6 @@ codegen-units = 1
# Package overrides
foundry-evm.opt-level = 3

ethers-solc.opt-level = 1
foundry-abi.opt-level = 1
mdbook.opt-level = 1
protobuf.opt-level = 1
Expand Down Expand Up @@ -93,12 +100,11 @@ wasm-bindgen-backend.opt-level = 0

# Local "release" mode, more optimized than dev but much faster to compile than release
[profile.local]
inherits = "release"
inherits = "dev"
opt-level = 1
lto = "none"
strip = true
panic = "abort"
codegen-units = 16
# Empty, clears `profile.release.package`
package = {}

[workspace.dependencies]
anvil = { path = "crates/anvil" }
Expand Down
4 changes: 2 additions & 2 deletions crates/cli/src/utils/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,15 @@ pub async fn handle_traces(
let (sources, bytecode) = etherscan_identifier.get_compiled_contracts().await?;
run_debugger(result, decoder, bytecode, sources)?;
} else {
print_traces(&mut result, decoder, verbose).await?;
print_traces(&mut result, &decoder, verbose).await?;
}

Ok(())
}

pub async fn print_traces(
result: &mut TraceResult,
decoder: CallTraceDecoder,
decoder: &CallTraceDecoder,
verbose: bool,
) -> Result<()> {
if result.traces.is_empty() {
Expand Down
9 changes: 3 additions & 6 deletions crates/evm/src/fuzz/invariant/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,12 @@ impl InvariantFuzzError {
anchor: usize,
removed_calls: &[usize],
) -> Result<Vec<&'a BasicTxDetails>, ()> {
let calls = calls.iter().enumerate().filter_map(|(index, element)| {
let mut new_sequence = Vec::with_capacity(calls.len());
for (index, details) in calls.iter().enumerate() {
if anchor > index || removed_calls.contains(&index) {
return None
continue
}
Some(element)
});

let mut new_sequence = vec![];
for details in calls {
new_sequence.push(details);

let (sender, (addr, bytes)) = details;
Expand Down
8 changes: 4 additions & 4 deletions crates/evm/src/fuzz/invariant/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ impl<'a> InvariantExecutor<'a> {
/// Returns a list of all the consumed gas and calldata of every invariant fuzz case
pub fn invariant_fuzz(
&mut self,
invariant_contract: InvariantContract,
invariant_contract: &InvariantContract,
) -> eyre::Result<InvariantFuzzTestResult> {
let (fuzz_state, targeted_contracts, strat) = self.prepare_fuzzing(&invariant_contract)?;
let (fuzz_state, targeted_contracts, strat) = self.prepare_fuzzing(invariant_contract)?;

// Stores the consumed gas and calldata of every successful fuzz call.
let fuzz_cases: RefCell<Vec<FuzzedCases>> = RefCell::new(Default::default());
Expand All @@ -113,7 +113,7 @@ impl<'a> InvariantExecutor<'a> {

let last_call_results = RefCell::new(
assert_invariants(
&invariant_contract,
invariant_contract,
&blank_executor.borrow(),
&[],
&mut failures.borrow_mut(),
Expand Down Expand Up @@ -199,7 +199,7 @@ impl<'a> InvariantExecutor<'a> {
});

let RichInvariantResults { success: can_continue, call_results } = can_continue(
&invariant_contract,
invariant_contract,
call_result,
&executor,
&inputs,
Expand Down
14 changes: 11 additions & 3 deletions crates/evm/src/trace/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use ethers::{
};
use foundry_common::{abi::get_indexed_event, SELECTOR_LEN};
use hashbrown::HashSet;
use once_cell::sync::OnceCell;
use std::collections::{BTreeMap, HashMap};

/// Build a new [CallTraceDecoder].
Expand All @@ -25,7 +26,7 @@ pub struct CallTraceDecoderBuilder {

impl CallTraceDecoderBuilder {
pub fn new() -> Self {
Self { decoder: CallTraceDecoder::new() }
Self { decoder: CallTraceDecoder::new().clone() }
}

/// Add known labels to the decoder.
Expand Down Expand Up @@ -65,7 +66,7 @@ impl CallTraceDecoderBuilder {
///
/// Note that a call trace decoder is required for each new set of traces, since addresses in
/// different sets might overlap.
#[derive(Default, Debug)]
#[derive(Clone, Default, Debug)]
pub struct CallTraceDecoder {
/// Information for decoding precompile calls.
pub precompiles: HashMap<Address, Function>,
Expand Down Expand Up @@ -115,7 +116,14 @@ impl CallTraceDecoder {
///
/// The call trace decoder always knows how to decode calls to the cheatcode address, as well
/// as DSTest-style logs.
pub fn new() -> Self {
pub fn new() -> &'static Self {
// If you want to take arguments in this function, assign them to the fields of the cloned
// lazy instead of removing it
static INIT: OnceCell<CallTraceDecoder> = OnceCell::new();
INIT.get_or_init(Self::init)
}

fn init() -> Self {
Self {
// TODO: These are the Ethereum precompiles. We should add a way to support precompiles
// for other networks, too.
Expand Down
7 changes: 3 additions & 4 deletions crates/forge/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,14 @@ impl<'a> ContractRunner<'a> {
InvariantContract { address, invariant_functions: functions, abi: self.contract };

let Ok(InvariantFuzzTestResult { invariants, cases, reverts, last_run_inputs }) =
evm.invariant_fuzz(invariant_contract.clone())
evm.invariant_fuzz(&invariant_contract)
else {
return vec![]
};

invariants
.into_values()
.map(|test_error| {
let (test_error, invariant) = test_error;
.map(|(test_error, invariant)| {
let mut counterexample = None;
let mut logs = logs.clone();
let mut traces = traces.clone();
Expand Down Expand Up @@ -495,7 +494,7 @@ impl<'a> ContractRunner<'a> {
// If invariants ran successfully, replay the last run to collect logs and
// traces.
replay_run(
&invariant_contract.clone(),
&invariant_contract,
self.executor.clone(),
known_contracts,
identified_contracts.clone(),
Expand Down