chore(clippy): add some deny lints (#1064)

* feat: add deny lints

* trim ethers core

* trim ethers eip712

* deny ethers contract derive

* deny ethers contract abigen

* deny ethers contract

* deny ethers providers

* chore: add denies and fix unused deps

* doc: fix links

* fix: wasm build

* doc: fix links

* doc: fix links

* doc: fix inline doc links

* docs: fix intra doc links
This commit is contained in:
Matthias Seitz 2022-03-19 18:05:39 +01:00 committed by GitHub
parent cde52c7c20
commit 916e9a7334
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 143 additions and 146 deletions

8
Cargo.lock generated
View File

@ -1198,7 +1198,6 @@ dependencies = [
"eyre", "eyre",
"getrandom 0.2.5", "getrandom 0.2.5",
"hex", "hex",
"once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"reqwest", "reqwest",
@ -1232,17 +1231,14 @@ dependencies = [
"bytes", "bytes",
"cargo_metadata", "cargo_metadata",
"convert_case", "convert_case",
"ecdsa",
"elliptic-curve", "elliptic-curve",
"ethabi", "ethabi",
"futures-util",
"generic-array 0.14.5", "generic-array 0.14.5",
"hex", "hex",
"hex-literal", "hex-literal",
"k256", "k256",
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote",
"rand 0.8.5", "rand 0.8.5",
"rlp", "rlp",
"rlp-derive", "rlp-derive",
@ -1251,7 +1247,6 @@ dependencies = [
"syn", "syn",
"thiserror", "thiserror",
"tiny-keccak", "tiny-keccak",
"tokio",
] ]
[[package]] [[package]]
@ -1263,9 +1258,7 @@ dependencies = [
"ethers-core", "ethers-core",
"ethers-signers", "ethers-signers",
"hex", "hex",
"proc-macro2",
"quote", "quote",
"serde",
"serde_json", "serde_json",
"syn", "syn",
] ]
@ -1377,7 +1370,6 @@ dependencies = [
"thiserror", "thiserror",
"tokio", "tokio",
"tracing", "tracing",
"tracing-futures",
"tracing-subscriber", "tracing-subscriber",
"trezor-client", "trezor-client",
"yubihsm", "yubihsm",

View File

@ -38,7 +38,6 @@ ethers-solc = { version = "^0.3.0", path = "../ethers-solc", default-features =
tokio = { version = "1.5", default-features = false, features = ["macros"] } tokio = { version = "1.5", default-features = false, features = ["macros"] }
[features] [features]
default = ["rustls"]
eip712 = ["ethers-derive-eip712", "ethers-core/eip712"] eip712 = ["ethers-derive-eip712", "ethers-core/eip712"]
abigen = ["ethers-contract-abigen/reqwest", "ethers-contract-derive"] abigen = ["ethers-contract-abigen/reqwest", "ethers-contract-derive"]
abigen-offline = ["ethers-contract-abigen", "ethers-contract-derive"] abigen-offline = ["ethers-contract-abigen", "ethers-contract-derive"]

View File

@ -21,7 +21,6 @@ serde_json = "1.0.61"
serde = { version = "1.0.124", features = ["derive"] } serde = { version = "1.0.124", features = ["derive"] }
hex = { version = "0.4.2", default-features = false, features = ["std"] } hex = { version = "0.4.2", default-features = false, features = ["std"] }
reqwest = { version = "0.11.3", default-features = false, features = ["blocking"] , optional = true } reqwest = { version = "0.11.3", default-features = false, features = ["blocking"] , optional = true }
once_cell = "1.8.0"
cfg-if = "1.0.0" cfg-if = "1.0.0"
dunce = "1.0.2" dunce = "1.0.2"
walkdir = "2.3.2" walkdir = "2.3.2"

View File

@ -1,4 +1,5 @@
#![deny(missing_docs, unsafe_code)] #![deny(missing_docs, unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
//! Module for generating type-safe bindings to Ethereum smart contracts. This //! Module for generating type-safe bindings to Ethereum smart contracts. This
//! module is intended to be used either indirectly with the `abigen` procedural //! module is intended to be used either indirectly with the `abigen` procedural

View File

@ -1,6 +1,7 @@
//! Implementation of procedural macro for generating type-safe bindings to an //! Implementation of procedural macro for generating type-safe bindings to an
//! ethereum smart contract. //! ethereum smart contract.
#![deny(missing_docs, unsafe_code)] #![deny(missing_docs, unsafe_code, unused_crate_dependencies)]
#![deny(rustdoc::broken_intra_doc_links)]
use proc_macro::TokenStream; use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput}; use syn::{parse_macro_input, DeriveInput};

View File

@ -32,7 +32,7 @@ pub fn parse_int_param_type(s: &str) -> Option<ParamType> {
// Converts param types for indexed parameters to bytes32 where appropriate // Converts param types for indexed parameters to bytes32 where appropriate
// This applies to strings, arrays, structs and bytes to follow the encoding of // This applies to strings, arrays, structs and bytes to follow the encoding of
// these indexed param types according to // these indexed param types according to
// https://solidity.readthedocs.io/en/develop/abi-spec.html#encoding-of-indexed-event-parameters // <https://solidity.readthedocs.io/en/develop/abi-spec.html#encoding-of-indexed-event-parameters>
pub fn topic_param_type_quote(kind: &ParamType) -> proc_macro2::TokenStream { pub fn topic_param_type_quote(kind: &ParamType) -> proc_macro2::TokenStream {
let core_crate = ethers_core_crate(); let core_crate = ethers_core_crate();
match kind { match kind {

View File

@ -23,7 +23,7 @@ pub struct BaseContract {
/// A mapping from method signature to a name-index pair for accessing /// A mapping from method signature to a name-index pair for accessing
/// functions in the contract ABI. This is used to avoid allocation when /// functions in the contract ABI. This is used to avoid allocation when
/// searching for matching functions by signature. /// searching for matching functions by signature.
// Adapted from: https://github.com/gnosis/ethcontract-rs/blob/master/src/contract.rs // Adapted from: <https://github.com/gnosis/ethcontract-rs/blob/master/src/contract.rs>
pub methods: HashMap<Selector, (String, usize)>, pub methods: HashMap<Selector, (String, usize)>,
} }

View File

@ -1,5 +1,7 @@
#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![deny(unsafe_code)]
mod contract; mod contract;
pub use contract::Contract; pub use contract::Contract;

View File

@ -119,7 +119,7 @@ pub static ADDRESS_BOOK: Lazy<HashMap<U256, Address>> = Lazy::new(|| {
/// ///
/// [`new`]: method@crate::Multicall::new /// [`new`]: method@crate::Multicall::new
/// [`block`]: method@crate::Multicall::block /// [`block`]: method@crate::Multicall::block
/// [`add_call`]: methond@crate::Multicall::add_call /// [`add_call`]: method@crate::Multicall::add_call
#[derive(Clone)] #[derive(Clone)]
pub struct Multicall<M> { pub struct Multicall<M> {
calls: Vec<Call>, calls: Vec<Call>,

View File

@ -16,10 +16,9 @@ arrayvec = { version = "0.7.2", default-features = false }
rlp-derive = { version = "0.1.0", default-features = false } rlp-derive = { version = "0.1.0", default-features = false }
# crypto # crypto
ecdsa = { version = "0.13.4", default-features = false, features = ["std"] }
elliptic-curve = { version = "0.11.12", default-features = false } elliptic-curve = { version = "0.11.12", default-features = false }
generic-array = { version = "0.14.5", default-features = false } generic-array = { version = "0.14.5", default-features = false }
k256 = { version = "0.10.4", default-features = false, features = ["keccak256", "ecdsa"] } k256 = { version = "0.10.4", default-features = false, features = ["keccak256", "ecdsa", "std"] }
rand = { version = "0.8.5", default-features = false } rand = { version = "0.8.5", default-features = false }
tiny-keccak = { version = "2.0.2", default-features = false } tiny-keccak = { version = "2.0.2", default-features = false }
@ -29,7 +28,7 @@ serde_json = { version = "1.0.64", default-features = false }
thiserror = { version = "1.0.30", default-features = false } thiserror = { version = "1.0.30", default-features = false }
bytes = { version = "1.1.0", features = ["serde"] } bytes = { version = "1.1.0", features = ["serde"] }
hex = { version = "0.4.3", default-features = false, features = ["std"] } hex = { version = "0.4.3", default-features = false, features = ["std"] }
once_cell = "1.10.0" once_cell = { version = "1.10.0", optional = true }
# macros feature enabled dependencies # macros feature enabled dependencies
cargo_metadata = { version = "0.14.2", optional = true } cargo_metadata = { version = "0.14.2", optional = true }
@ -37,28 +36,20 @@ cargo_metadata = { version = "0.14.2", optional = true }
# eip712 feature enabled dependencies # eip712 feature enabled dependencies
convert_case = { version = "0.5.0", optional = true } convert_case = { version = "0.5.0", optional = true }
syn = { version = "1.0.89", optional = true } syn = { version = "1.0.89", optional = true }
quote = { version = "1.0.16", optional = true }
proc-macro2 = { version = "1.0.36", optional = true } proc-macro2 = { version = "1.0.36", optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# async
tokio = { version = "1.5", default-features = false, optional = true}
futures-util = { version = "^0.3", optional = true }
[dev-dependencies] [dev-dependencies]
serde_json = { version = "1.0.64", default-features = false } serde_json = { version = "1.0.64", default-features = false }
bincode = { version = "1.3.3", default-features = false } bincode = { version = "1.3.3", default-features = false }
once_cell = { version = "1.10.0" } once_cell = { version = "1.10.0" }
hex-literal = "0.3.4" hex-literal = "0.3.4"
futures-util = { version = "^0.3" }
rand = "0.8.5" rand = "0.8.5"
[features] [features]
celo = ["legacy"] # celo support extends the transaction format with extra fields celo = ["legacy"] # celo support extends the transaction format with extra fields
setup = ["tokio", "futures-util"] # async support for concurrent setup
legacy = [] legacy = []
eip712 = ["convert_case", "syn", "quote", "proc-macro2"] eip712 = ["convert_case", "syn", "proc-macro2"]
macros = ["syn", "cargo_metadata"] macros = ["syn", "cargo_metadata", "once_cell"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

View File

@ -13,9 +13,7 @@ quote = "1.0.9"
syn = "1.0.77" syn = "1.0.77"
ethers-core = { version = "^0.6.0", path = "../", default-features = false, features = ["eip712", "macros"] } ethers-core = { version = "^0.6.0", path = "../", default-features = false, features = ["eip712", "macros"] }
hex = "0.4.3" hex = "0.4.3"
serde = "1.0.130"
serde_json = "1.0.68" serde_json = "1.0.68"
proc-macro2 = "1.0.29"
[dev-dependencies] [dev-dependencies]
ethers-contract = { version = "^0.6.0", path = "../../ethers-contract", features = ["abigen"]} ethers-contract = { version = "^0.6.0", path = "../../ethers-contract", features = ["abigen"]}

View File

@ -59,6 +59,10 @@
//! //!
//! There is an Inner helper attribute `#[eip712]` for fields that will eventually be used to //! There is an Inner helper attribute `#[eip712]` for fields that will eventually be used to
//! determine if there is a nested eip712 struct. However, this work is not yet complete. //! determine if there is a nested eip712 struct. However, this work is not yet complete.
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(unused_crate_dependencies)]
use std::convert::TryFrom; use std::convert::TryFrom;
use ethers_core::{macros::ethers_core_crate, types::transaction::eip712}; use ethers_core::{macros::ethers_core_crate, types::transaction::eip712};

View File

@ -362,14 +362,14 @@ impl AbiParser {
/// } /// }
/// ``` /// ```
/// ///
/// See https://github.com/rust-ethereum/ethabi/issues/254 /// See <https://github.com/rust-ethereum/ethabi/issues/254>
/// ///
/// Therefore, we need to double-check if the `ethabi::Reader` parsed an `uint8`, and ignore the /// Therefore, we need to double-check if the `ethabi::Reader` parsed an `uint8`, and ignore the
/// type if `type_str` is not uint8. However can lead to some problems if a function param is /// type if `type_str` is not uint8. However can lead to some problems if a function param is
/// array of custom types for example, like `Foo[]`, which the `Reader` would identify as /// array of custom types for example, like `Foo[]`, which the `Reader` would identify as
/// `uint8[]`. Therefor if the `Reader` returns an `uint8` we also check that the input string /// `uint8[]`. Therefor if the `Reader` returns an `uint8` we also check that the input string
/// contains a `uint8`. This however can still lead to false detection of `uint8` and is only /// contains a `uint8`. This however can still lead to false detection of `uint8` and is only
/// solvable with a more sophisticated parser: https://github.com/gakonst/ethers-rs/issues/474 /// solvable with a more sophisticated parser: <https://github.com/gakonst/ethers-rs/issues/474>
fn parse_type(&self, type_str: &str) -> Result<(ParamType, Option<String>)> { fn parse_type(&self, type_str: &str) -> Result<(ParamType, Option<String>)> {
if let Ok(kind) = Reader::read(type_str) { if let Ok(kind) = Reader::read(type_str) {
if is_likely_tuple_not_uint8(&kind, type_str) { if is_likely_tuple_not_uint8(&kind, type_str) {

View File

@ -1,5 +1,8 @@
#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(unused_crate_dependencies)]
pub mod types; pub mod types;
pub mod abi; pub mod abi;

View File

@ -1,4 +1,4 @@
// Taken from https://github.com/tomusdrw/rust-web3/blob/master/src/types/block.rs // Taken from <https://github.com/tomusdrw/rust-web3/blob/master/src/types/block.rs>
use crate::types::{Address, Bloom, Bytes, H256, U256, U64}; use crate::types::{Address, Bloom, Bytes, H256, U256, U64};
#[cfg(not(feature = "celo"))] #[cfg(not(feature = "celo"))]
use core::cmp::Ordering; use core::cmp::Ordering;
@ -91,7 +91,7 @@ pub struct Block<TX> {
pub epoch_snark_data: Option<EpochSnarkData>, pub epoch_snark_data: Option<EpochSnarkData>,
} }
// ref https://eips.ethereum.org/EIPS/eip-1559 // ref <https://eips.ethereum.org/EIPS/eip-1559>
#[cfg(not(feature = "celo"))] #[cfg(not(feature = "celo"))]
pub const ELASTICITY_MULTIPLIER: U256 = U256([2u64, 0, 0, 0]); pub const ELASTICITY_MULTIPLIER: U256 = U256([2u64, 0, 0, 0]);
// max base fee delta is 12.5% // max base fee delta is 12.5%
@ -106,7 +106,7 @@ impl<TX> Block<TX> {
} }
/// The next block's base fee, it is a function of parent block's base fee and gas usage. /// The next block's base fee, it is a function of parent block's base fee and gas usage.
/// Reference: https://eips.ethereum.org/EIPS/eip-1559 /// Reference: <https://eips.ethereum.org/EIPS/eip-1559>
#[cfg(not(feature = "celo"))] #[cfg(not(feature = "celo"))]
pub fn next_block_base_fee(&self) -> Option<U256> { pub fn next_block_base_fee(&self) -> Option<U256> {
let target_usage = self.gas_target(); let target_usage = self.gas_target();
@ -162,7 +162,7 @@ pub struct EpochSnarkData {
/// A Block Hash or Block Number /// A Block Hash or Block Number
pub enum BlockId { pub enum BlockId {
// TODO: May want to expand this to include the requireCanonical field // TODO: May want to expand this to include the requireCanonical field
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md // <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md>
/// A block hash /// A block hash
Hash(H256), Hash(H256),
/// A block number /// A block number
@ -291,7 +291,7 @@ mod tests {
} }
#[test] #[test]
// https://github.com/tomusdrw/rust-web3/commit/3a32ee962c0f2f8d50a5e25be9f2dfec7ae0750d // <https://github.com/tomusdrw/rust-web3/commit/3a32ee962c0f2f8d50a5e25be9f2dfec7ae0750d>
fn post_london_block() { fn post_london_block() {
let json = serde_json::json!( let json = serde_json::json!(
{ {
@ -330,7 +330,7 @@ mod tests {
#[test] #[test]
fn test_next_block_base_fee() { fn test_next_block_base_fee() {
// https://etherscan.io/block/14402566 // <https://etherscan.io/block/14402566>
let mut block_14402566 = Block::<TxHash>::default(); let mut block_14402566 = Block::<TxHash>::default();
block_14402566.number = Some(U64::from(14402566u64)); block_14402566.number = Some(U64::from(14402566u64));
block_14402566.base_fee_per_gas = Some(U256::from(36_803_013_756u128)); block_14402566.base_fee_per_gas = Some(U256::from(36_803_013_756u128));

View File

@ -1,5 +1,5 @@
//! This module contains an 256-bit signed integer implementation. //! This module contains an 256-bit signed integer implementation.
//! This module was derived for ethers-core via https://github.com/gnosis/ethcontract-rs/ //! This module was derived for ethers-core via <https://github.com/gnosis/ethcontract-rs/>
#![allow(clippy::wrong_self_convention)] #![allow(clippy::wrong_self_convention)]
use crate::{ use crate::{
abi::{InvalidOutputType, Token, Tokenizable}, abi::{InvalidOutputType, Token, Tokenizable},

View File

@ -1,6 +1,6 @@
//! Types for the Parity Ad-Hoc Trace API //! Types for the Parity Ad-Hoc Trace API
//! //!
//! https://openethereum.github.io/wiki/JSONRPC-trace-module //! <https://openethereum.github.io/wiki/JSONRPC-trace-module>
use crate::types::{Bytes, H160, H256, U256}; use crate::types::{Bytes, H160, H256, U256};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::BTreeMap; use std::collections::BTreeMap;

View File

@ -56,7 +56,7 @@ pub enum Eip712Error {
/// for `derive_eip712` for more information and example usage. /// for `derive_eip712` for more information and example usage.
/// ///
/// For those who wish to manually implement this trait, see: /// For those who wish to manually implement this trait, see:
/// https://eips.ethereum.org/EIPS/eip-712 /// <https://eips.ethereum.org/EIPS/eip-712>
/// ///
/// Any rust struct implementing Eip712 must also have a corresponding /// Any rust struct implementing Eip712 must also have a corresponding
/// struct in the verifying ethereum contract that matches its signature. /// struct in the verifying ethereum contract that matches its signature.
@ -412,7 +412,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
} }
/// Parse the eth abi parameter type based on the syntax type; /// Parse the eth abi parameter type based on the syntax type;
/// this method is copied from https://github.com/gakonst/ethers-rs/blob/master/ethers-contract/ethers-contract-derive/src/lib.rs#L600 /// this method is copied from <https://github.com/gakonst/ethers-rs/blob/master/ethers-contract/ethers-contract-derive/src/lib.rs#L600>
/// with additional modifications for finding byte arrays /// with additional modifications for finding byte arrays
pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> { pub fn find_parameter_type(ty: &Type) -> Result<ParamType, TokenStream> {
match ty { match ty {

View File

@ -252,7 +252,7 @@ pub fn secret_key_to_address(secret_key: &SigningKey) -> Address {
} }
/// Converts an Ethereum address to the checksum encoding /// Converts an Ethereum address to the checksum encoding
/// Ref: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md /// Ref: <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md>
pub fn to_checksum(addr: &Address, chain_id: Option<u8>) -> String { pub fn to_checksum(addr: &Address, chain_id: Option<u8>) -> String {
let prefixed_addr = match chain_id { let prefixed_addr = match chain_id {
Some(chain_id) => format!("{}0x{:x}", chain_id, addr), Some(chain_id) => format!("{}0x{:x}", chain_id, addr),

View File

@ -4,7 +4,7 @@ use std::collections::BTreeMap;
use k256::SecretKey; use k256::SecretKey;
/// Returns the private developer keys https://docs.moonbeam.network/snippets/code/setting-up-node/dev-accounts/ /// Returns the private developer keys <https://docs.moonbeam.network/snippets/code/setting-up-node/dev-accounts/>
pub fn dev_keys() -> Vec<SecretKey> { pub fn dev_keys() -> Vec<SecretKey> {
MoonbeamDev::default().into_keys().collect() MoonbeamDev::default().into_keys().collect()
} }

View File

@ -24,9 +24,9 @@ pub struct Client {
client: reqwest::Client, client: reqwest::Client,
/// Etherscan API key /// Etherscan API key
api_key: String, api_key: String,
/// Etherscan API endpoint like https://api(-chain).etherscan.io/api /// Etherscan API endpoint like <https://api(-chain).etherscan.io/api>
etherscan_api_url: Url, etherscan_api_url: Url,
/// Etherscan base endpoint like https://etherscan.io /// Etherscan base endpoint like <https://etherscan.io>
etherscan_url: Url, etherscan_url: Url,
} }

View File

@ -7,7 +7,7 @@ use ethers_core::types::U256;
/// Coefficient defaults to 1.125 (12.5%), the minimum increase for Parity to replace a transaction. /// Coefficient defaults to 1.125 (12.5%), the minimum increase for Parity to replace a transaction.
/// Coefficient can be adjusted, and there is an optional upper limit. /// Coefficient can be adjusted, and there is an optional upper limit.
/// ///
/// https://github.com/makerdao/pymaker/blob/master/pymaker/gas.py#L168 /// <https://github.com/makerdao/pymaker/blob/master/pymaker/gas.py#L168>
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct GeometricGasPrice { pub struct GeometricGasPrice {
every_secs: u64, every_secs: u64,

View File

@ -7,7 +7,7 @@ use ethers_core::types::U256;
/// Start with `initial_price`, then increase it by fixed amount `increase_by` every `every_secs` /// Start with `initial_price`, then increase it by fixed amount `increase_by` every `every_secs`
/// seconds until the transaction gets confirmed. There is an optional upper limit. /// seconds until the transaction gets confirmed. There is an optional upper limit.
/// ///
/// https://github.com/makerdao/pymaker/blob/master/pymaker/gas.py#L129 /// <https://github.com/makerdao/pymaker/blob/master/pymaker/gas.py#L129>
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LinearGasPrice { pub struct LinearGasPrice {
every_secs: u64, every_secs: u64,

View File

@ -1,4 +1,6 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![deny(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
/// The [Gas Escalator middleware](crate::gas_escalator::GasEscalatorMiddleware) /// The [Gas Escalator middleware](crate::gas_escalator::GasEscalatorMiddleware)
/// is used to re-broadcast transactions with an increasing gas price to guarantee /// is used to re-broadcast transactions with an increasing gas price to guarantee
@ -15,8 +17,9 @@ pub mod gas_oracle;
pub mod nonce_manager; pub mod nonce_manager;
pub use nonce_manager::NonceManagerMiddleware; pub use nonce_manager::NonceManagerMiddleware;
/// The [Transformer](crate::TransformerMiddleware) is used to intercept transactions and transform /// The [Transformer](crate::transformer::TransformerMiddleware) is used to intercept transactions
/// them to be sent via various supported transformers, e.g., [DSProxy](crate::transformer::DsProxy) /// and transform them to be sent via various supported transformers, e.g.,
/// [DSProxy](crate::transformer::DsProxy)
pub mod transformer; pub mod transformer;
/// The [Signer](crate::SignerMiddleware) is used to locally sign transactions and messages /// The [Signer](crate::SignerMiddleware) is used to locally sign transactions and messages

View File

@ -21,11 +21,9 @@ pub enum TransformerError {
AbiError(#[from] AbiError), AbiError(#[from] AbiError),
} }
/// `Transformer` is a trait to be implemented by a proxy wallet, eg. [`DSProxy`], that intends to /// `Transformer` is a trait to be implemented by a proxy wallet, eg. [`DsProxy`], that intends to
/// intercept a transaction request and transform it into one that is instead sent via the proxy /// intercept a transaction request and transform it into one that is instead sent via the proxy
/// contract. /// contract.
///
/// [`DSProxy`]: struct@crate::ds_proxy::DsProxy
pub trait Transformer: Send + Sync + std::fmt::Debug { pub trait Transformer: Send + Sync + std::fmt::Debug {
/// Transforms a [`transaction request`] into one that can be broadcasted and execute via the /// Transforms a [`transaction request`] into one that can be broadcasted and execute via the
/// proxy contract. /// proxy contract.

View File

@ -31,7 +31,7 @@ base64 = "0.13"
futures-core = { version = "0.3.16", default-features = false } futures-core = { version = "0.3.16", default-features = false }
futures-util = { version = "^0.3" } futures-util = { version = "^0.3" }
futures-timer = { version = "3.0.2", default-features = false } futures-timer = { version = "3.0.2", default-features = false }
futures-channel = { version = "0.3.16", default-features = false } futures-channel = { version = "0.3.16", default-features = false, optional = true }
pin-project = { version = "1.0.7", default-features = false } pin-project = { version = "1.0.7", default-features = false }
# tracing # tracing
@ -63,8 +63,8 @@ tempfile = "3.3.0"
[features] [features]
default = ["ws", "rustls"] default = ["ws", "rustls"]
celo = ["ethers-core/celo"] celo = ["ethers-core/celo"]
ws = ["tokio", "tokio-tungstenite"] ws = ["tokio", "tokio-tungstenite", "futures-channel"]
ipc = ["tokio", "tokio/io-util", "tokio-util", "bytes"] ipc = ["tokio", "tokio/io-util", "tokio-util", "bytes", "futures-channel"]
openssl = ["tokio-tungstenite/native-tls", "reqwest/native-tls"] openssl = ["tokio-tungstenite/native-tls", "reqwest/native-tls"]
# we use the webpki roots so we can build static binaries w/o any root cert dependencies # we use the webpki roots so we can build static binaries w/o any root cert dependencies

View File

@ -1,5 +1,5 @@
//! [Ethereum Name Service](https://docs.ens.domains/) support //! [Ethereum Name Service](https://docs.ens.domains/) support
//! Adapted from https://github.com/hhatto/rust-ens/blob/master/src/lib.rs //! Adapted from <https://github.com/hhatto/rust-ens/blob/master/src/lib.rs>
use ethers_core::{ use ethers_core::{
types::{Address, NameOrAddress, Selector, TransactionRequest, H160, H256}, types::{Address, NameOrAddress, Selector, TransactionRequest, H160, H256},
utils::keccak256, utils::keccak256,

View File

@ -1,5 +1,6 @@
#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(broken_intra_doc_links)] #![deny(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
#![allow(clippy::type_complexity)] #![allow(clippy::type_complexity)]
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
mod transports; mod transports;

View File

@ -754,7 +754,7 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
} }
/// Returns the EIP-1186 proof response /// Returns the EIP-1186 proof response
/// https://github.com/ethereum/EIPs/issues/1186 /// <https://github.com/ethereum/EIPs/issues/1186>
async fn get_proof<T: Into<NameOrAddress> + Send + Sync>( async fn get_proof<T: Into<NameOrAddress> + Send + Sync>(
&self, &self,
from: T, from: T,

View File

@ -314,8 +314,7 @@ impl From<IpcError> for ProviderError {
ProviderError::JsonRpcClientError(Box::new(src)) ProviderError::JsonRpcClientError(Box::new(src))
} }
} }
#[cfg(all(test, target_family = "unix"))]
#[cfg(all(test, unix))]
#[cfg(not(feature = "celo"))] #[cfg(not(feature = "celo"))]
mod test { mod test {
use super::*; use super::*;

View File

@ -25,21 +25,20 @@ elliptic-curve = { version = "0.11.12", default-features = false }
sha2 = { version = "0.9.8", default-features = false } sha2 = { version = "0.9.8", default-features = false }
rand = { version = "0.8.5", default-features = false } rand = { version = "0.8.5", default-features = false }
yubihsm = { version = "0.40.0", features = ["secp256k1", "http", "usb"], optional = true } yubihsm = { version = "0.40.0", features = ["secp256k1", "http", "usb"], optional = true }
futures-util = "^0.3" futures-util = { version = "^0.3", optional = true }
futures-executor = "^0.3" futures-executor = { version = "^0.3", optional = true }
semver = "1.0.6" semver = { version = "1.0.6", optional = true }
trezor-client = { version = "0.0.5", optional = true, default-features = false, features = ["f_ethereum"] } trezor-client = { version = "0.0.5", optional = true, default-features = false, features = ["f_ethereum"] }
# aws # aws
rusoto_core = { version = "0.47.0", optional = true } rusoto_core = { version = "0.47.0", optional = true }
rusoto_kms = { version = "0.47.0", optional = true } rusoto_kms = { version = "0.47.0", optional = true }
tracing = { version = "0.1.32", optional = true } tracing = { version = "0.1.32", optional = true }
tracing-futures = { version = "0.2.5", optional = true }
spki = { version = "0.5.4", optional = true } spki = { version = "0.5.4", optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
eth-keystore = { version = "0.4.1" } eth-keystore = { version = "0.4.1" }
home = "0.5.3" home = { version = "0.5.3", optional = true }
[dev-dependencies] [dev-dependencies]
ethers-contract = { version = "^0.6.0", path = "../ethers-contract", features = ["eip712", "abigen"]} ethers-contract = { version = "^0.6.0", path = "../ethers-contract", features = ["eip712", "abigen"]}
@ -54,8 +53,9 @@ tokio = { version = "1.5", default-features = false, features = ["macros", "rt"]
tempfile = "3.3.0" tempfile = "3.3.0"
[features] [features]
futures = ["futures-util", "futures-executor"]
celo = ["ethers-core/celo"] celo = ["ethers-core/celo"]
ledger = ["coins-ledger"] ledger = ["coins-ledger", "futures", "semver"]
yubi = ["yubihsm"] yubi = ["yubihsm"]
aws = ["rusoto_core", "rusoto_kms", "tracing", "tracing-futures", "spki"] aws = ["rusoto_core", "rusoto_kms", "tracing", "spki"]
trezor = ["trezor-client"] trezor = ["trezor-client", "futures", "semver", "home"]

View File

@ -1,4 +1,7 @@
//! Provides a unified interface for locally signing transactions. //! Provides a unified interface for locally signing transactions.
#![deny(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
mod wallet; mod wallet;
pub use wallet::{MnemonicBuilder, Wallet, WalletError}; pub use wallet::{MnemonicBuilder, Wallet, WalletError};

View File

@ -33,7 +33,7 @@ num_cpus = "1.13.1"
tiny-keccak = { version = "2.0.2", default-features = false } tiny-keccak = { version = "2.0.2", default-features = false }
tempfile = { version = "3.3.0", optional = true } tempfile = { version = "3.3.0", optional = true }
fs_extra = { version = "1.2.0", optional = true } fs_extra = { version = "1.2.0", optional = true }
sha2 = { version = "0.9.8", default-features = false } sha2 = { version = "0.9.8", default-features = false, optional = true }
dunce = "1.0.2" dunce = "1.0.2"
solang-parser = { default-features = false, version = "0.1.10" } solang-parser = { default-features = false, version = "0.1.10" }
rayon = "1.5.1" rayon = "1.5.1"

View File

@ -20,7 +20,7 @@ use std::{borrow::Cow, collections::BTreeMap, fs, path::Path};
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ConfigurableContractArtifact { pub struct ConfigurableContractArtifact {
/// The Ethereum Contract ABI. If empty, it is represented as an empty /// The Ethereum Contract ABI. If empty, it is represented as an empty
/// array. See https://docs.soliditylang.org/en/develop/abi-spec.html /// array. See <https://docs.soliditylang.org/en/develop/abi-spec.html>
pub abi: Option<LosslessAbi>, pub abi: Option<LosslessAbi>,
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub bytecode: Option<CompactBytecode>, pub bytecode: Option<CompactBytecode>,

View File

@ -421,7 +421,7 @@ where
/// this includes artifact file location and naming. /// this includes artifact file location and naming.
/// ///
/// Depending on the [`crate::Project`] contracts and their compatible versions, /// Depending on the [`crate::Project`] contracts and their compatible versions,
/// [`crate::ProjectCompiler::compile()`] may invoke different `solc` executables on the same /// The project compiler may invoke different `solc` executables on the same
/// solidity file leading to multiple [`crate::CompilerOutput`]s for the same `.sol` file. /// solidity file leading to multiple [`crate::CompilerOutput`]s for the same `.sol` file.
/// In addition to the `solidity file` to `contract` relationship (1-N*) /// In addition to the `solidity file` to `contract` relationship (1-N*)
/// [`crate::VersionedContracts`] also tracks the `contract` to (`artifact` + `solc version`) /// [`crate::VersionedContracts`] also tracks the `contract` to (`artifact` + `solc version`)
@ -456,11 +456,11 @@ pub trait ArtifactOutput {
/// Writes additional files for the contracts if the included in the `Contract`, such as `ir`, /// Writes additional files for the contracts if the included in the `Contract`, such as `ir`,
/// `ewasm`, `iropt`. /// `ewasm`, `iropt`.
/// ///
/// By default, these fields are _not_ enabled in the [`crate::Settings`], see /// By default, these fields are _not_ enabled in the [`crate::artifacts::Settings`], see
/// [`crate::Settings::default_output_selection()`], and the respective fields of the /// [`crate::artifacts::output_selection::OutputSelection::default_output_selection()`], and the
/// [`Contract`] will `None`. If they'll be manually added to the `output_selection`, then /// respective fields of the [`Contract`] will `None`. If they'll be manually added to the
/// we're also creating individual files for this output, such as `Greeter.iropt`, /// `output_selection`, then we're also creating individual files for this output, such as
/// `Gretter.ewasm` /// `Greeter.iropt`, `Gretter.ewasm`
fn write_extras( fn write_extras(
&self, &self,
contracts: &VersionedContracts, contracts: &VersionedContracts,

View File

@ -117,7 +117,7 @@ impl From<BytecodeObject> for Bytecode {
impl Bytecode { impl Bytecode {
/// Returns the parsed source map /// Returns the parsed source map
/// ///
/// See also https://docs.soliditylang.org/en/v0.8.10/internals/source_mappings.html /// See also <https://docs.soliditylang.org/en/v0.8.10/internals/source_mappings.html>
pub fn source_map(&self) -> Option<Result<SourceMap, SyntaxError>> { pub fn source_map(&self) -> Option<Result<SourceMap, SyntaxError>> {
self.source_map.as_ref().map(|map| sourcemap::parse(map)) self.source_map.as_ref().map(|map| sourcemap::parse(map))
} }
@ -279,7 +279,7 @@ impl BytecodeObject {
/// ///
/// This will replace all occurrences of the library placeholder with the given address. /// This will replace all occurrences of the library placeholder with the given address.
/// ///
/// See also: https://docs.soliditylang.org/en/develop/using-the-compiler.html#library-linking /// See also: <https://docs.soliditylang.org/en/develop/using-the-compiler.html#library-linking>
pub fn link_fully_qualified(&mut self, name: impl AsRef<str>, addr: Address) -> &mut Self { pub fn link_fully_qualified(&mut self, name: impl AsRef<str>, addr: Address) -> &mut Self {
if let BytecodeObject::Unlinked(ref mut unlinked) = self { if let BytecodeObject::Unlinked(ref mut unlinked) = self {
let name = name.as_ref(); let name = name.as_ref();

View File

@ -15,7 +15,7 @@ use std::{borrow::Cow, collections::BTreeMap, convert::TryFrom};
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Contract { pub struct Contract {
/// The Ethereum Contract Metadata. /// The Ethereum Contract Metadata.
/// See https://docs.soliditylang.org/en/develop/metadata.html /// See <https://docs.soliditylang.org/en/develop/metadata.html>
pub abi: Option<LosslessAbi>, pub abi: Option<LosslessAbi>,
#[serde( #[serde(
default, default,
@ -66,7 +66,7 @@ impl<'a> From<&'a Contract> for CompactContractBytecodeCow<'a> {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ContractBytecode { pub struct ContractBytecode {
/// The Ethereum Contract ABI. If empty, it is represented as an empty /// The Ethereum Contract ABI. If empty, it is represented as an empty
/// array. See https://docs.soliditylang.org/en/develop/abi-spec.html /// array. See <https://docs.soliditylang.org/en/develop/abi-spec.html>
pub abi: Option<Abi>, pub abi: Option<Abi>,
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub bytecode: Option<Bytecode>, pub bytecode: Option<Bytecode>,
@ -136,7 +136,7 @@ impl From<Contract> for ContractBytecode {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct CompactContractBytecode { pub struct CompactContractBytecode {
/// The Ethereum Contract ABI. If empty, it is represented as an empty /// The Ethereum Contract ABI. If empty, it is represented as an empty
/// array. See https://docs.soliditylang.org/en/develop/abi-spec.html /// array. See <https://docs.soliditylang.org/en/develop/abi-spec.html>
pub abi: Option<Abi>, pub abi: Option<Abi>,
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub bytecode: Option<CompactBytecode>, pub bytecode: Option<CompactBytecode>,
@ -245,7 +245,7 @@ impl TryFrom<ContractBytecode> for ContractBytecodeSome {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct CompactContractSome { pub struct CompactContractSome {
/// The Ethereum Contract ABI. If empty, it is represented as an empty /// The Ethereum Contract ABI. If empty, it is represented as an empty
/// array. See https://docs.soliditylang.org/en/develop/abi-spec.html /// array. See <https://docs.soliditylang.org/en/develop/abi-spec.html>
pub abi: Abi, pub abi: Abi,
pub bin: BytecodeObject, pub bin: BytecodeObject,
#[serde(rename = "bin-runtime")] #[serde(rename = "bin-runtime")]
@ -269,7 +269,7 @@ impl TryFrom<CompactContract> for CompactContractSome {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct CompactContract { pub struct CompactContract {
/// The Ethereum Contract ABI. If empty, it is represented as an empty /// The Ethereum Contract ABI. If empty, it is represented as an empty
/// array. See https://docs.soliditylang.org/en/develop/abi-spec.html /// array. See <https://docs.soliditylang.org/en/develop/abi-spec.html>
pub abi: Option<Abi>, pub abi: Option<Abi>,
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub bin: Option<BytecodeObject>, pub bin: Option<BytecodeObject>,

View File

@ -60,7 +60,7 @@ impl CompilerInput {
Source::read_all_from(path.as_ref()).map(Self::with_sources) Source::read_all_from(path.as_ref()).map(Self::with_sources)
} }
/// Creates a new [CompilerInput](s) with default settings and the given sources /// Creates a new [CompilerInput]s with default settings and the given sources
/// ///
/// A [CompilerInput] expects a language setting, supported by solc are solidity or yul. /// A [CompilerInput] expects a language setting, supported by solc are solidity or yul.
/// In case the `sources` is a mix of solidity and yul files, 2 CompilerInputs are returned /// In case the `sources` is a mix of solidity and yul files, 2 CompilerInputs are returned
@ -806,14 +806,14 @@ impl OutputContracts {
} }
} }
/// A helper type that ensures lossless (de)serialisation unlike [`ethabi::Contract`] which omits /// A helper type that ensures lossless (de)serialisation unlike [`ethers_core::abi::Abi`] which
/// some information of (nested) components in a serde roundtrip. This is a problem for /// omits some information of (nested) components in a serde roundtrip. This is a problem for
/// abienconderv2 structs because `ethabi::Contract`'s representation of those are [`ethabi::Param`] /// abienconderv2 structs because [`ethers_core::abi::Contract`]'s representation of those are
/// and the `kind` field of type [`ethabi::ParamType`] does not support deeply nested components as /// [`ethers_core::abi::Param`] and the `kind` field of type [`ethers_core::abi::ParamType`] does
/// it's the case for structs. This is not easily fixable in ethabi as it would require a redesign /// not support deeply nested components as it's the case for structs. This is not easily fixable in
/// of the overall `Param` and `ParamType` types. Instead, this type keeps a copy of the /// ethabi as it would require a redesign of the overall `Param` and `ParamType` types. Instead,
/// [`serde_json::Value`] when deserialized from the `solc` json compiler output and uses it to /// this type keeps a copy of the [`serde_json::Value`] when deserialized from the `solc` json
/// serialize the `abi` without loss. /// compiler output and uses it to serialize the `abi` without loss.
#[derive(Clone, Debug, PartialEq, Default)] #[derive(Clone, Debug, PartialEq, Default)]
pub struct LosslessAbi { pub struct LosslessAbi {
/// The complete abi as json value /// The complete abi as json value
@ -1243,7 +1243,7 @@ mod tests {
#[test] #[test]
fn can_link_bytecode() { fn can_link_bytecode() {
// test cases taken from https://github.com/ethereum/solc-js/blob/master/test/linker.js // test cases taken from <https://github.com/ethereum/solc-js/blob/master/test/linker.js>
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct Mockject { struct Mockject {

View File

@ -364,7 +364,7 @@ pub struct CacheEntry {
pub last_modification_date: u64, pub last_modification_date: u64,
/// hash to identify whether the content of the file changed /// hash to identify whether the content of the file changed
pub content_hash: String, pub content_hash: String,
/// identifier name see [`crate::util::source_name()`] /// identifier name see [`crate::utils::source_name()`]
pub source_name: PathBuf, pub source_name: PathBuf,
/// what config was set when compiling this file /// what config was set when compiling this file
pub solc_config: SolcConfig, pub solc_config: SolcConfig,

View File

@ -23,23 +23,23 @@ pub mod project;
pub const SOLC: &str = "solc"; pub const SOLC: &str = "solc";
/// Support for configuring the EVM version /// Support for configuring the EVM version
/// https://blog.soliditylang.org/2018/03/08/solidity-0.4.21-release-announcement/ /// <https://blog.soliditylang.org/2018/03/08/solidity-0.4.21-release-announcement/>
pub const CONSTANTINOPLE_SOLC: Version = Version::new(0, 4, 21); pub const CONSTANTINOPLE_SOLC: Version = Version::new(0, 4, 21);
/// Petersburg support /// Petersburg support
/// https://blog.soliditylang.org/2019/03/05/solidity-0.5.5-release-announcement/ /// <https://blog.soliditylang.org/2019/03/05/solidity-0.5.5-release-announcement/>
pub const PETERSBURG_SOLC: Version = Version::new(0, 5, 5); pub const PETERSBURG_SOLC: Version = Version::new(0, 5, 5);
/// Istanbul support /// Istanbul support
/// https://blog.soliditylang.org/2019/12/09/solidity-0.5.14-release-announcement/ /// <https://blog.soliditylang.org/2019/12/09/solidity-0.5.14-release-announcement/>
pub const ISTANBUL_SOLC: Version = Version::new(0, 5, 14); pub const ISTANBUL_SOLC: Version = Version::new(0, 5, 14);
/// Berlin support /// Berlin support
/// https://blog.soliditylang.org/2021/06/10/solidity-0.8.5-release-announcement/ /// <https://blog.soliditylang.org/2021/06/10/solidity-0.8.5-release-announcement/>
pub const BERLIN_SOLC: Version = Version::new(0, 8, 5); pub const BERLIN_SOLC: Version = Version::new(0, 8, 5);
/// London support /// London support
/// https://blog.soliditylang.org/2021/08/11/solidity-0.8.7-release-announcement/ /// <https://blog.soliditylang.org/2021/08/11/solidity-0.8.7-release-announcement/>
pub const LONDON_SOLC: Version = Version::new(0, 8, 7); pub const LONDON_SOLC: Version = Version::new(0, 8, 7);
#[cfg(any(test, feature = "tests"))] #[cfg(any(test, feature = "tests"))]

View File

@ -16,8 +16,6 @@ use std::{collections::BTreeMap, fmt, path::Path};
#[derive(Debug, Clone, PartialEq, Default)] #[derive(Debug, Clone, PartialEq, Default)]
pub struct ProjectCompileOutput<T: ArtifactOutput = ConfigurableArtifacts> { pub struct ProjectCompileOutput<T: ArtifactOutput = ConfigurableArtifacts> {
/// contains the aggregated `CompilerOutput` /// contains the aggregated `CompilerOutput`
///
/// See [`CompilerSources::compile`]
pub(crate) compiler_output: AggregatedCompilerOutput, pub(crate) compiler_output: AggregatedCompilerOutput,
/// all artifact files from `output` that were freshly compiled and written /// all artifact files from `output` that were freshly compiled and written
pub(crate) compiled_artifacts: Artifacts<T::Artifact>, pub(crate) compiled_artifacts: Artifacts<T::Artifact>,
@ -134,18 +132,21 @@ impl<T: ArtifactOutput> ProjectCompileOutput<T> {
self.cached_artifacts.remove(contract_name) self.cached_artifacts.remove(contract_name)
} }
/// Returns the set of `Artifacts` that were cached and got reused during [`Project::compile()`] /// Returns the set of `Artifacts` that were cached and got reused during
/// [`crate::Project::compile()`]
pub fn cached_artifacts(&self) -> &Artifacts<T::Artifact> { pub fn cached_artifacts(&self) -> &Artifacts<T::Artifact> {
&self.cached_artifacts &self.cached_artifacts
} }
/// Returns the set of `Artifacts` that were compiled with `solc` in [`Project::compile()`] /// Returns the set of `Artifacts` that were compiled with `solc` in
/// [`crate::Project::compile()`]
pub fn compiled_artifacts(&self) -> &Artifacts<T::Artifact> { pub fn compiled_artifacts(&self) -> &Artifacts<T::Artifact> {
&self.compiled_artifacts &self.compiled_artifacts
} }
/// Returns a `BTreeMap` that maps the compiler version used during [`Project::compile()`] /// Returns a `BTreeMap` that maps the compiler version used during
/// to a Vector of tuples containing the contract name and the `Contract` /// [`crate::Project::compile()`] to a Vector of tuples containing the contract name and the
/// `Contract`
pub fn compiled_contracts_by_compiler_version( pub fn compiled_contracts_by_compiler_version(
&self, &self,
) -> BTreeMap<Version, Vec<(String, Contract)>> { ) -> BTreeMap<Version, Vec<(String, Contract)>> {
@ -177,7 +178,7 @@ where
impl ProjectCompileOutput<ConfigurableArtifacts> { impl ProjectCompileOutput<ConfigurableArtifacts> {
/// A helper functions that extracts the underlying [`CompactContractBytecode`] from the /// A helper functions that extracts the underlying [`CompactContractBytecode`] from the
/// [`ConfigurableContractArtifact`] /// [`crate::ConfigurableContractArtifact`]
/// ///
/// # Example /// # Example
/// ///

View File

@ -5,13 +5,13 @@
//! First the project's dependency graph [`crate::Graph`] is constructed and all imported //! First the project's dependency graph [`crate::Graph`] is constructed and all imported
//! dependencies are resolved. The graph holds all the relationships between the files and their //! dependencies are resolved. The graph holds all the relationships between the files and their
//! versions. From there the appropriate version set is derived //! versions. From there the appropriate version set is derived
//! [`crate::Graph::into_sources_by_version()`] which need to be compiled with different //! [`crate::Graph`] which need to be compiled with different
//! [`crate::Solc`] versions. //! [`crate::Solc`] versions.
//! //!
//! At this point we check if we need to compile a source file or whether we can reuse an _existing_ //! At this point we check if we need to compile a source file or whether we can reuse an _existing_
//! `Artifact`. We don't to compile if: //! `Artifact`. We don't to compile if:
//! - caching is enabled //! - caching is enabled
//! - the file is **not** dirty [`Cache::is_dirty()`] //! - the file is **not** dirty
//! - the artifact for that file exists //! - the artifact for that file exists
//! //!
//! This concludes the preprocessing, and we now have either //! This concludes the preprocessing, and we now have either
@ -58,7 +58,7 @@
//! import "/project/lib/util.sol"; // source unit name: /project/lib/util.sol //! import "/project/lib/util.sol"; // source unit name: /project/lib/util.sol
//! import "lib/util.sol"; // source unit name: lib/util.sol //! import "lib/util.sol"; // source unit name: lib/util.sol
//! import "@openzeppelin/address.sol"; // source unit name: @openzeppelin/address.sol //! import "@openzeppelin/address.sol"; // source unit name: @openzeppelin/address.sol
//! import "https://example.com/token.sol"; // source unit name: https://example.com/token.sol //! import "https://example.com/token.sol"; // source unit name: <https://example.com/token.sol>
//! ``` //! ```
//! //!
//! After applying any import remappings the import path simply becomes the source unit name. //! After applying any import remappings the import path simply becomes the source unit name.
@ -78,11 +78,11 @@
//! ### Caching and Change detection //! ### Caching and Change detection
//! //!
//! If caching is enabled in the [Project](crate::Project) a cache file will be created upon a //! If caching is enabled in the [Project](crate::Project) a cache file will be created upon a
//! successful solc build. The [cache file](crate::SolFilesCache) stores metadata for all the files //! successful solc build. The [cache file](crate::cache::SolFilesCache) stores metadata for all the
//! that were provided to solc. //! files that were provided to solc.
//! For every file the cache file contains a dedicated [cache //! For every file the cache file contains a dedicated [cache
//! entry](crate::CacheEntry), which represents the state of the file. A solidity file can contain //! entry](crate::cache::CacheEntry), which represents the state of the file. A solidity file can
//! several contracts, for every contract a separate [artifact](crate::Artifact) is emitted. //! contain several contracts, for every contract a separate [artifact](crate::Artifact) is emitted.
//! Therefor the entry also tracks all artifacts emitted by a file. A solidity file can also be //! Therefor the entry also tracks all artifacts emitted by a file. A solidity file can also be
//! compiled with several solc versions. //! compiled with several solc versions.
//! //!
@ -124,7 +124,7 @@ pub struct ProjectCompiler<'a, T: ArtifactOutput> {
project: &'a Project<T>, project: &'a Project<T>,
/// how to compile all the sources /// how to compile all the sources
sources: CompilerSources, sources: CompilerSources,
/// How to select solc [CompilerOutput] for files /// How to select solc [`crate::artifacts::CompilerOutput`] for files
sparse_output: SparseOutputFileFilter, sparse_output: SparseOutputFileFilter,
} }
@ -182,7 +182,7 @@ impl<'a, T: ArtifactOutput> ProjectCompiler<'a, T> {
Ok(Self { edges, project, sources, sparse_output: Default::default() }) Ok(Self { edges, project, sources, sparse_output: Default::default() })
} }
/// Applies the specified [SparseOutputFileFilter] to be applied when selecting solc output for /// Applies the specified filter to be applied when selecting solc output for
/// specific files to be compiled /// specific files to be compiled
pub fn with_sparse_output(mut self, sparse_output: impl Into<SparseOutputFileFilter>) -> Self { pub fn with_sparse_output(mut self, sparse_output: impl Into<SparseOutputFileFilter>) -> Self {
self.sparse_output = sparse_output.into(); self.sparse_output = sparse_output.into();

View File

@ -167,12 +167,13 @@ impl ProjectPathsConfig {
/// ///
/// `import "@openzeppelin/token/ERC20/IERC20.sol";` /// `import "@openzeppelin/token/ERC20/IERC20.sol";`
/// ///
/// There is no strict rule behind this, but because [`Remappings::find_many`] returns /// There is no strict rule behind this, but because [`crate::remappings::Remapping::find_many`]
/// `'@openzeppelin/=node_modules/@openzeppelin/contracts/'` we should handle the case if the /// returns `'@openzeppelin/=node_modules/@openzeppelin/contracts/'` we should handle the
/// remapping path ends with `contracts` and the import path starts with `<remapping /// case if the remapping path ends with `contracts` and the import path starts with
/// name>/contracts`. Otherwise we can end up with a resolved path that has a duplicate /// `<remapping name>/contracts`. Otherwise we can end up with a resolved path that has a
/// `contracts` segment: `@openzeppelin/contracts/contracts/token/ERC20/IERC20.sol` we check /// duplicate `contracts` segment:
/// for this edge case here so that both styles work out of the box. /// `@openzeppelin/contracts/contracts/token/ERC20/IERC20.sol` we check for this edge case
/// here so that both styles work out of the box.
pub fn resolve_library_import(&self, import: &Path) -> Option<PathBuf> { pub fn resolve_library_import(&self, import: &Path) -> Option<PathBuf> {
// if the import path starts with the name of the remapping then we get the resolved path by // if the import path starts with the name of the remapping then we get the resolved path by
// removing the name and adding the remainder to the path of the remapping // removing the name and adding the remainder to the path of the remapping

View File

@ -26,7 +26,7 @@ where
} }
} }
/// An [InputFileFilter] that matches all solidity files that end with `.t.sol` /// An [FileFilter] that matches all solidity files that end with `.t.sol`
#[derive(Default)] #[derive(Default)]
pub struct TestFileFilter { pub struct TestFileFilter {
_priv: (), _priv: (),

View File

@ -1,3 +1,4 @@
#![deny(rustdoc::broken_intra_doc_links)]
pub mod artifacts; pub mod artifacts;
pub mod sourcemap; pub mod sourcemap;
@ -192,7 +193,7 @@ impl<T: ArtifactOutput> Project<T> {
/// `CompilerOutput::has_error` instead. /// `CompilerOutput::has_error` instead.
/// ///
/// NB: If the `svm` feature is enabled, this function will automatically detect /// NB: If the `svm` feature is enabled, this function will automatically detect
/// solc versions across files, see [`Self::svm_compile()`] /// solc versions across files.
/// ///
/// # Example /// # Example
/// ///

View File

@ -679,7 +679,7 @@ mod tests {
assert_eq!(err, RemappingError::NoTarget); assert_eq!(err, RemappingError::NoTarget);
} }
// https://doc.rust-lang.org/rust-by-example/std_misc/fs.html // <https://doc.rust-lang.org/rust-by-example/std_misc/fs.html>
fn touch(path: &std::path::Path) -> std::io::Result<()> { fn touch(path: &std::path::Path) -> std::io::Result<()> {
match std::fs::OpenOptions::new().create(true).write(true).open(path) { match std::fs::OpenOptions::new().create(true).write(true).open(path) {
Ok(_) => Ok(()), Ok(_) => Ok(()),

View File

@ -8,8 +8,8 @@
use crate::{CompilerInput, CompilerOutput}; use crate::{CompilerInput, CompilerOutput};
use std::{env, path::PathBuf, str::FromStr}; use std::{env, path::PathBuf, str::FromStr};
/// Debug Helper type that can be used to write the [Solc] [CompilerInput] and [CompilerOutput] to /// Debug Helper type that can be used to write the [crate::Solc] [CompilerInput] and
/// disk if configured. /// [CompilerOutput] to disk if configured.
/// ///
/// # Example /// # Example
/// ///

View File

@ -1,18 +1,18 @@
//! Subscribe to events in the compiler pipeline //! Subscribe to events in the compiler pipeline
//! //!
//! The _reporter_ is the component of the [`Project::compile()`] pipeline which is responsible //! The _reporter_ is the component of the [`crate::Project::compile()`] pipeline which is
//! for reporting on specific steps in the process. //! responsible for reporting on specific steps in the process.
//! //!
//! By default, the current reporter is a noop that does //! By default, the current reporter is a noop that does
//! nothing. //! nothing.
//! //!
//! To use another report implementation, it must be set as the current reporter. //! To use another report implementation, it must be set as the current reporter.
//! There are two methods for doing so: [`with_scoped`] and //! There are two methods for doing so: [`with_scoped`] and
//! [`set_global`]. `with_scoped` sets the reporter for the //! [`try_init`]. `with_scoped` sets the reporter for the
//! duration of a scope, while `set_global` sets a global default report //! duration of a scope, while `set_global` sets a global default report
//! for the entire process. //! for the entire process.
// https://github.com/tokio-rs/tracing/blob/master/tracing-core/src/dispatch.rs // <https://github.com/tokio-rs/tracing/blob/master/tracing-core/src/dispatch.rs>
use crate::{remappings::Remapping, CompilerInput, CompilerOutput, Solc}; use crate::{remappings::Remapping, CompilerInput, CompilerOutput, Solc};
use semver::Version; use semver::Version;
@ -103,8 +103,8 @@ pub trait Reporter: 'static {
/// contains the files that absolutely must be recompiled, while the [CompilerInput] contains /// contains the files that absolutely must be recompiled, while the [CompilerInput] contains
/// all files, the dirty files and all their dependencies. /// all files, the dirty files and all their dependencies.
/// ///
/// If this is a fresh compile then the [Sources] set of the [CompilerInput] matches the dirty /// If this is a fresh compile then the [crate::artifacts::Sources] set of the [CompilerInput]
/// files set. /// matches the dirty files set.
fn on_solc_spawn( fn on_solc_spawn(
&self, &self,
_solc: &Solc, _solc: &Solc,
@ -114,7 +114,7 @@ pub trait Reporter: 'static {
) { ) {
} }
/// Invoked with the `CompilerOutput` if [`Solc::compiled()`] was successful /// Invoked with the `CompilerOutput` if [`Solc::compile()`] was successful
fn on_solc_success(&self, _solc: &Solc, _version: &Version, _output: &CompilerOutput) {} fn on_solc_success(&self, _solc: &Solc, _version: &Version, _output: &CompilerOutput) {}
/// Invoked before a new [`Solc`] bin is installed /// Invoked before a new [`Solc`] bin is installed
@ -133,17 +133,17 @@ pub trait Reporter: 'static {
/// [`NonNull`] pointer to that type. Otherwise, returns `None`. /// [`NonNull`] pointer to that type. Otherwise, returns `None`.
/// ///
/// If you wish to downcast a `Reporter`, it is strongly advised to use /// If you wish to downcast a `Reporter`, it is strongly advised to use
/// the safe API provided by [`downcast_ref`] instead. /// the safe API provided by downcast_ref instead.
/// ///
/// This API is required for `downcast_raw` to be a trait method; a method /// This API is required for `downcast_raw` to be a trait method; a method
/// signature like [`downcast_ref`] (with a generic type parameter) is not /// signature like downcast_ref (with a generic type parameter) is not
/// object-safe, and thus cannot be a trait method for `Reporter`. This /// object-safe, and thus cannot be a trait method for `Reporter`. This
/// means that if we only exposed `downcast_ref`, `Reporter` /// means that if we only exposed downcast_ref, `Reporter`
/// implementations could not override the downcasting behavior /// implementations could not override the downcasting behavior
/// ///
/// # Safety /// # Safety
/// ///
/// The [`downcast_ref`] method expects that the pointer returned by /// The downcast_ref method expects that the pointer returned by
/// `downcast_raw` points to a valid instance of the type /// `downcast_raw` points to a valid instance of the type
/// with the provided `TypeId`. Failure to ensure this will result in /// with the provided `TypeId`. Failure to ensure this will result in
/// undefined behaviour, so implementing `downcast_raw` is unsafe. /// undefined behaviour, so implementing `downcast_raw` is unsafe.
@ -217,7 +217,7 @@ fn get_global() -> Option<&'static Report> {
} }
} }
/// Executes a closure with a reference to this thread's current [reporter]. /// Executes a closure with a reference to this thread's current reporter.
#[inline(always)] #[inline(always)]
pub fn get_default<T, F>(mut f: F) -> T pub fn get_default<T, F>(mut f: F) -> T
where where

View File

@ -156,7 +156,7 @@ impl GraphEdges {
/// Represents a fully-resolved solidity dependency graph. Each node in the graph /// Represents a fully-resolved solidity dependency graph. Each node in the graph
/// is a file and edges represent dependencies between them. /// is a file and edges represent dependencies between them.
/// See also https://docs.soliditylang.org/en/latest/layout-of-source-files.html?highlight=import#importing-other-source-files /// See also <https://docs.soliditylang.org/en/latest/layout-of-source-files.html?highlight=import#importing-other-source-files>
#[derive(Debug)] #[derive(Debug)]
pub struct Graph { pub struct Graph {
nodes: Vec<Node>, nodes: Vec<Node>,

View File

@ -142,7 +142,7 @@ impl<'a> fmt::Display for Jump {
/// Represents a whole source map as list of `SourceElement`s /// Represents a whole source map as list of `SourceElement`s
/// ///
/// See also https://docs.soliditylang.org/en/latest/internals/source_mappings.html#source-mappings /// See also <https://docs.soliditylang.org/en/latest/internals/source_mappings.html#source-mappings>
pub type SourceMap = Vec<SourceElement>; pub type SourceMap = Vec<SourceElement>;
/// Represents a single element in the source map /// Represents a single element in the source map

View File

@ -15,7 +15,7 @@ use walkdir::WalkDir;
/// A regex that matches the import path and identifier of a solidity import /// A regex that matches the import path and identifier of a solidity import
/// statement with the named groups "path", "id". /// statement with the named groups "path", "id".
// Adapted from https://github.com/nomiclabs/hardhat/blob/cced766c65b25d3d0beb39ef847246ac9618bdd9/packages/hardhat-core/src/internal/solidity/parse.ts#L100 // Adapted from <https://github.com/nomiclabs/hardhat/blob/cced766c65b25d3d0beb39ef847246ac9618bdd9/packages/hardhat-core/src/internal/solidity/parse.ts#L100>
pub static RE_SOL_IMPORT: Lazy<Regex> = Lazy::new(|| { pub static RE_SOL_IMPORT: Lazy<Regex> = Lazy::new(|| {
Regex::new(r#"import\s+(?:(?:"(?P<p1>[^;]*)"|'(?P<p2>[^;]*)')(?:;|\s+as\s+(?P<id>[^;]*);)|.+from\s+(?:"(?P<p3>.*)"|'(?P<p4>.*)');)"#).unwrap() Regex::new(r#"import\s+(?:(?:"(?P<p1>[^;]*)"|'(?P<p2>[^;]*)')(?:;|\s+as\s+(?P<id>[^;]*);)|.+from\s+(?:"(?P<p3>.*)"|'(?P<p4>.*)');)"#).unwrap()
}); });
@ -23,7 +23,7 @@ pub static RE_SOL_IMPORT: Lazy<Regex> = Lazy::new(|| {
/// A regex that matches the version part of a solidity pragma /// A regex that matches the version part of a solidity pragma
/// as follows: `pragma solidity ^0.5.2;` => `^0.5.2` /// as follows: `pragma solidity ^0.5.2;` => `^0.5.2`
/// statement with the named group "version". /// statement with the named group "version".
// Adapted from https://github.com/nomiclabs/hardhat/blob/cced766c65b25d3d0beb39ef847246ac9618bdd9/packages/hardhat-core/src/internal/solidity/parse.ts#L119 // Adapted from <https://github.com/nomiclabs/hardhat/blob/cced766c65b25d3d0beb39ef847246ac9618bdd9/packages/hardhat-core/src/internal/solidity/parse.ts#L119>
pub static RE_SOL_PRAGMA_VERSION: Lazy<Regex> = pub static RE_SOL_PRAGMA_VERSION: Lazy<Regex> =
Lazy::new(|| Regex::new(r"pragma\s+solidity\s+(?P<version>.+?);").unwrap()); Lazy::new(|| Regex::new(r"pragma\s+solidity\s+(?P<version>.+?);").unwrap());
@ -35,7 +35,7 @@ pub static RE_SOL_SDPX_LICENSE_IDENTIFIER: Lazy<Regex> =
/// Returns all path parts from any solidity import statement in a string, /// Returns all path parts from any solidity import statement in a string,
/// `import "./contracts/Contract.sol";` -> `"./contracts/Contract.sol"`. /// `import "./contracts/Contract.sol";` -> `"./contracts/Contract.sol"`.
/// ///
/// See also https://docs.soliditylang.org/en/v0.8.9/grammar.html /// See also <https://docs.soliditylang.org/en/v0.8.9/grammar.html>
pub fn find_import_paths(contract: &str) -> impl Iterator<Item = Match> { pub fn find_import_paths(contract: &str) -> impl Iterator<Item = Match> {
RE_SOL_IMPORT.captures_iter(contract).filter_map(|cap| { RE_SOL_IMPORT.captures_iter(contract).filter_map(|cap| {
cap.name("p1") cap.name("p1")
@ -216,7 +216,7 @@ pub fn library_hash_placeholder(name: impl AsRef<[u8]>) -> String {
/// The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully /// The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully
/// qualified library name. /// qualified library name.
/// ///
/// See also https://docs.soliditylang.org/en/develop/using-the-compiler.html#library-linking /// See also <https://docs.soliditylang.org/en/develop/using-the-compiler.html#library-linking>
pub fn library_hash(name: impl AsRef<[u8]>) -> [u8; 17] { pub fn library_hash(name: impl AsRef<[u8]>) -> [u8; 17] {
let mut output = [0u8; 17]; let mut output = [0u8; 17];
let mut hasher = Keccak::v256(); let mut hasher = Keccak::v256();

View File

@ -5,8 +5,8 @@ use ethers::{
}; };
// Generate the EIP712 permit hash to sign for a Uniswap V2 pair. // Generate the EIP712 permit hash to sign for a Uniswap V2 pair.
// https://eips.ethereum.org/EIPS/eip-712 // <https://eips.ethereum.org/EIPS/eip-712>
// https://eips.ethereum.org/EIPS/eip-2612 // <https://eips.ethereum.org/EIPS/eip-2612>
#[derive(Eip712, EthAbiType, Clone)] #[derive(Eip712, EthAbiType, Clone)]
#[eip712( #[eip712(
name = "Uniswap V2", name = "Uniswap V2",