Skip to content

Commit

Permalink
feat(deps): Move to Alloy ABI encoding/decoding & alloy types (#5986)
Browse files Browse the repository at this point in the history
* feat: find and replace all ethers_solc mentions outside anvil

* chore: keep resolving errors as fuzz is getting migrated

* feat: fuzz/trace changes

* feat: partial trace migration

* chore: use temporal sol! macro in diff file for decode migration

* feat: use proptest traits instead of custom impl

* chore: address comments

* chore: remove alloy console bindings

* feat: introduce foundry-block-explorers

* chore: partial common abi helpers migration

* feat: partial decode migration

* feat: re-introduce block-explorers

* feat: fix compiler errors

* chore

* chore: tentative inspector migration

* feat: switch to using static decoder to decode errors

* chore: clippy

* feat: migrate trace types temporarily

* chore: replace ethers tracing types for local tracing types

* fix: handle decoding with static decoder, tests

* chore: use JsonAbi for console/hardhat/hevm abis

* chore: add todo

* chore: replace types downstream and remove glue

* feat: fix last evm issues, start fixing downstream type issues

* chore: cargo

* chore: more downstream error fixes

* chore: fix test files

* chore: more downstream fixes

* chore: fmt

* feat: migrate unit utils, replace

* chore: fix tests, fmt

* compiles

* clippy

* chore: clippy

* chore: last fixes

* chore: update block explorers

* chore: actually coerce values correctly

* chore: fix broken test

* chore: fix estimation test, parse values as alloy nums

* chore: fix abi parsing

* chore: selector tests

* chore: fix more tests, remove more glue

* chore: properly decode logs

* chore: use selector_type to handle tuples correctly

* chore: clippy and fix another test

* chore: fix remaining abi tests

* chore: use proptest traits for fuzzer

* more test fixes ongod

* clippy

* chore: use abigen for console logs for now

* fix: generate valid values in fuzzer

* chore: clippy

* chore: readd settings

* chore: various fixes

* chore: fix script arguments decoding

* chore: fix more tests

* chore: last ots fixes

* fix: decoding

* chore: clippy

* chore: fmt

* chore: fix deny check

* chore: deny fixes

* chore: force default features off

* chore: update block-explorers

* chore: doc fixes

* chore: ignore invariant storage test due to flakyness

* chore: update foundry-block-explorers

* chore: cleanup, config migration

* chore: resolve comments, more cleanup, remove unwraps

* chore: remove last mentions of ethers::etherscan

* chore: remove ethers-solc feat

* chore: use alloy master again

* chore: readd NameOrAddress

* chore: clippy/fmt

* chore: readd support on storage

* fix: add remappings on settings

* chore: address comments (remove create2, noop map, remove eyre from decode.rs)

* chore: use NameOrAddress
  • Loading branch information
Evalir authored Oct 25, 2023
1 parent 6ac22df commit 251ef74
Show file tree
Hide file tree
Showing 161 changed files with 3,382 additions and 1,935 deletions.
635 changes: 413 additions & 222 deletions Cargo.lock

Large diffs are not rendered by default.

38 changes: 23 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ alloy-json-abi = "0.4.1"
alloy-sol-types = "0.4.1"
syn-solidity = "0.4.1"

# solc utils
foundry-compilers = { version = "0.1", default-features = false }
# block explorer utils
foundry-block-explorers = { version = "0.1", default-features = false }

solang-parser = "=0.3.2"

## misc
Expand Down Expand Up @@ -187,18 +192,21 @@ color-eyre = "0.6"
#ethers-solc = { path = "../ethers-rs/ethers-solc" }

[patch.crates-io]
ethers = { git = "https://github.com/gakonst/ethers-rs" }
ethers-addressbook = { git = "https://github.com/gakonst/ethers-rs" }
ethers-core = { git = "https://github.com/gakonst/ethers-rs" }
ethers-contract = { git = "https://github.com/gakonst/ethers-rs" }
ethers-contract-abigen = { git = "https://github.com/gakonst/ethers-rs" }
ethers-providers = { git = "https://github.com/gakonst/ethers-rs" }
ethers-signers = { git = "https://github.com/gakonst/ethers-rs" }
ethers-middleware = { git = "https://github.com/gakonst/ethers-rs" }
ethers-etherscan = { git = "https://github.com/gakonst/ethers-rs" }
ethers-solc = { git = "https://github.com/gakonst/ethers-rs" }

# revm = { git = "https://github.com/bluealloy/revm/", branch = "main" }
# revm-interpreter = { git = "https://github.com/bluealloy/revm/", branch = "main" }
# revm-precompile = { git = "https://github.com/bluealloy/revm/", branch = "main" }
# revm-primitives = { git = "https://github.com/bluealloy/revm/", branch = "main" }
ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-addressbook = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-core = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-contract = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-contract-abigen = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-providers = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-signers = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-middleware = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-etherscan = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }
ethers-solc = { git = "https://github.com/gakonst/ethers-rs", rev = "9754f22d06a2defe5608c4c9b809cc361443a3dc" }

foundry-compilers = { git = "https://github.com/foundry-rs/compilers" }
foundry-block-explorers = { git = "https://github.com/foundry-rs/block-explorers"}

alloy-dyn-abi = { git = "https://github.com/alloy-rs/core/" }
alloy-primitives = { git = "https://github.com/alloy-rs/core/" }
alloy-json-abi = { git = "https://github.com/alloy-rs/core/" }
alloy-sol-types = { git = "https://github.com/alloy-rs/core/" }
2 changes: 1 addition & 1 deletion crates/abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ foundry-macros.workspace = true

ethers-core.workspace = true
ethers-contract = { workspace = true, features = ["abigen", "providers"] }
ethers-providers.workspace = true
ethers-providers.workspace = true
2 changes: 1 addition & 1 deletion crates/anvil/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl NodeArgs {
.fork_block_number
.or_else(|| self.evm_opts.fork_url.as_ref().and_then(|f| f.block)),
)
.with_fork_chain_id(self.evm_opts.fork_chain_id)
.with_fork_chain_id(self.evm_opts.fork_chain_id.map(u64::from))
.fork_request_timeout(self.evm_opts.fork_request_timeout.map(Duration::from_millis))
.fork_request_retries(self.evm_opts.fork_request_retries)
.fork_retry_backoff(self.evm_opts.fork_retry_backoff.map(Duration::from_millis))
Expand Down
2 changes: 1 addition & 1 deletion crates/anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,7 @@ impl Backend {
(halt_to_instruction_result(reason), gas_used, None)
},
};
let res = inspector.tracer.unwrap_or_default().traces.geth_trace(gas_used.into(), opts);
let res = inspector.tracer.unwrap_or_default().traces.geth_trace(rU256::from(gas_used), opts);
trace!(target: "backend", "trace call return {:?} out: {:?} gas {} on block {}", exit_reason, out, gas_used, block_number);
Ok(res)
})
Expand Down
4 changes: 2 additions & 2 deletions crates/anvil/src/eth/backend/mem/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use ethers::{
types::{ActionType, Bytes, GethDebugTracingOptions, TransactionReceipt, U256},
};
use foundry_evm::revm::{interpreter::InstructionResult, primitives::Env};
use foundry_utils::types::ToEthers;
use foundry_utils::types::{ToAlloy, ToEthers};
use parking_lot::RwLock;
use std::{
collections::{HashMap, VecDeque},
Expand Down Expand Up @@ -406,7 +406,7 @@ impl MinedTransaction {
}

pub fn geth_trace(&self, opts: GethDebugTracingOptions) -> DefaultFrame {
self.info.traces.geth_trace(self.receipt.gas_used(), opts)
self.info.traces.geth_trace(self.receipt.gas_used().to_alloy(), opts)
}
}

Expand Down
60 changes: 32 additions & 28 deletions crates/anvil/src/eth/otterscan/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use alloy_primitives::U256 as rU256;
use ethers::types::{
Action, Address, Block, Bytes, CallType, Trace, Transaction, TransactionReceipt, H256, U256,
};
use foundry_evm::{executor::InstructionResult, CallKind};
use foundry_utils::types::ToEthers;
use futures::future::join_all;
use serde::{de::DeserializeOwned, Serialize};
use serde_repr::Serialize_repr;
Expand Down Expand Up @@ -239,35 +241,37 @@ impl OtsInternalOperation {
.traces
.arena
.iter()
.filter_map(|node| match (node.kind(), node.status()) {
(CallKind::Call, _) if !node.trace.value.is_zero() => Some(Self {
r#type: OtsInternalOperationType::Transfer,
from: node.trace.caller,
to: node.trace.address,
value: node.trace.value,
}),
(CallKind::Create, _) => Some(Self {
r#type: OtsInternalOperationType::Create,
from: node.trace.caller,
to: node.trace.address,
value: node.trace.value,
}),
(CallKind::Create2, _) => Some(Self {
r#type: OtsInternalOperationType::Create2,
from: node.trace.caller,
to: node.trace.address,
value: node.trace.value,
}),
(_, InstructionResult::SelfDestruct) => {
Some(Self {
r#type: OtsInternalOperationType::SelfDestruct,
from: node.trace.address,
// the foundry CallTraceNode doesn't have a refund address
to: Default::default(),
value: node.trace.value,
})
.filter_map(|node| {
match (node.kind(), node.status()) {
(CallKind::Call, _) if node.trace.value != rU256::ZERO => Some(Self {
r#type: OtsInternalOperationType::Transfer,
from: node.trace.caller.to_ethers(),
to: node.trace.address.to_ethers(),
value: node.trace.value.to_ethers(),
}),
(CallKind::Create, _) => Some(Self {
r#type: OtsInternalOperationType::Create,
from: node.trace.caller.to_ethers(),
to: node.trace.address.to_ethers(),
value: node.trace.value.to_ethers(),
}),
(CallKind::Create2, _) => Some(Self {
r#type: OtsInternalOperationType::Create2,
from: node.trace.caller.to_ethers(),
to: node.trace.address.to_ethers(),
value: node.trace.value.to_ethers(),
}),
(_, InstructionResult::SelfDestruct) => {
Some(Self {
r#type: OtsInternalOperationType::SelfDestruct,
from: node.trace.address.to_ethers(),
// the foundry CallTraceNode doesn't have a refund address
to: Default::default(),
value: node.trace.value.to_ethers(),
})
}
_ => None,
}
_ => None,
})
.collect()
}
Expand Down
10 changes: 7 additions & 3 deletions crates/anvil/tests/it/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ use ethers::{
};
use foundry_common::get_http_provider;
use foundry_config::Config;
use foundry_utils::{rpc, rpc::next_http_rpc_endpoint, types::ToAlloy};
use foundry_utils::{
rpc,
rpc::next_http_rpc_endpoint,
types::{ToAlloy, ToEthers},
};
use futures::StreamExt;
use std::{sync::Arc, time::Duration};

Expand Down Expand Up @@ -160,8 +164,8 @@ async fn test_fork_eth_get_nonce() {
}

let addr = Config::DEFAULT_SENDER;
let api_nonce = api.transaction_count(addr, None).await.unwrap();
let provider_nonce = provider.get_transaction_count(addr, None).await.unwrap();
let api_nonce = api.transaction_count(addr.to_ethers(), None).await.unwrap();
let provider_nonce = provider.get_transaction_count(addr.to_ethers(), None).await.unwrap();
assert_eq!(api_nonce, provider_nonce);
}

Expand Down
9 changes: 9 additions & 0 deletions crates/cast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ foundry-common.workspace = true
ethers-etherscan.workspace = true
ethers-core.workspace = true
ethers-providers.workspace = true

alloy-primitives.workspace = true
alloy-json-abi.workspace = true
alloy-dyn-abi.workspace = true

foundry-compilers = { workspace = true, default-features = false }
foundry-block-explorers = { workspace = true }


chrono.workspace = true
evm-disassembler = "0.3"
eyre.workspace = true
Expand Down
4 changes: 3 additions & 1 deletion crates/cast/bin/cmd/access_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use foundry_cli::{
utils,
};
use foundry_config::{Chain, Config};
use foundry_utils::types::ToEthers;
use std::str::FromStr;

/// CLI arguments for `cast access-list`.
Expand Down Expand Up @@ -65,7 +66,8 @@ impl AccessListArgs {
let chain = utils::get_chain(config.chain_id, &provider).await?;
let sender = eth.wallet.sender().await;

access_list(&provider, sender, to, sig, args, data, tx, chain, block, to_json).await?;
access_list(&provider, sender.to_ethers(), to, sig, args, data, tx, chain, block, to_json)
.await?;
Ok(())
}
}
Expand Down
19 changes: 9 additions & 10 deletions crates/cast/bin/cmd/call.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
use alloy_primitives::U256;
use cast::{Cast, TxBuilder};
use clap::Parser;
use ethers::{
solc::EvmVersion,
types::{BlockId, NameOrAddress, U256},
};
use ethers::types::{BlockId, NameOrAddress};
use eyre::{Result, WrapErr};
use foundry_cli::{
opts::{EthereumOpts, TransactionOpts},
utils::{self, handle_traces, parse_ether_value, TraceResult},
};
use foundry_common::runtime_client::RuntimeClient;
use foundry_compilers::EvmVersion;
use foundry_config::{find_project_root_path, Config};
use foundry_evm::{executor::opts::EvmOpts, trace::TracingExecutor};
use foundry_utils::types::ToAlloy;
use foundry_utils::types::{ToAlloy, ToEthers};
use std::str::FromStr;

type Provider = ethers::providers::Provider<RuntimeClient>;
Expand Down Expand Up @@ -131,7 +130,7 @@ impl CallArgs {
let sender = eth.wallet.sender().await;

let mut builder: TxBuilder<'_, Provider> =
TxBuilder::new(&provider, sender, to, chain, tx.legacy).await?;
TxBuilder::new(&provider, sender.to_ethers(), to, chain, tx.legacy).await?;

builder
.gas(tx.gas_limit)
Expand All @@ -156,9 +155,9 @@ impl CallArgs {
.await;

let trace = match executor.deploy(
sender.to_alloy(),
sender,
code.into_bytes().into(),
value.unwrap_or(U256::zero()).to_alloy(),
value.unwrap_or(U256::ZERO),
None,
) {
Ok(deploy_result) => TraceResult::from(deploy_result),
Expand Down Expand Up @@ -193,7 +192,7 @@ impl CallArgs {
let (tx, _) = builder.build();

let trace = TraceResult::from(executor.call_raw_committing(
sender.to_alloy(),
sender,
tx.to_addr().copied().expect("an address to be here").to_alloy(),
tx.data().cloned().unwrap_or_default().to_vec().into(),
tx.value().copied().unwrap_or_default().to_alloy(),
Expand All @@ -208,7 +207,7 @@ impl CallArgs {

let builder_output: (
ethers::types::transaction::eip2718::TypedTransaction,
Option<ethers::abi::Function>,
Option<alloy_json_abi::Function>,
) = builder.build();

println!("{}", Cast::new(provider).call(builder_output, block).await?);
Expand Down
29 changes: 9 additions & 20 deletions crates/cast/bin/cmd/create2.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
use cast::SimpleCast;
use alloy_primitives::{keccak256, Address, B256, U256};
use clap::Parser;
use ethers::{
core::rand::thread_rng,
types::{Address, Bytes, H256, U256},
utils::{get_create2_address_from_hash, keccak256},
};
use eyre::{Result, WrapErr};
use rayon::prelude::*;
use regex::RegexSetBuilder;
Expand Down Expand Up @@ -114,7 +109,7 @@ impl Create2Args {
let init_code_hash_bytes = hex::decode(init_code_hash)?;
assert!(init_code_hash_bytes.len() == 32, "init code hash should be 32 bytes long");
a.copy_from_slice(&init_code_hash_bytes);
a
a.into()
} else {
keccak256(hex::decode(init_code)?)
};
Expand All @@ -124,14 +119,9 @@ impl Create2Args {
let (salt, addr) = std::iter::repeat(())
.par_bridge()
.map(|_| {
let salt = H256::random_using(&mut thread_rng());
let salt = Bytes::from(salt.to_fixed_bytes());
let salt = B256::random();

let addr = SimpleCast::to_checksum_address(&get_create2_address_from_hash(
deployer,
salt.clone(),
init_code_hash,
));
let addr = deployer.create2(salt, init_code_hash).to_checksum(None);

(salt, addr)
})
Expand All @@ -142,7 +132,7 @@ impl Create2Args {
})
.unwrap();

let salt = U256::from(salt.to_vec().as_slice());
let salt = U256::from_be_bytes(*salt);
let address = Address::from_str(&addr).unwrap();

println!(
Expand All @@ -165,8 +155,6 @@ fn get_regex_hex_string(s: String) -> Result<String> {

#[cfg(test)]
mod tests {
use ethers::{abi::AbiEncode, utils::get_create2_address};

use super::*;

const DEPLOYER: &str = "0x4e59b44847b379578588920ca78fbf26c0b4956c";
Expand Down Expand Up @@ -304,11 +292,12 @@ mod tests {
}

fn verify_create2(deployer: Address, salt: U256, init_code: Vec<u8>) -> Address {
// let init_code_hash = keccak256(init_code);
get_create2_address(deployer, salt.encode(), init_code)
let init_code_hash = keccak256(init_code);
deployer.create2(salt.to_be_bytes(), init_code_hash)
}

fn verify_create2_hash(deployer: Address, salt: U256, init_code_hash: Vec<u8>) -> Address {
get_create2_address_from_hash(deployer, salt.encode(), init_code_hash)
let init_code_hash = B256::from_slice(&init_code_hash);
deployer.create2(salt.to_be_bytes(), init_code_hash)
}
}
3 changes: 2 additions & 1 deletion crates/cast/bin/cmd/estimate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use alloy_primitives::U256;
use cast::{Cast, TxBuilder};
use clap::Parser;
use ethers::types::{NameOrAddress, U256};
use ethers::types::NameOrAddress;
use eyre::Result;
use foundry_cli::{
opts::{EtherscanOpts, RpcOpts},
Expand Down
Loading

0 comments on commit 251ef74

Please sign in to comment.