Skip to content

Commit

Permalink
fix: decode events for 0-sized contracts (#1317)
Browse files Browse the repository at this point in the history
  • Loading branch information
onbjerg committed Apr 15, 2022
1 parent 968125b commit 0b85a3e
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 16 deletions.
7 changes: 5 additions & 2 deletions cli/src/cmd/forge/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use forge::{
builder::Backend, opts::EvmOpts, CallResult, DatabaseRef, DeployResult, EvmError, Executor,
ExecutorBuilder, RawCallResult,
},
trace::{identifier::LocalTraceIdentifier, CallTraceArena, CallTraceDecoder, TraceKind},
trace::{identifier::LocalTraceIdentifier, CallTraceArena, CallTraceDecoderBuilder, TraceKind},
CALLER,
};
use foundry_common::evm::EvmArgs;
Expand Down Expand Up @@ -162,7 +162,10 @@ impl Cmd for RunArgs {
// bytecode. Might be better to wait for an interactive debugger where we can do this on
// the fly while retaining access to the database?
let local_identifier = LocalTraceIdentifier::new(&known_contracts);
let mut decoder = CallTraceDecoder::new_with_labels(result.labeled_addresses.clone());
let mut decoder = CallTraceDecoderBuilder::new()
.with_labels(result.labeled_addresses.clone())
.with_events(local_identifier.events())
.build();
for (_, trace) in &mut result.traces {
decoder.identify(trace, &local_identifier);
}
Expand Down
8 changes: 5 additions & 3 deletions cli/src/cmd/forge/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use forge::{
gas_report::GasReport,
trace::{
identifier::{EtherscanIdentifier, LocalTraceIdentifier},
CallTraceDecoder, TraceKind,
CallTraceDecoderBuilder, TraceKind,
},
MultiContractRunner, MultiContractRunnerBuilder, SuiteResult, TestFilter, TestKind,
};
Expand Down Expand Up @@ -521,8 +521,10 @@ fn test(

if !result.traces.is_empty() {
// Identify addresses in each trace
let mut decoder =
CallTraceDecoder::new_with_labels(result.labeled_addresses.clone());
let mut decoder = CallTraceDecoderBuilder::new()
.with_labels(result.labeled_addresses.clone())
.with_events(local_identifier.events())
.build();

// Decode the traces
let mut decoded_traces = Vec::new();
Expand Down
45 changes: 36 additions & 9 deletions evm/src/trace/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,42 @@ use ethers::{
};
use std::collections::{BTreeMap, HashMap};

/// Build a new [CallTraceDecoder].
#[derive(Default)]
pub struct CallTraceDecoderBuilder {
decoder: CallTraceDecoder,
}

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

/// Add known labels to the decoder.
pub fn with_labels(mut self, labels: BTreeMap<Address, String>) -> Self {
for (address, label) in labels.into_iter() {
self.decoder.labels.insert(address, label);
}
self
}

/// Add known events to the decoder.
pub fn with_events(mut self, events: Vec<Event>) -> Self {
events
.into_iter()
.map(|event| ((event.signature(), indexed_inputs(&event)), event))
.for_each(|(sig, event)| {
self.decoder.events.entry(sig).or_default().push(event);
});
self
}

/// Build the decoder.
pub fn build(self) -> CallTraceDecoder {
self.decoder
}
}

/// The call trace decoder.
///
/// The decoder collects address labels and ABIs from any number of [TraceIdentifier]s, which it
Expand Down Expand Up @@ -130,15 +166,6 @@ impl CallTraceDecoder {
}
}

/// Creates a new call trace decoder with predetermined address labels.
pub fn new_with_labels(labels: BTreeMap<Address, String>) -> Self {
let mut info = Self::new();
for (address, label) in labels.into_iter() {
info.labels.insert(address, label);
}
info
}

/// Identify unknown addresses in the specified call trace using the specified identifier.
///
/// Unknown contracts are contracts that either lack a label or an ABI.
Expand Down
7 changes: 6 additions & 1 deletion evm/src/trace/identifier/local.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{AddressIdentity, TraceIdentifier};
use ethers::{
abi::{Abi, Address},
abi::{Abi, Address, Event},
prelude::ArtifactId,
};
use std::{borrow::Cow, collections::BTreeMap};
Expand All @@ -21,6 +21,11 @@ impl LocalTraceIdentifier {
.collect(),
}
}

/// Get all the events of the local contracts.
pub fn events(&self) -> Vec<Event> {
self.local_contracts.iter().flat_map(|(_, (_, abi))| abi.events().cloned()).collect()
}
}

impl TraceIdentifier for LocalTraceIdentifier {
Expand Down
2 changes: 1 addition & 1 deletion evm/src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod decoder;
mod node;
mod utils;

pub use decoder::CallTraceDecoder;
pub use decoder::{CallTraceDecoder, CallTraceDecoderBuilder};

use crate::{abi::CHEATCODE_ADDRESS, CallKind};
use ansi_term::Colour;
Expand Down

0 comments on commit 0b85a3e

Please sign in to comment.