Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Refactoring: Fully Migrate to Alloy #48

Open
wants to merge 12 commits into
base: 47-migrate-to-alloy-rs
Choose a base branch
from
74 changes: 39 additions & 35 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,51 +22,55 @@ path = "src/cached_proxy.rs"
[lib]
name = "dvf_libs"
path = "lib/lib.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tracing = "0.1.34"
tracing-subscriber = { version = "0.3.11", default-features = true, features = ["env-filter", "fmt"]}
reqwest = { version = "0.11", features = ["json", "blocking"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85"
substring = "1.4.5"
clap = { version = "3.1.6", features = ["derive"]}
actix-web = "4.7.0"
alloy = { version = "0.6.4", features = ["full"] }
alloy-chains = { version = "0.1.47", features = ["serde"] }
alloy-dyn-abi = { version = "0.8.12", features = ["eip712"] }
alloy-json-abi = "0.8.12"
alloy-node-bindings = "0.7.0"
alloy-rpc-types = "0.6.4"
alloy-rpc-types-trace = "0.6.4"
alloy-signer = { version = "0.6.4", features = ["eip712"] }
alloy-signer-ledger = "0.6.4"
alloy-signer-local = "0.6.4"
async-trait = "0.1.69"
bigint = "1"
bytes = "1.4.0"
clap = { version = "3.1.6", features = ["derive"] }
colored = "1.0.0"
console = "0.15.7"
dirs-next = "2.0.0"
dotenv = "0.15.0"
foundry-block-explorers = "0.9.0"
foundry-compilers = "0.11.6"
foundry-compilers-core = "0.12.3"
hex = "0.4"
indicatif = "0.17.6"
prettytable-rs = "0.10.0"
rand = "0.8.5"
regex = "1"
bigint = "1"
tiny-keccak = { version = "2.0.0", features = ["sha3", "keccak"] }
hex = "0.4"
ethers = { version = "2.0.8", features = ["solc"] }
ethers-contract = "2.0.8"
ethers-core = { version = "2.0.8" }
ethers-etherscan = { version = "2.0.8" }
ethers-providers = "2.0.8"
ethers-signers = {version = "2.0.8", features = ["ledger", "yubi", "yubihsm"]}
ethers-solc = "2.0.8"
reqwest = { version = "0.11", features = ["json", "blocking"] }
reth-trie = { git = "https://github.com/paradigmxyz/reth", tag = "v1.1.2"}
ruint = "1.12.3"
rustc-hex = "2.1.0"
scanf = "1.2.1"
semver = { version = "1.0.17", features = ["serde"] }
toml = "0.7.4"
dirs-next = "2.0.0"
zip = "0.6.6"
serde = { version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85"
sha3 = "0.10.8"
substring = "1.4.5"
tempfile = "3.6.0"
bytes = "1.4.0"
async-trait = "0.1.69"
thiserror = "1.0.40"
sha3 = "0.10.8"
rustc-hex = "2.1.0"
indicatif = "0.17.6"
console = "0.15.7"
actix-web = "4.7.0"
scanf = "1.2.1"
dotenv = "0.15.0"
time = "0.3.36"
foundry-compilers = "0.11.6"
alloy = { version = "0.6.4", features = ["full"] }
alloy-rpc-types = "0.6.4"
alloy-rpc-types-trace = "0.6.4"
tiny-keccak = { version = "2.0.0", features = ["sha3", "keccak"] }
tokio = { version = "1", features = ["full"] }
toml = "0.7.4"
tracing = "0.1.34"
tracing-subscriber = { version = "0.3.11", default-features = true, features = ["env-filter", "fmt"] }
zip = "0.6.6"

[dev-dependencies]
assert_cmd = "2.0.12"
Expand Down
15 changes: 7 additions & 8 deletions lib/bytecode_verification/compare_bytecodes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloy::dyn_abi::{JsonAbiExt};
use alloy::dyn_abi::JsonAbiExt;
use foundry_compilers::artifacts::BytecodeHash;
use tracing::{debug, info};

Expand Down Expand Up @@ -273,8 +273,8 @@ impl CompareInitCode {
for (arg, value) in project_info.constructor_args.iter_mut().zip(decoded_args) {
let encoded_value = value.abi_encode_packed();
let formatted_value = format!("0x{}", hex::encode(&encoded_value));

let sol_type = value.as_type().expect(format!("Unable to find constructor argument type for {}", arg.name).as_str());
let sol_type = value.as_type().unwrap_or_else(|| panic!("Unable to find constructor argument type for {}", arg.name));

arg.value = formatted_value;
arg.type_string = sol_type.sol_type_name().to_string()
Expand All @@ -289,7 +289,6 @@ impl CompareInitCode {
mod tests {
use crate::types::ConstructorArg;
use alloy::json_abi::{Constructor, Param, StateMutability};
use ethers::abi::ParamType;
use semver::Version;
use std::collections::HashMap;

Expand Down Expand Up @@ -359,18 +358,18 @@ mod tests {
ConstructorArg {
name: "arg1".to_string(),
value: "1".to_string(),
type_string: "uint256".to_string(),
type_string: "address".to_string(),
},
ConstructorArg {
name: "arg2".to_string(),
value: "2".to_string(),
type_string: "uint128".to_string(),
type_string: "address".to_string(),
},
];

let constructor_inputs: Vec<Param> = vec![
Param::parse("uint256 arg1").unwrap(),
Param::parse("uint128 arg2").unwrap()
Param::parse("address arg1").unwrap(),
Param::parse("address arg2").unwrap()
];

let constructor = Constructor {
Expand Down
20 changes: 9 additions & 11 deletions lib/bytecode_verification/parse_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,14 +869,12 @@ impl ProjectInfo {
if value["nodeType"] == "FunctionCall" && value["expression"]["name"] == "keccak256" {
if let Some(arguments) = value.get("arguments") {
if !arguments.as_array().unwrap().is_empty() {
let mut slot = U256::from_str(
arguments[0]["typeDescriptions"]["typeIdentifier"]
.as_str()
.unwrap()
.replace("t_stringliteral_", "")
.as_str(),
)
.unwrap();
let mut hex_wo_prefix = arguments[0]["typeDescriptions"]["typeIdentifier"]
.as_str()
.unwrap()
.replace("t_stringliteral_", "");
hex_wo_prefix.insert_str(0, "0x");
let mut slot = U256::from_str(hex_wo_prefix.as_str()).unwrap();
if let Some(binary_op) = binary_op {
slot -= U256::from(binary_op);
}
Expand Down Expand Up @@ -1399,9 +1397,9 @@ impl ProjectInfo {
Ok(read_dir) => {
for build_info_file in read_dir.flatten() {
let bi: BuildInfo = BuildInfo::read(&build_info_file.path())?;
if bi.output.contracts.values().flatten().find(|(name, _)| {
name == &contract_name
}).is_some() {
if bi.output.contracts.values().flatten().any(|(name, _)| {
name == contract_name
}) {
build_infos.push(bi);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/bytecode_verification/verify_bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io::prelude::*;
use std::path::Path;

use colored::Colorize;
use ethers::abi::Address;
use alloy::primitives::Address;
use prettytable::Table;
use tracing::debug;

Expand Down
132 changes: 86 additions & 46 deletions lib/dvf/abstract_wallet.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
use async_trait::async_trait;
use ethers::signers::{LocalWallet, Signer};
use ethers::types::Signature;
use ethers_core::types::transaction::eip2718::TypedTransaction;
use ethers_core::types::transaction::eip712::Eip712;
use ethers_core::types::Address;
use ethers_signers::Ledger;
use ethers_signers::LedgerError;
use ethers_signers::WalletError;

use alloy::signers::{Signer, Error as SignerError};
use alloy::signers::local::{PrivateKeySigner, LocalSignerError};
use alloy_signer_ledger::{LedgerSigner, LedgerError};
use alloy::primitives::{Address, PrimitiveSignature as Signature, B256, ChainId};
use alloy::consensus::SignableTransaction;
use alloy::network::TxSigner;
use alloy::dyn_abi::eip712::TypedData;
use alloy::sol_types::{Eip712Domain, SolStruct};

use thiserror::Error;

#[derive(Error, Debug)]
pub enum AbstractError {
LedgerError(LedgerError),
WalletError(WalletError),
WalletError(LocalSignerError),
GeneralError(SignerError),
}

impl From<LedgerError> for AbstractError {
Expand All @@ -21,106 +24,143 @@ impl From<LedgerError> for AbstractError {
}
}

impl From<WalletError> for AbstractError {
fn from(error: WalletError) -> Self {
impl From<LocalSignerError> for AbstractError {
fn from(error: LocalSignerError) -> Self {
AbstractError::WalletError(error)
}
}

impl From<alloy::signers::Error> for AbstractError {
fn from(error: SignerError) -> Self {
AbstractError::GeneralError(error)
}
}

impl std::fmt::Display for AbstractError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AbstractError::LedgerError(e) => write!(f, "{:?}", e),
AbstractError::WalletError(e) => write!(f, "{:?}", e),
AbstractError::GeneralError(e) => write!(f, "{:?}", e),
}
}
}

#[derive(Debug)]
pub enum AbstractWallet {
Ledger(Ledger),
LocalWallet(LocalWallet),
Ledger(LedgerSigner),
LocalWallet(PrivateKeySigner),
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl TxSigner<Signature> for AbstractWallet {

fn address(&self) -> Address {
match self {
AbstractWallet::Ledger(ledger) => Signer::address(ledger),
AbstractWallet::LocalWallet(localwallet) => localwallet.address(),
}
}

#[inline]
async fn sign_transaction(
&self,
tx: &mut dyn SignableTransaction<Signature>,
) -> Result<Signature, alloy::signers::Error> { //@audit how to turn a typed transaction into a signableTx?
match self {
AbstractWallet::Ledger(ledger) => ledger
.sign_transaction(tx)
.await,
AbstractWallet::LocalWallet(localwallet) => localwallet
.sign_transaction(tx)
.await,
}
}
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl Signer for AbstractWallet {
type Error = AbstractError;

async fn sign_message<S: Send + Sync + AsRef<[u8]>>(
async fn sign_hash(&self, _hash: &B256) -> Result<Signature, alloy::signers::Error> {
Err(alloy_signer::Error::UnsupportedOperation(
alloy_signer::UnsupportedSignerOperation::SignHash,
))
}

async fn sign_message(
&self,
message: S,
) -> Result<Signature, AbstractError> {
message: &[u8],
) -> Result<Signature, alloy::signers::Error> {
match self {
AbstractWallet::Ledger(ledger) => ledger
.sign_message(message)
.await
.map_err(AbstractError::from),
.await,
AbstractWallet::LocalWallet(localwallet) => localwallet
.sign_message(message)
.await
.map_err(AbstractError::from),
.await,
}
}

/// Signs the transaction
async fn sign_transaction(
#[inline]
async fn sign_typed_data<T: SolStruct + Send + Sync>(
&self,
message: &TypedTransaction,
) -> Result<Signature, AbstractError> {
payload: &T,
domain: &Eip712Domain,
) -> Result<Signature, alloy::signers::Error> {
match self {
AbstractWallet::Ledger(ledger) => ledger
.sign_transaction(message)
.await
.map_err(AbstractError::from),
.sign_typed_data(payload, domain)
.await,
// .map_err(AbstractError::from),
AbstractWallet::LocalWallet(localwallet) => localwallet
.sign_transaction(message)
.await
.map_err(AbstractError::from),
.sign_typed_data(payload, domain)
.await,
// .map_err(AbstractError::from),
}
}

async fn sign_typed_data<T: Eip712 + Send + Sync>(
&self,
payload: &T,
) -> Result<Signature, AbstractError> {
#[inline]
async fn sign_dynamic_typed_data(&self, payload: &TypedData) -> Result<Signature, alloy::signers::Error> {
match self {
AbstractWallet::Ledger(ledger) => ledger
.sign_typed_data(payload)
.await
.map_err(AbstractError::from),
.sign_dynamic_typed_data(payload)
.await,
// .map_err(AbstractError::from),
AbstractWallet::LocalWallet(localwallet) => localwallet
.sign_typed_data(payload)
.await
.map_err(AbstractError::from),
.sign_dynamic_typed_data(payload)
.await,
// .map_err(AbstractError::from),
}
}

/// Returns the signer's Ethereum Address
fn address(&self) -> Address {
match self {
AbstractWallet::Ledger(ledger) => ledger.address(),
AbstractWallet::Ledger(ledger) => Signer::address(ledger),
AbstractWallet::LocalWallet(localwallet) => localwallet.address(),
}
}

/// Returns the signer's chain id
fn chain_id(&self) -> u64 {
fn chain_id(&self) -> Option<ChainId> {
match self {
AbstractWallet::Ledger(ledger) => ledger.chain_id(),
AbstractWallet::LocalWallet(localwallet) => localwallet.chain_id(),
}
}

/// Sets the signer's chain id
fn with_chain_id<T: Into<u64>>(self, chain_id: T) -> Self {
fn set_chain_id(&mut self, chain_id: Option<ChainId>) {
match self {
AbstractWallet::Ledger(ledger) => {
AbstractWallet::Ledger(ledger.with_chain_id(chain_id))
ledger.set_chain_id(chain_id)
}
AbstractWallet::LocalWallet(localwallet) => {
AbstractWallet::LocalWallet(localwallet.with_chain_id(chain_id))
localwallet.set_chain_id(chain_id)
}
}
}
}

Loading