From 279aea6323b824609aab7dc2963c3b6637c7fcc9 Mon Sep 17 00:00:00 2001 From: Andrey Kuznetsov Date: Sun, 18 Dec 2022 15:05:02 +0400 Subject: [PATCH 01/40] feat(contract): add_calls and call_array for multicall (#1941) --- CHANGELOG.md | 1 + ethers-contract/src/multicall/mod.rs | 60 ++++++++++++++++++++++++++++ ethers-contract/tests/it/contract.rs | 33 +++++++++++---- 3 files changed, 86 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1b26a77..7b157dc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ - [#842](https://github.com/gakonst/ethers-rs/issues/842) Add support for I256 types in `parse_units` and `format_units`. Added `twos_complement` function for I256. - [#1934](https://github.com/gakonst/ethers-rs/pull/1934) Allow 16 calls in multicall. +- [#1941](https://github.com/gakonst/ethers-rs/pull/1941) Add `add_calls` and `call_array` for `Multicall`. ## ethers-contract-abigen diff --git a/ethers-contract/src/multicall/mod.rs b/ethers-contract/src/multicall/mod.rs index 8dd24542..56dca427 100644 --- a/ethers-contract/src/multicall/mod.rs +++ b/ethers-contract/src/multicall/mod.rs @@ -437,6 +437,27 @@ impl Multicall { } } + /// Appends multiple `call`s to the list of calls of the Multicall instance. + /// + /// Version specific details: + /// - 1: `allow_failure` is ignored. + /// - >=2: `allow_failure` specifies whether or not this call is allowed to revert in the + /// multicall. + /// - 3: Transaction values are used when broadcasting transactions with [`send`], otherwise + /// they are always ignored. + /// + /// [`send`]: #method.send + pub fn add_calls( + &mut self, + allow_failure: bool, + calls: impl IntoIterator>, + ) -> &mut Self { + for call in calls { + self.add_call(call, allow_failure); + } + self + } + /// Appends a `call` to the list of calls of the Multicall instance for querying the block hash /// of a given block number. /// @@ -615,6 +636,45 @@ impl Multicall { Ok(data) } + /// Queries the Ethereum blockchain using `eth_call`, but via the Multicall contract, assuming + /// that every call returns same data type. + /// + /// Note: this method _does not_ send a transaction from your account. + /// + /// # Errors + /// + /// Returns a [`MulticallError`] if there are any errors in the RPC call or while detokenizing + /// the tokens back to the expected return type. + /// + /// # Examples + /// + /// The return type must be annotated while calling this method: + /// + /// ```no_run + /// # async fn foo() -> Result<(), Box> { + /// # use ethers_core::types::{U256, Address}; + /// # use ethers_providers::{Provider, Http}; + /// # use ethers_contract::Multicall; + /// # use std::convert::TryFrom; + /// # + /// # let client = Provider::::try_from("http://localhost:8545")?; + /// # + /// # let multicall = Multicall::new(client, None).await?; + /// // If the all Solidity function calls `returns (uint256)`: + /// let result: Vec = multicall.call().await?; + /// # Ok(()) + /// # } + /// ``` + pub async fn call_array(&self) -> Result, M> { + let tokens = self.call_raw().await?; + let res: std::result::Result, ContractError> = tokens + .into_iter() + .map(|token| D::from_tokens(vec![token]).map_err(ContractError::DetokenizationError)) + .collect(); + + Ok(res?) + } + /// Queries the Ethereum blockchain using `eth_call`, but via the Multicall contract and /// without detokenization. /// diff --git a/ethers-contract/tests/it/contract.rs b/ethers-contract/tests/it/contract.rs index e15005aa..8fdd0469 100644 --- a/ethers-contract/tests/it/contract.rs +++ b/ethers-contract/tests/it/contract.rs @@ -15,7 +15,7 @@ mod eth_tests { use ethers_derive_eip712::*; use ethers_providers::{Http, Middleware, PendingTransaction, Provider, StreamExt}; use ethers_signers::{LocalWallet, Signer}; - use std::{convert::TryFrom, sync::Arc, time::Duration}; + use std::{convert::TryFrom, iter::FromIterator, sync::Arc, time::Duration}; #[tokio::test] async fn deploy_and_call_contract() { @@ -517,10 +517,26 @@ mod eth_tests { .add_get_eth_balance(addrs[5], false) .add_get_eth_balance(addrs[6], false); + let valid_balances = [ + U256::from(10_000_000_000_000_000_000_000u128), + U256::from(10_000_000_000_000_000_000_000u128), + U256::from(10_000_000_000_000_000_000_000u128), + ]; + let balances: (U256, U256, U256) = multicall.call().await.unwrap(); - assert_eq!(balances.0, U256::from(10_000_000_000_000_000_000_000u128)); - assert_eq!(balances.1, U256::from(10_000_000_000_000_000_000_000u128)); - assert_eq!(balances.2, U256::from(10_000_000_000_000_000_000_000u128)); + assert_eq!(balances.0, valid_balances[0]); + assert_eq!(balances.1, valid_balances[1]); + assert_eq!(balances.2, valid_balances[2]); + + // call_array + multicall + .clear_calls() + .add_get_eth_balance(addrs[4], false) + .add_get_eth_balance(addrs[5], false) + .add_get_eth_balance(addrs[6], false); + + let balances: Vec = multicall.call_array().await.unwrap(); + assert_eq!(balances, Vec::from_iter(valid_balances.iter().copied())); // clear multicall so we can test `call_raw` w/ >16 calls multicall.clear_calls(); @@ -536,10 +552,11 @@ mod eth_tests { .unwrap(); // build up a list of calls greater than the 16 max restriction - for i in 0..=16 { - let call = simple_contract.method::<_, String>("getValue", ()).unwrap(); - multicall.add_call(call, false); - } + multicall.add_calls( + false, + std::iter::repeat(simple_contract.method::<_, String>("getValue", ()).unwrap()) + .take(17), // .collect(), + ); // must use `call_raw` as `.calls` > 16 let tokens = multicall.call_raw().await.unwrap(); From e86183e935afadb12930389929f9ccc0b54088c7 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sun, 18 Dec 2022 12:33:40 +0100 Subject: [PATCH 02/40] feat: make geth executable configurable (#1947) * feat: make geth executable configurable * Update ethers-core/src/utils/geth.rs Co-authored-by: Bjerg * Update ethers-core/src/utils/geth.rs Co-authored-by: Bjerg Co-authored-by: Bjerg --- ethers-core/src/utils/geth.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/ethers-core/src/utils/geth.rs b/ethers-core/src/utils/geth.rs index 8657c888..8c13d175 100644 --- a/ethers-core/src/utils/geth.rs +++ b/ethers-core/src/utils/geth.rs @@ -164,6 +164,7 @@ impl Default for PrivateNetOptions { /// ``` #[derive(Clone, Default)] pub struct Geth { + program: Option, port: Option, authrpc_port: Option, ipc_path: Option, @@ -180,6 +181,32 @@ impl Geth { Self::default() } + /// Creates a Geth builder which will execute `geth` at the given path. + /// + /// # Example + /// + /// ``` + /// use ethers_core::utils::Geth; + /// # fn a() { + /// let geth = Geth::at("../go-ethereum/build/bin/geth").spawn(); + /// + /// println!("Geth running at `{}`", geth.endpoint()); + /// # } + /// ``` + pub fn at(path: impl Into) -> Self { + Self::new().path(path) + } + + /// Sets the `path` to the `geth` executable + /// + /// By default, it's expected that `geth` is in `$PATH`, see also + /// [`std::process::Command::new()`] + #[must_use] + pub fn path>(mut self, path: T) -> Self { + self.program = Some(path.into()); + self + } + /// Sets the port which will be used when the `geth-cli` instance is launched. #[must_use] pub fn port>(mut self, port: T) -> Self { @@ -274,9 +301,10 @@ impl Geth { /// Consumes the builder and spawns `geth` with stdout redirected /// to /dev/null. pub fn spawn(self) -> GethInstance { - let mut cmd = Command::new(GETH); + let mut cmd = + if let Some(ref prg) = self.program { Command::new(prg) } else { Command::new(GETH) }; // geth uses stderr for its logs - cmd.stderr(std::process::Stdio::piped()); + cmd.stderr(Stdio::piped()); let port = if let Some(port) = self.port { port } else { unused_port() }; let authrpc_port = if let Some(port) = self.authrpc_port { port } else { unused_port() }; From 6efa7ca85f41d0f7dc28db1d308667b26557c1e8 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Sun, 18 Dec 2022 06:40:43 -0500 Subject: [PATCH 03/40] fix(core): decode to correctly in Transaction (#1946) * would not correctly decode a create transaction because 0x80 was not properly decoded --- ethers-core/src/types/transaction/eip1559.rs | 2 +- ethers-core/src/types/transaction/mod.rs | 2 +- ethers-core/src/types/transaction/request.rs | 2 +- ethers-core/src/types/transaction/response.rs | 35 ++++++++++++++----- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ethers-core/src/types/transaction/eip1559.rs b/ethers-core/src/types/transaction/eip1559.rs index ba080e19..ba937fe6 100644 --- a/ethers-core/src/types/transaction/eip1559.rs +++ b/ethers-core/src/types/transaction/eip1559.rs @@ -208,7 +208,7 @@ impl Eip1559TransactionRequest { *offset += 1; tx.gas = Some(rlp.val_at(*offset)?); *offset += 1; - tx.to = decode_to(rlp, offset)?; + tx.to = decode_to(rlp, offset)?.map(NameOrAddress::Address); tx.value = Some(rlp.val_at(*offset)?); *offset += 1; let data = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; diff --git a/ethers-core/src/types/transaction/mod.rs b/ethers-core/src/types/transaction/mod.rs index efe70780..816f4539 100644 --- a/ethers-core/src/types/transaction/mod.rs +++ b/ethers-core/src/types/transaction/mod.rs @@ -75,7 +75,7 @@ fn decode_signature( fn decode_to( rlp: &rlp::Rlp, offset: &mut usize, -) -> Result, rlp::DecoderError> { +) -> Result, rlp::DecoderError> { let to = { let to = rlp.at(*offset)?; if to.is_empty() { diff --git a/ethers-core/src/types/transaction/request.rs b/ethers-core/src/types/transaction/request.rs index f8be2627..d31d91bf 100644 --- a/ethers-core/src/types/transaction/request.rs +++ b/ethers-core/src/types/transaction/request.rs @@ -233,7 +233,7 @@ impl TransactionRequest { *offset += 1; } - txn.to = decode_to(rlp, offset)?; + txn.to = decode_to(rlp, offset)?.map(NameOrAddress::Address); txn.value = Some(rlp.at(*offset)?.as_val()?); *offset += 1; diff --git a/ethers-core/src/types/transaction/response.rs b/ethers-core/src/types/transaction/response.rs index 314caf0b..b29d6f99 100644 --- a/ethers-core/src/types/transaction/response.rs +++ b/ethers-core/src/types/transaction/response.rs @@ -1,7 +1,7 @@ //! Transaction types use super::{ - decode_signature, eip2718::TypedTransaction, eip2930::AccessList, normalize_v, rlp_opt, - rlp_opt_list, + decode_signature, decode_to, eip2718::TypedTransaction, eip2930::AccessList, normalize_v, + rlp_opt, rlp_opt_list, }; use crate::{ types::{ @@ -248,8 +248,7 @@ impl Transaction { *offset += 1; self.gas = rlp.val_at(*offset)?; *offset += 1; - self.to = Some(rlp.val_at(*offset)?); - *offset += 1; + self.to = decode_to(rlp, offset)?; self.value = rlp.val_at(*offset)?; *offset += 1; let input = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; @@ -279,8 +278,7 @@ impl Transaction { #[cfg(feature = "celo")] self.decode_celo_metadata(rlp, offset)?; - self.to = Some(rlp.val_at(*offset)?); - *offset += 1; + self.to = decode_to(rlp, offset)?; self.value = rlp.val_at(*offset)?; *offset += 1; let input = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; @@ -310,8 +308,7 @@ impl Transaction { #[cfg(feature = "celo")] self.decode_celo_metadata(rlp, offset)?; - self.to = Some(rlp.val_at(*offset)?); - *offset += 1; + self.to = decode_to(rlp, offset)?; self.value = rlp.val_at(*offset)?; *offset += 1; let input = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; @@ -473,7 +470,7 @@ impl PartialOrd for TransactionReceipt { #[cfg(test)] #[cfg(not(feature = "celo"))] mod tests { - use rlp::Encodable; + use rlp::{Encodable, Rlp}; use crate::types::transaction::eip2930::AccessListItem; @@ -1093,4 +1090,24 @@ mod tests { let r = rlp::Rlp::new(b.as_slice()); Transaction::decode(&r).unwrap(); } + + #[test] + fn test_rlp_decoding_create_roundtrip() { + let tx = Transaction { + block_hash: None, + block_number: None, + from: Address::from_str("c26ad91f4e7a0cad84c4b9315f420ca9217e315d").unwrap(), + gas: U256::from_str_radix("0x10e2b", 16).unwrap(), + gas_price: Some(U256::from_str_radix("0x12ec276caf", 16).unwrap()), + hash: H256::from_str("929ff27a5c7833953df23103c4eb55ebdfb698678139d751c51932163877fada").unwrap(), + input: Bytes::from( + hex::decode("a9059cbb000000000000000000000000fdae129ecc2c27d166a3131098bc05d143fa258e0000000000000000000000000000000000000000000000000000000002faf080").unwrap() + ), + nonce: U256::zero(), + transaction_index: None, + value: U256::zero(), + ..Default::default() + }; + Transaction::decode(&Rlp::new(&tx.rlp())).unwrap(); + } } From 022f082cee60f40d5004c12c4f12a7a56bf2da07 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sun, 18 Dec 2022 12:41:11 +0100 Subject: [PATCH 04/40] fix(msrv): bump in .clippy.toml and add a comment in root Cargo.toml (#1945) --- .clippy.toml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.clippy.toml b/.clippy.toml index 6bfeada7..ad0ea4e7 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1 +1 @@ -msrv = "1.62" +msrv = "1.64" diff --git a/Cargo.toml b/Cargo.toml index eff02c36..3205a175 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "ethers" version = "1.0.2" edition = "2021" -rust-version = "1.64" +rust-version = "1.64" # must also be changed in **/Cargo.toml and .clippy.toml authors = ["Georgios Konstantopoulos "] license = "MIT OR Apache-2.0" readme = "README.md" From bb4af1c13478ab368e89be143e79b553eb956922 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sun, 18 Dec 2022 12:45:47 +0100 Subject: [PATCH 05/40] fix(middleware): oracles, tests (#1944) * fix(middleware): oracles, tests * fix: use util * fix: make blocknative api key optional * make response fields public * import orders * docs: oracle trait * fix: make response fns public * chore: clippy * fix: doc tests --- ethers-middleware/README.md | 12 +- ethers-middleware/src/builder.rs | 6 +- ethers-middleware/src/gas_escalator/mod.rs | 4 +- .../src/gas_oracle/blocknative.rs | 242 +++++++++--------- ethers-middleware/src/gas_oracle/cache.rs | 38 +-- .../src/gas_oracle/eth_gas_station.rs | 134 +++++----- .../src/gas_oracle/etherchain.rs | 98 +++---- ethers-middleware/src/gas_oracle/etherscan.rs | 70 +++-- ethers-middleware/src/gas_oracle/gas_now.rs | 106 ++++---- ethers-middleware/src/gas_oracle/median.rs | 13 +- .../src/gas_oracle/middleware.rs | 4 +- ethers-middleware/src/gas_oracle/mod.rs | 101 +++++--- ethers-middleware/src/gas_oracle/polygon.rs | 116 +++++---- .../src/gas_oracle/provider_oracle.rs | 11 +- .../src/transformer/ds_proxy/factory.rs | 12 +- ethers-middleware/tests/builder.rs | 118 +++++---- ethers-middleware/tests/gas_escalator.rs | 1 + ethers-middleware/tests/gas_oracle.rs | 88 +++++-- ethers-middleware/tests/nonce_manager.rs | 20 +- ethers-middleware/tests/signer.rs | 32 +-- ethers-middleware/tests/stack.rs | 174 +++++++------ ethers-middleware/tests/transformer.rs | 6 +- 22 files changed, 753 insertions(+), 653 deletions(-) diff --git a/ethers-middleware/README.md b/ethers-middleware/README.md index 97d37ab2..75a9b328 100644 --- a/ethers-middleware/README.md +++ b/ethers-middleware/README.md @@ -23,13 +23,13 @@ use ethers_providers::{Middleware, Provider, Http}; use std::sync::Arc; use std::convert::TryFrom; use ethers_signers::{LocalWallet, Signer}; -use ethers_middleware::{*,gas_oracle::*}; +use ethers_middleware::{gas_oracle::{GasOracle, GasNow}, MiddlewareBuilder}; fn builder_example() { let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; let signer = key.parse::().unwrap(); let address = signer.address(); - let gas_oracle = EthGasStation::new(None); + let gas_oracle = GasNow::new(); let provider = Provider::::try_from("http://localhost:8545") .unwrap() @@ -58,7 +58,7 @@ fn builder_example_wrap_into() { .unwrap() .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) .wrap_into(|p| SignerMiddleware::new(p, signer)) - .wrap_into(|p| GasOracleMiddleware::new(p, EthGasStation::new(None))) + .wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new())) .wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer } ``` @@ -72,7 +72,7 @@ use ethers_providers::{Provider, Http}; use ethers_signers::{LocalWallet, Signer}; use ethers_middleware::{ gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency}, - gas_oracle::{GasOracleMiddleware, EthGasStation, GasCategory}, + gas_oracle::{GasOracleMiddleware, GasCategory, GasNow}, signer::SignerMiddleware, nonce_manager::NonceManagerMiddleware, }; @@ -91,8 +91,8 @@ let signer = LocalWallet::new(&mut rand::thread_rng()); let address = signer.address(); let provider = SignerMiddleware::new(provider, signer); -// Use EthGasStation as the gas oracle -let gas_oracle = EthGasStation::new(None); +// Use GasNow as the gas oracle +let gas_oracle = GasNow::new(); let provider = GasOracleMiddleware::new(provider, gas_oracle); // Manage nonces locally diff --git a/ethers-middleware/src/builder.rs b/ethers-middleware/src/builder.rs index b1827407..f824add9 100644 --- a/ethers-middleware/src/builder.rs +++ b/ethers-middleware/src/builder.rs @@ -16,14 +16,14 @@ use ethers_signers::Signer; /// use std::sync::Arc; /// use std::convert::TryFrom; /// use ethers_signers::{LocalWallet, Signer}; -/// use ethers_middleware::{*,gas_escalator::*,gas_oracle::*}; +/// use ethers_middleware::{*, gas_escalator::*, gas_oracle::*}; /// /// fn builder_example() { /// let key = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; /// let signer = key.parse::().unwrap(); /// let address = signer.address(); /// let escalator = GeometricGasPrice::new(1.125, 60_u64, None::); -/// let gas_oracle = EthGasStation::new(None); +/// let gas_oracle = GasNow::new(); /// /// let provider = Provider::::try_from("http://localhost:8545") /// .unwrap() @@ -43,7 +43,7 @@ use ethers_signers::Signer; /// .unwrap() /// .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) /// .wrap_into(|p| SignerMiddleware::new(p, signer)) -/// .wrap_into(|p| GasOracleMiddleware::new(p, EthGasStation::new(None))) +/// .wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new())) /// .wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer /// } /// ``` diff --git a/ethers-middleware/src/gas_escalator/mod.rs b/ethers-middleware/src/gas_escalator/mod.rs index a71adbf3..f3ab1840 100644 --- a/ethers-middleware/src/gas_escalator/mod.rs +++ b/ethers-middleware/src/gas_escalator/mod.rs @@ -46,7 +46,7 @@ pub enum Frequency { /// use ethers_providers::{Provider, Http}; /// use ethers_middleware::{ /// gas_escalator::{GeometricGasPrice, Frequency, GasEscalatorMiddleware}, -/// gas_oracle::{EthGasStation, GasCategory, GasOracleMiddleware}, +/// gas_oracle::{GasNow, GasCategory, GasOracleMiddleware}, /// }; /// use std::{convert::TryFrom, time::Duration, sync::Arc}; /// @@ -60,7 +60,7 @@ pub enum Frequency { /// }; /// /// // ... proceed to wrap it in other middleware -/// let gas_oracle = EthGasStation::new(None).category(GasCategory::SafeLow); +/// let gas_oracle = GasNow::new().category(GasCategory::SafeLow); /// let provider = GasOracleMiddleware::new(provider, gas_oracle); /// ``` pub struct GasEscalatorMiddleware { diff --git a/ethers-middleware/src/gas_oracle/blocknative.rs b/ethers-middleware/src/gas_oracle/blocknative.rs index 11832c5a..84b037c0 100644 --- a/ethers-middleware/src/gas_oracle/blocknative.rs +++ b/ethers-middleware/src/gas_oracle/blocknative.rs @@ -1,13 +1,128 @@ -use crate::gas_oracle::{GasCategory, GasOracle, GasOracleError, GWEI_TO_WEI}; +use super::{from_gwei_f64, GasCategory, GasOracle, GasOracleError, Result, GWEI_TO_WEI_U256}; use async_trait::async_trait; use ethers_core::types::U256; use reqwest::{header::AUTHORIZATION, Client}; use serde::Deserialize; -use std::{collections::HashMap, convert::TryInto}; +use std::collections::HashMap; use url::Url; -const BLOCKNATIVE_GAS_PRICE_ENDPOINT: &str = "https://api.blocknative.com/gasprices/blockprices"; +const URL: &str = "https://api.blocknative.com/gasprices/blockprices"; +/// A client over HTTP for the [BlockNative](https://www.blocknative.com/gas-estimator) gas tracker API +/// that implements the `GasOracle` trait. +#[derive(Clone, Debug)] +#[must_use] +pub struct BlockNative { + client: Client, + url: Url, + api_key: Option, + gas_category: GasCategory, +} + +#[derive(Clone, Debug, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct Response { + pub system: String, + pub network: String, + pub unit: String, + pub max_price: u64, + pub block_prices: Vec, + pub estimated_base_fees: Option>>>, +} + +#[derive(Clone, Debug, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct BlockPrice { + pub block_number: u64, + pub estimated_transaction_count: u64, + pub base_fee_per_gas: f64, + pub estimated_prices: Vec, +} + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct GasEstimate { + pub confidence: u64, + pub price: u64, + pub max_priority_fee_per_gas: f64, + pub max_fee_per_gas: f64, +} + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct BaseFeeEstimate { + pub confidence: u64, + pub base_fee: f64, +} + +impl Response { + #[inline] + pub fn estimate_from_category(&self, gas_category: &GasCategory) -> Result { + let confidence = gas_category_to_confidence(gas_category); + let price = self + .block_prices + .first() + .ok_or(GasOracleError::InvalidResponse)? + .estimated_prices + .iter() + .find(|p| p.confidence == confidence) + .ok_or(GasOracleError::GasCategoryNotSupported)?; + Ok(*price) + } +} + +impl Default for BlockNative { + fn default() -> Self { + Self::new(None) + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl GasOracle for BlockNative { + async fn fetch(&self) -> Result { + let estimate = self.query().await?.estimate_from_category(&self.gas_category)?; + Ok(U256::from(estimate.price) * GWEI_TO_WEI_U256) + } + + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { + let estimate = self.query().await?.estimate_from_category(&self.gas_category)?; + let max = from_gwei_f64(estimate.max_fee_per_gas); + let prio = from_gwei_f64(estimate.max_priority_fee_per_gas); + Ok((max, prio)) + } +} + +impl BlockNative { + /// Creates a new [BlockNative](https://www.blocknative.com/gas-estimator) gas oracle. + pub fn new(api_key: Option) -> Self { + Self::with_client(Client::new(), api_key) + } + + /// Same as [`Self::new`] but with a custom [`Client`]. + pub fn with_client(client: Client, api_key: Option) -> Self { + let url = Url::parse(URL).unwrap(); + Self { client, api_key, url, gas_category: GasCategory::Standard } + } + + /// Sets the gas price category to be used when fetching the gas price. + pub fn category(mut self, gas_category: GasCategory) -> Self { + self.gas_category = gas_category; + self + } + + /// Perform a request to the gas price API and deserialize the response. + pub async fn query(&self) -> Result { + let mut request = self.client.get(self.url.clone()); + if let Some(api_key) = self.api_key.as_ref() { + request = request.header(AUTHORIZATION, api_key); + } + let response = request.send().await?.error_for_status()?.json().await?; + Ok(response) + } +} + +#[inline] fn gas_category_to_confidence(gas_category: &GasCategory) -> u64 { match gas_category { GasCategory::SafeLow => 80, @@ -16,124 +131,3 @@ fn gas_category_to_confidence(gas_category: &GasCategory) -> u64 { GasCategory::Fastest => 99, } } - -/// A client over HTTP for the [BlockNative](https://www.blocknative.com/gas-estimator) gas tracker API -/// that implements the `GasOracle` trait -#[derive(Clone, Debug)] -pub struct BlockNative { - client: Client, - url: Url, - api_key: String, - gas_category: GasCategory, -} - -#[derive(Debug, Deserialize, PartialEq)] -#[serde(rename_all = "camelCase")] -pub struct BlockNativeGasResponse { - system: Option, - network: Option, - unit: Option, - max_price: Option, - block_prices: Vec, - estimated_base_fees: Vec>>, -} - -impl BlockNativeGasResponse { - pub fn get_estimation_for( - &self, - gas_category: &GasCategory, - ) -> Result { - let confidence = gas_category_to_confidence(gas_category); - Ok(self - .block_prices - .first() - .ok_or(GasOracleError::InvalidResponse)? - .estimated_prices - .iter() - .find(|p| p.confidence == confidence) - .ok_or(GasOracleError::GasCategoryNotSupported)? - .clone()) - } -} - -#[derive(Debug, Deserialize, PartialEq)] -#[serde(rename_all = "camelCase")] -pub struct BlockPrice { - block_number: u64, - estimated_transaction_count: u64, - base_fee_per_gas: f64, - estimated_prices: Vec, -} - -#[derive(Clone, Debug, Deserialize, PartialEq)] -#[serde(rename_all = "camelCase")] -pub struct EstimatedPrice { - confidence: u64, - price: u64, - max_priority_fee_per_gas: f64, - max_fee_per_gas: f64, -} - -#[derive(Debug, Deserialize, PartialEq)] -#[serde(rename_all = "camelCase")] -pub struct BaseFeeEstimate { - confidence: u64, - base_fee: f64, -} - -impl BlockNative { - /// Creates a new [BlockNative](https://www.blocknative.com/gas-estimator) gas oracle. - pub fn new(api_key: String) -> Self { - Self::with_client(Client::new(), api_key) - } - - /// Same as [`Self::new`] but with a custom [`Client`]. - pub fn with_client(client: Client, api_key: String) -> Self { - Self { - client, - api_key, - url: BLOCKNATIVE_GAS_PRICE_ENDPOINT.try_into().unwrap(), - gas_category: GasCategory::Standard, - } - } - - /// Sets the gas price category to be used when fetching the gas price. - #[must_use] - pub fn category(mut self, gas_category: GasCategory) -> Self { - self.gas_category = gas_category; - self - } - - /// Perform request to Blocknative, decode response - pub async fn request(&self) -> Result { - self.client - .get(self.url.as_ref()) - .header(AUTHORIZATION, &self.api_key) - .send() - .await? - .error_for_status()? - .json() - .await - .map_err(GasOracleError::HttpClientError) - } -} - -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl GasOracle for BlockNative { - async fn fetch(&self) -> Result { - let prices = self.request().await?.get_estimation_for(&self.gas_category)?; - Ok(U256::from(prices.price * 100_u64) * U256::from(GWEI_TO_WEI) / U256::from(100)) - } - - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { - let prices = self.request().await?.get_estimation_for(&self.gas_category)?; - let base_fee = U256::from((prices.max_fee_per_gas * 100.0) as u64) * - U256::from(GWEI_TO_WEI) / - U256::from(100); - let prio_fee = U256::from((prices.max_priority_fee_per_gas * 100.0) as u64) * - U256::from(GWEI_TO_WEI) / - U256::from(100); - Ok((base_fee, prio_fee)) - } -} diff --git a/ethers-middleware/src/gas_oracle/cache.rs b/ethers-middleware/src/gas_oracle/cache.rs index 6f8b162b..d840cb0f 100644 --- a/ethers-middleware/src/gas_oracle/cache.rs +++ b/ethers-middleware/src/gas_oracle/cache.rs @@ -1,4 +1,4 @@ -use crate::gas_oracle::{GasOracle, GasOracleError}; +use super::{GasOracle, Result}; use async_trait::async_trait; use ethers_core::types::U256; use futures_locks::RwLock; @@ -19,6 +19,24 @@ pub struct Cache { #[derive(Default, Debug)] struct Cached(RwLock>); +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl GasOracle for Cache { + async fn fetch(&self) -> Result { + self.fee.get(self.validity, || self.inner.fetch()).await + } + + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { + self.eip1559.get(self.validity, || self.inner.estimate_eip1559_fees()).await + } +} + +impl Cache { + pub fn new(validity: Duration, inner: T) -> Self { + Self { inner, validity, fee: Cached::default(), eip1559: Cached::default() } + } +} + impl Cached { async fn get(&self, validity: Duration, fetch: F) -> Result where @@ -50,21 +68,3 @@ impl Cached { } } } - -impl Cache { - pub fn new(validity: Duration, inner: T) -> Self { - Self { inner, validity, fee: Cached::default(), eip1559: Cached::default() } - } -} - -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl GasOracle for Cache { - async fn fetch(&self) -> Result { - self.fee.get(self.validity, || self.inner.fetch()).await - } - - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { - self.eip1559.get(self.validity, || self.inner.estimate_eip1559_fees()).await - } -} diff --git a/ethers-middleware/src/gas_oracle/eth_gas_station.rs b/ethers-middleware/src/gas_oracle/eth_gas_station.rs index 683caf37..73f1572c 100644 --- a/ethers-middleware/src/gas_oracle/eth_gas_station.rs +++ b/ethers-middleware/src/gas_oracle/eth_gas_station.rs @@ -1,88 +1,78 @@ -use std::collections::HashMap; - -use ethers_core::types::U256; +#![allow(deprecated)] +use super::{GasCategory, GasOracle, GasOracleError, Result, GWEI_TO_WEI_U256}; use async_trait::async_trait; +use ethers_core::types::U256; use reqwest::Client; use serde::Deserialize; +use std::collections::HashMap; use url::Url; -use crate::gas_oracle::{GasCategory, GasOracle, GasOracleError, GWEI_TO_WEI}; +const URL: &str = "https://ethgasstation.info/api/ethgasAPI.json"; -const ETH_GAS_STATION_URL_PREFIX: &str = "https://ethgasstation.info/api/ethgasAPI.json"; - -/// A client over HTTP for the [EthGasStation](https://ethgasstation.info/api/ethgasAPI.json) gas tracker API -/// that implements the `GasOracle` trait +/// A client over HTTP for the [EthGasStation](https://ethgasstation.info) gas tracker API +/// that implements the `GasOracle` trait. #[derive(Clone, Debug)] +#[deprecated = "ETHGasStation is shutting down: https://twitter.com/ETHGasStation/status/1597341610777317376"] +#[must_use] pub struct EthGasStation { client: Client, url: Url, gas_category: GasCategory, } -#[derive(Clone, Debug, Deserialize, PartialEq)] -#[serde(rename_all = "camelCase")] /// Eth Gas Station's response for the current recommended fast, standard and /// safe low gas prices on the Ethereum network, along with the current block /// and wait times for each "speed". -pub struct EthGasStationResponse { - /// Recommended safe(expected to be mined in < 30 minutes) gas price in - /// x10 Gwei (divide by 10 to convert it to gwei) - pub safe_low: f64, - /// Recommended average(expected to be mined in < 5 minutes) gas price in - /// x10 Gwei (divide by 10 to convert it to gwei) +#[derive(Clone, Debug, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct Response { + /// Recommended safe (expected to be mined in < 30 minutes). + /// + /// In gwei * 10 (divide by 10 to convert it to gwei). + pub safe_low: u64, + /// Recommended average (expected to be mined in < 5 minutes). + /// + /// In gwei * 10 (divide by 10 to convert it to gwei). pub average: u64, - /// Recommended fast(expected to be mined in < 2 minutes) gas price in - /// x10 Gwei (divide by 10 to convert it to gwei) + /// Recommended fast (expected to be mined in < 2 minutes). + /// + /// In gwei * 10 (divide by 10 to convert it to gwei). pub fast: u64, - /// Recommended fastest(expected to be mined in < 30 seconds) gas price - /// in x10 Gwei(divide by 10 to convert it to gwei) + /// Recommended fastest (expected to be mined in < 30 seconds). + /// + /// In gwei * 10 (divide by 10 to convert it to gwei). pub fastest: u64, // post eip-1559 fields + /// Average time (in seconds) to mine a single block. #[serde(rename = "block_time")] // inconsistent json response naming... - /// Average time(in seconds) to mine one single block pub block_time: f64, - /// The latest block number + /// The latest block number. pub block_num: u64, - /// Smallest value of (gasUsed / gaslimit) from last 10 blocks + /// Smallest value of `gasUsed / gaslimit` from the last 10 blocks. pub speed: f64, - /// Waiting time(in minutes) for the `safe_low` gas price + /// Waiting time (in minutes) for the `safe_low` gas price. pub safe_low_wait: f64, - /// Waiting time(in minutes) for the `average` gas price + /// Waiting time (in minutes) for the `average` gas price. pub avg_wait: f64, - /// Waiting time(in minutes) for the `fast` gas price + /// Waiting time (in minutes) for the `fast` gas price. pub fast_wait: f64, - /// Waiting time(in minutes) for the `fastest` gas price + /// Waiting time (in minutes) for the `fastest` gas price. pub fastest_wait: f64, // What is this? pub gas_price_range: HashMap, } -impl EthGasStation { - /// Creates a new [EthGasStation](https://docs.ethgasstation.info/) gas oracle - pub fn new(api_key: Option<&str>) -> Self { - Self::with_client(Client::new(), api_key) - } - - /// Same as [`Self::new`] but with a custom [`Client`]. - pub fn with_client(client: Client, api_key: Option<&str>) -> Self { - let mut url = Url::parse(ETH_GAS_STATION_URL_PREFIX).expect("invalid url"); - if let Some(key) = api_key { - url.query_pairs_mut().append_pair("api-key", key); +impl Response { + #[inline] + pub fn gas_from_category(&self, gas_category: GasCategory) -> u64 { + match gas_category { + GasCategory::SafeLow => self.safe_low, + GasCategory::Standard => self.average, + GasCategory::Fast => self.fast, + GasCategory::Fastest => self.fastest, } - EthGasStation { client, url, gas_category: GasCategory::Standard } - } - - /// Sets the gas price category to be used when fetching the gas price. - #[must_use] - pub fn category(mut self, gas_category: GasCategory) -> Self { - self.gas_category = gas_category; - self - } - - pub async fn query(&self) -> Result { - Ok(self.client.get(self.url.as_ref()).send().await?.json::().await?) } } @@ -95,19 +85,43 @@ impl Default for EthGasStation { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GasOracle for EthGasStation { - async fn fetch(&self) -> Result { + async fn fetch(&self) -> Result { let res = self.query().await?; - let gas_price = match self.gas_category { - GasCategory::SafeLow => U256::from((res.safe_low.ceil() as u64 * GWEI_TO_WEI) / 10), - GasCategory::Standard => U256::from((res.average * GWEI_TO_WEI) / 10), - GasCategory::Fast => U256::from((res.fast * GWEI_TO_WEI) / 10), - GasCategory::Fastest => U256::from((res.fastest * GWEI_TO_WEI) / 10), - }; - - Ok(gas_price) + let gas_price = res.gas_from_category(self.gas_category); + // gas_price is in `gwei * 10` + Ok(U256::from(gas_price) * GWEI_TO_WEI_U256 / U256::from(10_u64)) } - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { Err(GasOracleError::Eip1559EstimationNotSupported) } } + +impl EthGasStation { + /// Creates a new [EthGasStation](https://docs.ethgasstation.info/) gas oracle. + pub fn new(api_key: Option<&str>) -> Self { + Self::with_client(Client::new(), api_key) + } + + /// Same as [`Self::new`] but with a custom [`Client`]. + pub fn with_client(client: Client, api_key: Option<&str>) -> Self { + let mut url = Url::parse(URL).unwrap(); + if let Some(key) = api_key { + url.query_pairs_mut().append_pair("api-key", key); + } + EthGasStation { client, url, gas_category: GasCategory::Standard } + } + + /// Sets the gas price category to be used when fetching the gas price. + pub fn category(mut self, gas_category: GasCategory) -> Self { + self.gas_category = gas_category; + self + } + + /// Perform a request to the gas price API and deserialize the response. + pub async fn query(&self) -> Result { + let response = + self.client.get(self.url.clone()).send().await?.error_for_status()?.json().await?; + Ok(response) + } +} diff --git a/ethers-middleware/src/gas_oracle/etherchain.rs b/ethers-middleware/src/gas_oracle/etherchain.rs index 3fc94e6a..5d419929 100644 --- a/ethers-middleware/src/gas_oracle/etherchain.rs +++ b/ethers-middleware/src/gas_oracle/etherchain.rs @@ -1,56 +1,42 @@ -use ethers_core::types::U256; - +use super::{from_gwei_f64, GasCategory, GasOracle, GasOracleError, Result}; use async_trait::async_trait; +use ethers_core::types::U256; use reqwest::Client; use serde::Deserialize; use url::Url; -use crate::gas_oracle::{GasCategory, GasOracle, GasOracleError, GWEI_TO_WEI}; - -const ETHERCHAIN_URL: &str = "https://www.etherchain.org/api/gasPriceOracle"; +const URL: &str = "https://www.etherchain.org/api/gasPriceOracle"; /// A client over HTTP for the [Etherchain](https://www.etherchain.org/api/gasPriceOracle) gas tracker API -/// that implements the `GasOracle` trait +/// that implements the `GasOracle` trait. #[derive(Clone, Debug)] +#[must_use] pub struct Etherchain { client: Client, url: Url, gas_category: GasCategory, } -#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] -pub struct EtherchainResponse { - pub safe_low: f32, - pub standard: f32, - pub fast: f32, - pub fastest: f32, - pub current_base_fee: f32, - pub recommended_base_fee: f32, +pub struct Response { + pub safe_low: f64, + pub standard: f64, + pub fast: f64, + pub fastest: f64, + pub current_base_fee: f64, + pub recommended_base_fee: f64, } -impl Etherchain { - /// Creates a new [Etherchain](https://etherchain.org/tools/gasPriceOracle) gas price oracle. - pub fn new() -> Self { - Self::with_client(Client::new()) - } - - /// Same as [`Self::new`] but with a custom [`Client`]. - pub fn with_client(client: Client) -> Self { - let url = Url::parse(ETHERCHAIN_URL).expect("invalid url"); - - Etherchain { client, url, gas_category: GasCategory::Standard } - } - - /// Sets the gas price category to be used when fetching the gas price. - #[must_use] - pub fn category(mut self, gas_category: GasCategory) -> Self { - self.gas_category = gas_category; - self - } - - pub async fn query(&self) -> Result { - Ok(self.client.get(self.url.as_ref()).send().await?.json::().await?) +impl Response { + #[inline] + pub fn gas_from_category(&self, gas_category: GasCategory) -> f64 { + match gas_category { + GasCategory::SafeLow => self.safe_low, + GasCategory::Standard => self.standard, + GasCategory::Fast => self.fast, + GasCategory::Fastest => self.fastest, + } } } @@ -63,19 +49,39 @@ impl Default for Etherchain { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GasOracle for Etherchain { - async fn fetch(&self) -> Result { + async fn fetch(&self) -> Result { let res = self.query().await?; - let gas_price = match self.gas_category { - GasCategory::SafeLow => U256::from((res.safe_low as u64) * GWEI_TO_WEI), - GasCategory::Standard => U256::from((res.standard as u64) * GWEI_TO_WEI), - GasCategory::Fast => U256::from((res.fast as u64) * GWEI_TO_WEI), - GasCategory::Fastest => U256::from((res.fastest as u64) * GWEI_TO_WEI), - }; - - Ok(gas_price) + let gas_price = res.gas_from_category(self.gas_category); + Ok(from_gwei_f64(gas_price)) } - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { Err(GasOracleError::Eip1559EstimationNotSupported) } } + +impl Etherchain { + /// Creates a new [Etherchain](https://etherchain.org/tools/gasPriceOracle) gas price oracle. + pub fn new() -> Self { + Self::with_client(Client::new()) + } + + /// Same as [`Self::new`] but with a custom [`Client`]. + pub fn with_client(client: Client) -> Self { + let url = Url::parse(URL).unwrap(); + Etherchain { client, url, gas_category: GasCategory::Standard } + } + + /// Sets the gas price category to be used when fetching the gas price. + pub fn category(mut self, gas_category: GasCategory) -> Self { + self.gas_category = gas_category; + self + } + + /// Perform a request to the gas price API and deserialize the response. + pub async fn query(&self) -> Result { + let response = + self.client.get(self.url.clone()).send().await?.error_for_status()?.json().await?; + Ok(response) + } +} diff --git a/ethers-middleware/src/gas_oracle/etherscan.rs b/ethers-middleware/src/gas_oracle/etherscan.rs index b39cebff..9d8da4c0 100644 --- a/ethers-middleware/src/gas_oracle/etherscan.rs +++ b/ethers-middleware/src/gas_oracle/etherscan.rs @@ -1,18 +1,57 @@ +use super::{GasCategory, GasOracle, GasOracleError, Result, GWEI_TO_WEI_U256}; use async_trait::async_trait; - use ethers_core::types::U256; use ethers_etherscan::Client; - -use crate::gas_oracle::{GasCategory, GasOracle, GasOracleError, GWEI_TO_WEI}; +use std::ops::{Deref, DerefMut}; /// A client over HTTP for the [Etherscan](https://api.etherscan.io/api?module=gastracker&action=gasoracle) gas tracker API /// that implements the `GasOracle` trait #[derive(Clone, Debug)] +#[must_use] pub struct Etherscan { client: Client, gas_category: GasCategory, } +impl Deref for Etherscan { + type Target = Client; + + fn deref(&self) -> &Self::Target { + &self.client + } +} + +impl DerefMut for Etherscan { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.client + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl GasOracle for Etherscan { + async fn fetch(&self) -> Result { + // handle unsupported gas categories before making the request + match self.gas_category { + GasCategory::SafeLow | GasCategory::Standard | GasCategory::Fast => {} + GasCategory::Fastest => return Err(GasOracleError::GasCategoryNotSupported), + } + + let result = self.query().await?; + let gas_price = match self.gas_category { + GasCategory::SafeLow => result.safe_gas_price, + GasCategory::Standard => result.propose_gas_price, + GasCategory::Fast => result.fast_gas_price, + _ => unreachable!(), + }; + Ok(U256::from(gas_price) * GWEI_TO_WEI_U256) + } + + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { + Err(GasOracleError::Eip1559EstimationNotSupported) + } +} + impl Etherscan { /// Creates a new [Etherscan](https://etherscan.io/gastracker) gas price oracle. pub fn new(client: Client) -> Self { @@ -20,32 +59,13 @@ impl Etherscan { } /// Sets the gas price category to be used when fetching the gas price. - #[must_use] pub fn category(mut self, gas_category: GasCategory) -> Self { self.gas_category = gas_category; self } -} -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl GasOracle for Etherscan { - async fn fetch(&self) -> Result { - if matches!(self.gas_category, GasCategory::Fastest) { - return Err(GasOracleError::GasCategoryNotSupported) - } - - let result = self.client.gas_oracle().await?; - - match self.gas_category { - GasCategory::SafeLow => Ok(U256::from(result.safe_gas_price * GWEI_TO_WEI)), - GasCategory::Standard => Ok(U256::from(result.propose_gas_price * GWEI_TO_WEI)), - GasCategory::Fast => Ok(U256::from(result.fast_gas_price * GWEI_TO_WEI)), - _ => Err(GasOracleError::GasCategoryNotSupported), - } - } - - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { - Err(GasOracleError::Eip1559EstimationNotSupported) + /// Perform a request to the gas price API and deserialize the response. + pub async fn query(&self) -> Result { + Ok(self.client.gas_oracle().await?) } } diff --git a/ethers-middleware/src/gas_oracle/gas_now.rs b/ethers-middleware/src/gas_oracle/gas_now.rs index 65ddc46c..29de2c46 100644 --- a/ethers-middleware/src/gas_oracle/gas_now.rs +++ b/ethers-middleware/src/gas_oracle/gas_now.rs @@ -1,64 +1,54 @@ -use ethers_core::types::U256; - +use super::{GasCategory, GasOracle, GasOracleError, Result}; use async_trait::async_trait; +use ethers_core::types::U256; use reqwest::Client; use serde::Deserialize; use url::Url; -use crate::gas_oracle::{GasCategory, GasOracle, GasOracleError}; +const URL: &str = "https://beaconcha.in/api/v1/execution/gasnow"; -const GAS_NOW_URL: &str = "https://etherchain.org/api/gasnow"; - -/// A client over HTTP for the [Etherchain GasNow](https://etherchain.org/tools/gasnow) gas tracker API -/// that implements the `GasOracle` trait +/// A client over HTTP for the [beaconcha.in GasNow](https://beaconcha.in/gasnow) gas tracker API +/// that implements the `GasOracle` trait. #[derive(Clone, Debug)] +#[must_use] pub struct GasNow { client: Client, url: Url, gas_category: GasCategory, } -#[derive(Deserialize)] -struct GasNowResponseWrapper { - data: GasNowResponse, +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] +pub struct Response { + pub code: u64, + pub data: ResponseData, } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq, PartialOrd, Ord)] -pub struct GasNowResponse { +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] +pub struct ResponseData { pub rapid: u64, pub fast: u64, pub standard: u64, pub slow: u64, + pub timestamp: u64, + #[serde(rename = "priceUSD")] + pub price_usd: f64, } -impl GasNow { - /// Creates a new [Etherchain GasNow](https://etherchain.org/tools/gasnow) gas price oracle. - pub fn new() -> Self { - Self::with_client(Client::new()) +impl Response { + #[inline] + pub fn gas_from_category(&self, gas_category: GasCategory) -> u64 { + self.data.gas_from_category(gas_category) } +} - /// Same as [`Self::new`] but with a custom [`Client`]. - pub fn with_client(client: Client) -> Self { - let url = Url::parse(GAS_NOW_URL).expect("invalid url"); - - Self { client, url, gas_category: GasCategory::Standard } - } - - /// Sets the gas price category to be used when fetching the gas price. - pub fn category(mut self, gas_category: GasCategory) -> Self { - self.gas_category = gas_category; - self - } - - pub async fn query(&self) -> Result { - let res = self - .client - .get(self.url.as_ref()) - .send() - .await? - .json::() - .await?; - Ok(res.data) +impl ResponseData { + fn gas_from_category(&self, gas_category: GasCategory) -> u64 { + match gas_category { + GasCategory::SafeLow => self.slow, + GasCategory::Standard => self.standard, + GasCategory::Fast => self.fast, + GasCategory::Fastest => self.rapid, + } } } @@ -71,19 +61,39 @@ impl Default for GasNow { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GasOracle for GasNow { - async fn fetch(&self) -> Result { + async fn fetch(&self) -> Result { let res = self.query().await?; - let gas_price = match self.gas_category { - GasCategory::SafeLow => U256::from(res.slow), - GasCategory::Standard => U256::from(res.standard), - GasCategory::Fast => U256::from(res.fast), - GasCategory::Fastest => U256::from(res.rapid), - }; - - Ok(gas_price) + let gas_price = res.gas_from_category(self.gas_category); + Ok(U256::from(gas_price)) } - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { Err(GasOracleError::Eip1559EstimationNotSupported) } } + +impl GasNow { + /// Creates a new [beaconcha.in GasNow](https://beaconcha.in/gasnow) gas price oracle. + pub fn new() -> Self { + Self::with_client(Client::new()) + } + + /// Same as [`Self::new`] but with a custom [`Client`]. + pub fn with_client(client: Client) -> Self { + let url = Url::parse(URL).unwrap(); + Self { client, url, gas_category: GasCategory::Standard } + } + + /// Sets the gas price category to be used when fetching the gas price. + pub fn category(mut self, gas_category: GasCategory) -> Self { + self.gas_category = gas_category; + self + } + + /// Perform a request to the gas price API and deserialize the response. + pub async fn query(&self) -> Result { + let response = + self.client.get(self.url.as_ref()).send().await?.error_for_status()?.json().await?; + Ok(response) + } +} diff --git a/ethers-middleware/src/gas_oracle/median.rs b/ethers-middleware/src/gas_oracle/median.rs index 2149ce41..c6dd6c7e 100644 --- a/ethers-middleware/src/gas_oracle/median.rs +++ b/ethers-middleware/src/gas_oracle/median.rs @@ -1,4 +1,4 @@ -use crate::gas_oracle::{GasOracle, GasOracleError}; +use super::{GasOracle, GasOracleError, Result}; use async_trait::async_trait; use ethers_core::types::U256; use futures_util::future::join_all; @@ -28,13 +28,10 @@ impl Median { self.oracles.push((weight, Box::new(oracle))); } - pub async fn query_all<'a, Fn, Fut, O>( - &'a self, - mut f: Fn, - ) -> Result, GasOracleError> + pub async fn query_all<'a, Fn, Fut, O>(&'a self, mut f: Fn) -> Result> where Fn: FnMut(&'a dyn GasOracle) -> Fut, - Fut: Future>, + Fut: Future>, { // Process the oracles in parallel let futures = self.oracles.iter().map(|(_, oracle)| f(oracle.as_ref())); @@ -62,13 +59,13 @@ impl Median { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GasOracle for Median { - async fn fetch(&self) -> Result { + async fn fetch(&self) -> Result { let mut values = self.query_all(|oracle| oracle.fetch()).await?; // `query_all` guarantees `values` is not empty Ok(*weighted_fractile_by_key(0.5, &mut values, |fee| fee).unwrap()) } - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { let mut values = self.query_all(|oracle| oracle.estimate_eip1559_fees()).await?; // `query_all` guarantees `values` is not empty Ok(( diff --git a/ethers-middleware/src/gas_oracle/middleware.rs b/ethers-middleware/src/gas_oracle/middleware.rs index 272b0150..918ec4b0 100644 --- a/ethers-middleware/src/gas_oracle/middleware.rs +++ b/ethers-middleware/src/gas_oracle/middleware.rs @@ -4,8 +4,8 @@ use ethers_core::types::{transaction::eip2718::TypedTransaction, *}; use ethers_providers::{FromErr, Middleware, PendingTransaction}; use thiserror::Error; +/// Middleware used for fetching gas prices over an API instead of `eth_gasPrice`. #[derive(Debug)] -/// Middleware used for fetching gas prices over an API instead of `eth_gasPrice` pub struct GasOracleMiddleware { inner: M, gas_oracle: G, @@ -21,7 +21,7 @@ where } } -#[derive(Error, Debug)] +#[derive(Debug, Error)] pub enum MiddlewareError { #[error(transparent)] GasOracleError(#[from] GasOracleError), diff --git a/ethers-middleware/src/gas_oracle/mod.rs b/ethers-middleware/src/gas_oracle/mod.rs index 4a7a701c..9be17750 100644 --- a/ethers-middleware/src/gas_oracle/mod.rs +++ b/ethers-middleware/src/gas_oracle/mod.rs @@ -1,54 +1,58 @@ -mod blocknative; +pub mod blocknative; pub use blocknative::BlockNative; -mod eth_gas_station; +pub mod eth_gas_station; +#[allow(deprecated)] pub use eth_gas_station::EthGasStation; -mod etherchain; +pub mod etherchain; pub use etherchain::Etherchain; -mod etherscan; +pub mod etherscan; pub use etherscan::Etherscan; -mod middleware; +pub mod middleware; pub use middleware::{GasOracleMiddleware, MiddlewareError}; -mod median; +pub mod median; pub use median::Median; -mod cache; +pub mod cache; pub use cache::Cache; -mod polygon; +pub mod polygon; pub use polygon::Polygon; -mod gas_now; +pub mod gas_now; pub use gas_now::GasNow; -mod provider_oracle; +pub mod provider_oracle; pub use provider_oracle::ProviderOracle; -use ethers_core::types::U256; - use async_trait::async_trait; use auto_impl::auto_impl; +use ethers_core::types::U256; use reqwest::Error as ReqwestError; -use std::error::Error; +use std::{error::Error, fmt::Debug}; use thiserror::Error; -const GWEI_TO_WEI: u64 = 1000000000; +pub(crate) const GWEI_TO_WEI: u64 = 1_000_000_000; +pub(crate) const GWEI_TO_WEI_U256: U256 = U256([0, 0, 0, GWEI_TO_WEI]); -/// Various gas price categories. Choose one of the available -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub type Result = std::result::Result; + +/// Generic [`GasOracle`] gas price categories. +#[derive(Clone, Copy, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] pub enum GasCategory { SafeLow, + #[default] Standard, Fast, Fastest, } -#[derive(Error, Debug)] -/// Error thrown when fetching data from the `GasOracle` +/// Error thrown by a [`GasOracle`]. +#[derive(Debug, Error)] pub enum GasOracleError { /// An internal error in the HTTP request made from the underlying /// gas oracle @@ -83,48 +87,69 @@ pub enum GasOracleError { UnsupportedChain, /// Error thrown when the provider failed. - #[error("Chain is not supported by the oracle")] + #[error("Provider error: {0}")] ProviderError(#[from] Box), } -/// `GasOracle` is a trait that an underlying gas oracle needs to implement. +/// An Ethereum gas price oracle. /// /// # Example /// /// ```no_run -/// use ethers_middleware::{ -/// gas_oracle::{EthGasStation, Etherscan, GasCategory, GasOracle}, -/// }; +/// use ethers_core::types::U256; +/// use ethers_middleware::gas_oracle::{GasCategory, GasNow, GasOracle}; /// /// # async fn foo() -> Result<(), Box> { -/// let eth_gas_station_oracle = EthGasStation::new(Some("my-api-key")); -/// let etherscan_oracle = EthGasStation::new(None).category(GasCategory::SafeLow); -/// -/// let data_1 = eth_gas_station_oracle.fetch().await?; -/// let data_2 = etherscan_oracle.fetch().await?; +/// let oracle = GasNow::default().category(GasCategory::SafeLow); +/// let gas_price = oracle.fetch().await?; +/// assert!(gas_price > U256::zero()); /// # Ok(()) /// # } /// ``` #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[auto_impl(&, Box, Arc)] -pub trait GasOracle: Send + Sync + std::fmt::Debug { - /// Makes an asynchronous HTTP query to the underlying `GasOracle` +pub trait GasOracle: Send + Sync + Debug { + /// Makes an asynchronous HTTP query to the underlying [`GasOracle`] to fetch the current gas + /// price estimate. /// /// # Example /// - /// ``` - /// use ethers_middleware::{ - /// gas_oracle::{Etherchain, GasCategory, GasOracle}, - /// }; + /// ```no_run + /// use ethers_core::types::U256; + /// use ethers_middleware::gas_oracle::{GasCategory, GasNow, GasOracle}; /// /// # async fn foo() -> Result<(), Box> { - /// let etherchain_oracle = Etherchain::new().category(GasCategory::Fastest); - /// let data = etherchain_oracle.fetch().await?; + /// let oracle = GasNow::default().category(GasCategory::SafeLow); + /// let gas_price = oracle.fetch().await?; + /// assert!(gas_price > U256::zero()); /// # Ok(()) /// # } /// ``` - async fn fetch(&self) -> Result; + async fn fetch(&self) -> Result; - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError>; + /// Makes an asynchronous HTTP query to the underlying [`GasOracle`] to fetch the current max + /// gas fee and priority gas fee estimates. + /// + /// # Example + /// + /// ```no_run + /// use ethers_core::types::U256; + /// use ethers_middleware::gas_oracle::{GasCategory, GasNow, GasOracle}; + /// + /// # async fn foo() -> Result<(), Box> { + /// let oracle = GasNow::default().category(GasCategory::SafeLow); + /// let (max_fee, priority_fee) = oracle.estimate_eip1559_fees().await?; + /// assert!(max_fee > U256::zero()); + /// assert!(priority_fee > U256::zero()); + /// # Ok(()) + /// # } + /// ``` + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)>; +} + +#[inline] +#[doc(hidden)] +pub(crate) fn from_gwei_f64(gwei: f64) -> U256 { + ethers_core::types::u256_from_f64_saturating(gwei) * GWEI_TO_WEI_U256 } diff --git a/ethers-middleware/src/gas_oracle/polygon.rs b/ethers-middleware/src/gas_oracle/polygon.rs index 47a3415d..5fd63545 100644 --- a/ethers-middleware/src/gas_oracle/polygon.rs +++ b/ethers-middleware/src/gas_oracle/polygon.rs @@ -1,16 +1,17 @@ -use crate::gas_oracle::{GasCategory, GasOracle, GasOracleError}; +use super::{from_gwei_f64, GasCategory, GasOracle, GasOracleError, Result}; use async_trait::async_trait; -use ethers_core::types::{u256_from_f64_saturating, Chain, U256}; +use ethers_core::types::{Chain, U256}; use reqwest::Client; use serde::Deserialize; use url::Url; -const GAS_PRICE_ENDPOINT: &str = "https://gasstation-mainnet.matic.network/v2"; -const MUMBAI_GAS_PRICE_ENDPOINT: &str = "https://gasstation-mumbai.matic.today/v2"; +const MAINNET_URL: &str = "https://gasstation-mainnet.matic.network/v2"; +const MUMBAI_URL: &str = "https://gasstation-mumbai.matic.today/v2"; /// The [Polygon](https://docs.polygon.technology/docs/develop/tools/polygon-gas-station/) gas station API -/// Queries over HTTP and implements the `GasOracle` trait +/// Queries over HTTP and implements the `GasOracle` trait. #[derive(Clone, Debug)] +#[must_use] pub struct Polygon { client: Client, url: Url, @@ -18,74 +19,87 @@ pub struct Polygon { } /// The response from the Polygon gas station API. +/// /// Gas prices are in Gwei. #[derive(Debug, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Response { - estimated_base_fee: f64, - safe_low: GasEstimate, - standard: GasEstimate, - fast: GasEstimate, + pub estimated_base_fee: f64, + pub safe_low: GasEstimate, + pub standard: GasEstimate, + pub fast: GasEstimate, } #[derive(Clone, Copy, Debug, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct GasEstimate { - max_priority_fee: f64, - max_fee: f64, + pub max_priority_fee: f64, + pub max_fee: f64, } -impl Polygon { - pub fn new(chain: Chain) -> Result { - Self::with_client(Client::new(), chain) +impl Response { + #[inline] + pub fn estimate_from_category(&self, gas_category: GasCategory) -> GasEstimate { + match gas_category { + GasCategory::SafeLow => self.safe_low, + GasCategory::Standard => self.standard, + GasCategory::Fast => self.fast, + GasCategory::Fastest => self.fast, + } } +} - pub fn with_client(client: Client, chain: Chain) -> Result { - // TODO: Sniff chain from chain id. - let url = match chain { - Chain::Polygon => Url::parse(GAS_PRICE_ENDPOINT).unwrap(), - Chain::PolygonMumbai => Url::parse(MUMBAI_GAS_PRICE_ENDPOINT).unwrap(), - _ => return Err(GasOracleError::UnsupportedChain), - }; - Ok(Self { client, url, gas_category: GasCategory::Standard }) - } - - /// Sets the gas price category to be used when fetching the gas price. - #[must_use] - pub fn category(mut self, gas_category: GasCategory) -> Self { - self.gas_category = gas_category; - self - } - - /// Perform request to Blocknative, decode response - pub async fn request(&self) -> Result<(f64, GasEstimate), GasOracleError> { - let response: Response = - self.client.get(self.url.as_ref()).send().await?.error_for_status()?.json().await?; - let estimate = match self.gas_category { - GasCategory::SafeLow => response.safe_low, - GasCategory::Standard => response.standard, - GasCategory::Fast => response.fast, - GasCategory::Fastest => response.fast, - }; - Ok((response.estimated_base_fee, estimate)) +impl Default for Polygon { + fn default() -> Self { + Self::new(Chain::Polygon).unwrap() } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GasOracle for Polygon { - async fn fetch(&self) -> Result { - let (base_fee, estimate) = self.request().await?; - let fee = base_fee + estimate.max_priority_fee; - Ok(from_gwei(fee)) + async fn fetch(&self) -> Result { + let response = self.query().await?; + let base = response.estimated_base_fee; + let prio = response.estimate_from_category(self.gas_category).max_priority_fee; + let fee = base + prio; + Ok(from_gwei_f64(fee)) } - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { - let (_, estimate) = self.request().await?; - Ok((from_gwei(estimate.max_fee), from_gwei(estimate.max_priority_fee))) + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { + let response = self.query().await?; + let estimate = response.estimate_from_category(self.gas_category); + let max = from_gwei_f64(estimate.max_fee); + let prio = from_gwei_f64(estimate.max_priority_fee); + Ok((max, prio)) } } -fn from_gwei(gwei: f64) -> U256 { - u256_from_f64_saturating(gwei * 1.0e9_f64) +impl Polygon { + pub fn new(chain: Chain) -> Result { + Self::with_client(Client::new(), chain) + } + + pub fn with_client(client: Client, chain: Chain) -> Result { + // TODO: Sniff chain from chain id. + let url = match chain { + Chain::Polygon => MAINNET_URL, + Chain::PolygonMumbai => MUMBAI_URL, + _ => return Err(GasOracleError::UnsupportedChain), + }; + Ok(Self { client, url: Url::parse(url).unwrap(), gas_category: GasCategory::Standard }) + } + + /// Sets the gas price category to be used when fetching the gas price. + pub fn category(mut self, gas_category: GasCategory) -> Self { + self.gas_category = gas_category; + self + } + + /// Perform a request to the gas price API and deserialize the response. + pub async fn query(&self) -> Result { + let response = + self.client.get(self.url.clone()).send().await?.error_for_status()?.json().await?; + Ok(response) + } } diff --git a/ethers-middleware/src/gas_oracle/provider_oracle.rs b/ethers-middleware/src/gas_oracle/provider_oracle.rs index 894bb5ab..c97c857d 100644 --- a/ethers-middleware/src/gas_oracle/provider_oracle.rs +++ b/ethers-middleware/src/gas_oracle/provider_oracle.rs @@ -1,4 +1,4 @@ -use crate::gas_oracle::{GasOracle, GasOracleError}; +use super::{GasOracle, GasOracleError, Result}; use async_trait::async_trait; use ethers_core::types::U256; use ethers_providers::Middleware; @@ -6,7 +6,8 @@ use std::fmt::Debug; /// Gas oracle from a [`Middleware`] implementation such as an /// Ethereum RPC provider. -#[derive(Debug)] +#[derive(Clone, Debug)] +#[must_use] pub struct ProviderOracle { provider: M, } @@ -21,16 +22,16 @@ impl ProviderOracle { #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GasOracle for ProviderOracle where - ::Error: 'static, + M::Error: 'static, { - async fn fetch(&self) -> Result { + async fn fetch(&self) -> Result { self.provider .get_gas_price() .await .map_err(|err| GasOracleError::ProviderError(Box::new(err))) } - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { // TODO: Allow configuring different estimation functions. self.provider .estimate_eip1559_fees(None) diff --git a/ethers-middleware/src/transformer/ds_proxy/factory.rs b/ethers-middleware/src/transformer/ds_proxy/factory.rs index 11fb1380..122c7bf1 100644 --- a/ethers-middleware/src/transformer/ds_proxy/factory.rs +++ b/ethers-middleware/src/transformer/ds_proxy/factory.rs @@ -1,22 +1,21 @@ use ethers_contract::Lazy; use ethers_core::types::*; -use std::{collections::HashMap, str::FromStr}; +use std::collections::HashMap; /// A lazily computed hash map with the Ethereum network IDs as keys and the corresponding /// DsProxyFactory contract addresses as values pub static ADDRESS_BOOK: Lazy> = Lazy::new(|| { - let mut m = HashMap::new(); + let mut m = HashMap::with_capacity(1); // mainnet - let addr = - Address::from_str("eefba1e63905ef1d7acba5a8513c70307c1ce441").expect("Decoding failed"); - m.insert(U256::from(1u8), addr); + let addr = "eefba1e63905ef1d7acba5a8513c70307c1ce441".parse().unwrap(); + m.insert(U256::from(1_u64), addr); m }); +/// Generated with abigen: /// -/// Generated with /// ```ignore /// # use ethers_contract::abigen; /// abigen!(DsProxyFactory, @@ -26,7 +25,6 @@ pub static ADDRESS_BOOK: Lazy> = Lazy::new(|| { /// } /// ); /// ``` -// Auto-generated type-safe bindings pub use dsproxyfactory_mod::*; #[allow(clippy::too_many_arguments)] mod dsproxyfactory_mod { diff --git a/ethers-middleware/tests/builder.rs b/ethers-middleware/tests/builder.rs index 7c988bb8..d99c603e 100644 --- a/ethers-middleware/tests/builder.rs +++ b/ethers-middleware/tests/builder.rs @@ -1,69 +1,67 @@ #![cfg(not(target_arch = "wasm32"))] -#[cfg(not(feature = "celo"))] -mod tests { - use ethers_core::{rand::thread_rng, types::U64}; - use ethers_middleware::{ - builder::MiddlewareBuilder, - gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}, - gas_oracle::{EthGasStation, GasOracleMiddleware}, - nonce_manager::NonceManagerMiddleware, - signer::SignerMiddleware, - }; - use ethers_providers::{Middleware, Provider}; - use ethers_signers::{LocalWallet, Signer}; - #[tokio::test] - async fn build_raw_middleware_stack() { - let (provider, mock) = Provider::mocked(); +use ethers_core::{rand::thread_rng, types::U64}; +use ethers_middleware::{ + builder::MiddlewareBuilder, + gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}, + gas_oracle::{GasNow, GasOracleMiddleware}, + nonce_manager::NonceManagerMiddleware, + signer::SignerMiddleware, +}; +use ethers_providers::{Middleware, Provider}; +use ethers_signers::{LocalWallet, Signer}; - let signer = LocalWallet::new(&mut thread_rng()); - let address = signer.address(); - let escalator = GeometricGasPrice::new(1.125, 60u64, None::); +#[tokio::test] +async fn build_raw_middleware_stack() { + let (provider, mock) = Provider::mocked(); - let provider = provider - .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) - .wrap_into(|p| GasOracleMiddleware::new(p, EthGasStation::new(None))) - .wrap_into(|p| SignerMiddleware::new(p, signer)) - .wrap_into(|p| NonceManagerMiddleware::new(p, address)); + let signer = LocalWallet::new(&mut thread_rng()); + let address = signer.address(); + let escalator = GeometricGasPrice::new(1.125, 60u64, None::); - // push a response - mock.push(U64::from(12u64)).unwrap(); - let block: U64 = provider.get_block_number().await.unwrap(); - assert_eq!(block.as_u64(), 12); + let provider = provider + .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) + .wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new())) + .wrap_into(|p| SignerMiddleware::new(p, signer)) + .wrap_into(|p| NonceManagerMiddleware::new(p, address)); - provider.get_block_number().await.unwrap_err(); + // push a response + mock.push(U64::from(12u64)).unwrap(); + let block: U64 = provider.get_block_number().await.unwrap(); + assert_eq!(block.as_u64(), 12); - // 2 calls were made - mock.assert_request("eth_blockNumber", ()).unwrap(); - mock.assert_request("eth_blockNumber", ()).unwrap(); - mock.assert_request("eth_blockNumber", ()).unwrap_err(); - } + provider.get_block_number().await.unwrap_err(); - #[tokio::test] - async fn build_declarative_middleware_stack() { - let (provider, mock) = Provider::mocked(); - - let signer = LocalWallet::new(&mut thread_rng()); - let address = signer.address(); - let escalator = GeometricGasPrice::new(1.125, 60u64, None::); - let gas_oracle = EthGasStation::new(None); - - let provider = provider - .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) - .gas_oracle(gas_oracle) - .with_signer(signer) - .nonce_manager(address); - - // push a response - mock.push(U64::from(12u64)).unwrap(); - let block: U64 = provider.get_block_number().await.unwrap(); - assert_eq!(block.as_u64(), 12); - - provider.get_block_number().await.unwrap_err(); - - // 2 calls were made - mock.assert_request("eth_blockNumber", ()).unwrap(); - mock.assert_request("eth_blockNumber", ()).unwrap(); - mock.assert_request("eth_blockNumber", ()).unwrap_err(); - } + // 2 calls were made + mock.assert_request("eth_blockNumber", ()).unwrap(); + mock.assert_request("eth_blockNumber", ()).unwrap(); + mock.assert_request("eth_blockNumber", ()).unwrap_err(); +} + +#[tokio::test] +async fn build_declarative_middleware_stack() { + let (provider, mock) = Provider::mocked(); + + let signer = LocalWallet::new(&mut thread_rng()); + let address = signer.address(); + let escalator = GeometricGasPrice::new(1.125, 60u64, None::); + let gas_oracle = GasNow::new(); + + let provider = provider + .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) + .gas_oracle(gas_oracle) + .with_signer(signer) + .nonce_manager(address); + + // push a response + mock.push(U64::from(12u64)).unwrap(); + let block: U64 = provider.get_block_number().await.unwrap(); + assert_eq!(block.as_u64(), 12); + + provider.get_block_number().await.unwrap_err(); + + // 2 calls were made + mock.assert_request("eth_blockNumber", ()).unwrap(); + mock.assert_request("eth_blockNumber", ()).unwrap(); + mock.assert_request("eth_blockNumber", ()).unwrap_err(); } diff --git a/ethers-middleware/tests/gas_escalator.rs b/ethers-middleware/tests/gas_escalator.rs index a9eff59c..c2bfbad6 100644 --- a/ethers-middleware/tests/gas_escalator.rs +++ b/ethers-middleware/tests/gas_escalator.rs @@ -1,4 +1,5 @@ #![cfg(not(target_arch = "wasm32"))] + use ethers_core::types::*; use ethers_middleware::{ gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}, diff --git a/ethers-middleware/tests/gas_oracle.rs b/ethers-middleware/tests/gas_oracle.rs index 10db9ba0..9464fb3d 100644 --- a/ethers-middleware/tests/gas_oracle.rs +++ b/ethers-middleware/tests/gas_oracle.rs @@ -1,16 +1,14 @@ #![cfg(not(target_arch = "wasm32"))] -use std::convert::TryFrom; - use async_trait::async_trait; - use ethers_core::{types::*, utils::Anvil}; use ethers_middleware::gas_oracle::{ - EthGasStation, Etherchain, Etherscan, GasCategory, GasOracle, GasOracleError, - GasOracleMiddleware, + BlockNative, Etherchain, Etherscan, GasCategory, GasNow, GasOracle, GasOracleError, + GasOracleMiddleware, Polygon, ProviderOracle, Result, }; use ethers_providers::{Http, Middleware, Provider}; use serial_test::serial; +use std::convert::TryFrom; #[derive(Debug)] struct FakeGasOracle { @@ -20,17 +18,18 @@ struct FakeGasOracle { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GasOracle for FakeGasOracle { - async fn fetch(&self) -> Result { + async fn fetch(&self) -> Result { Ok(self.gas_price) } - async fn estimate_eip1559_fees(&self) -> Result<(U256, U256), GasOracleError> { + async fn estimate_eip1559_fees(&self) -> Result<(U256, U256)> { Err(GasOracleError::Eip1559EstimationNotSupported) } } #[tokio::test] -async fn using_gas_oracle() { +#[serial] +async fn provider_using_gas_oracle() { let anvil = Anvil::new().spawn(); let from = anvil.addresses()[0]; @@ -38,11 +37,11 @@ async fn using_gas_oracle() { // connect to the network let provider = Provider::::try_from(anvil.endpoint()).unwrap(); - // initial base fee - let base_fee = 1_000_000_000u64; // assign a gas oracle to use - let gas_oracle = FakeGasOracle { gas_price: (base_fee + 1337).into() }; - let expected_gas_price = gas_oracle.fetch().await.unwrap(); + let expected_gas_price = U256::from(1234567890_u64); + let gas_oracle = FakeGasOracle { gas_price: expected_gas_price }; + let gas_price = gas_oracle.fetch().await.unwrap(); + assert_eq!(gas_price, expected_gas_price); let provider = GasOracleMiddleware::new(provider, gas_oracle); @@ -55,35 +54,70 @@ async fn using_gas_oracle() { } #[tokio::test] -async fn eth_gas_station() { - // initialize and fetch gas estimates from EthGasStation - let eth_gas_station_oracle = EthGasStation::default(); - let data = eth_gas_station_oracle.fetch().await; - data.unwrap(); +#[serial] +async fn provider_oracle() { + // spawn anvil and connect to it + let anvil = Anvil::new().spawn(); + let provider = Provider::::try_from(anvil.endpoint()).unwrap(); + + // assert that provider.get_gas_price() and oracle.fetch() return the same value + let expected_gas_price = provider.get_gas_price().await.unwrap(); + let provider_oracle = ProviderOracle::new(provider); + let gas = provider_oracle.fetch().await.unwrap(); + assert_eq!(gas, expected_gas_price); +} + +#[tokio::test] +async fn blocknative() { + let gas_now_oracle = BlockNative::default(); + let gas_price = gas_now_oracle.fetch().await.unwrap(); + assert!(gas_price > U256::zero()); +} + +#[tokio::test] +#[ignore = "ETHGasStation is shutting down: https://twitter.com/ETHGasStation/status/1597341610777317376"] +#[allow(deprecated)] +async fn eth_gas_station() { + let eth_gas_station_oracle = ethers_middleware::gas_oracle::EthGasStation::default(); + let gas_price = eth_gas_station_oracle.fetch().await.unwrap(); + assert!(gas_price > U256::zero()); +} + +#[tokio::test] +#[ignore = "Etherchain / beaconcha.in's `gasPriceOracle` API currently returns 404: https://www.etherchain.org/api/gasPriceOracle"] +async fn etherchain() { + let etherchain_oracle = Etherchain::default(); + let gas_price = etherchain_oracle.fetch().await.unwrap(); + assert!(gas_price > U256::zero()); } #[tokio::test] -#[serial] async fn etherscan() { let etherscan_client = ethers_etherscan::Client::new_from_env(Chain::Mainnet).unwrap(); // initialize and fetch gas estimates from Etherscan // since etherscan does not support `fastest` category, we expect an error let etherscan_oracle = Etherscan::new(etherscan_client.clone()).category(GasCategory::Fastest); - let data = etherscan_oracle.fetch().await; - data.unwrap_err(); + let error = etherscan_oracle.fetch().await.unwrap_err(); + assert!(matches!(error, GasOracleError::GasCategoryNotSupported)); // but fetching the `standard` gas price should work fine let etherscan_oracle = Etherscan::new(etherscan_client).category(GasCategory::SafeLow); - let data = etherscan_oracle.fetch().await; - data.unwrap(); + let gas_price = etherscan_oracle.fetch().await.unwrap(); + assert!(gas_price > U256::zero()); } #[tokio::test] -async fn etherchain() { - // initialize and fetch gas estimates from Etherchain - let etherchain_oracle = Etherchain::default().category(GasCategory::Fast); - let data = etherchain_oracle.fetch().await; - data.unwrap(); +async fn gas_now() { + let gas_now_oracle = GasNow::default(); + let gas_price = gas_now_oracle.fetch().await.unwrap(); + assert!(gas_price > U256::zero()); +} + +#[tokio::test] +async fn polygon() { + let polygon_oracle = Polygon::default(); + let gas_price = polygon_oracle.fetch().await.unwrap(); + assert!(gas_price > U256::zero()); } diff --git a/ethers-middleware/tests/nonce_manager.rs b/ethers-middleware/tests/nonce_manager.rs index ce7bac22..a1c74915 100644 --- a/ethers-middleware/tests/nonce_manager.rs +++ b/ethers-middleware/tests/nonce_manager.rs @@ -1,18 +1,18 @@ -#![cfg(not(target_arch = "wasm32"))] -#[tokio::test] -#[cfg(not(feature = "celo"))] -async fn nonce_manager() { - use ethers_core::types::*; - use ethers_middleware::{nonce_manager::NonceManagerMiddleware, signer::SignerMiddleware}; - use ethers_providers::Middleware; - use ethers_signers::{LocalWallet, Signer}; - use std::time::Duration; +#![cfg(all(not(target_arch = "wasm32"), not(feature = "celo")))] +use ethers_core::types::*; +use ethers_middleware::{nonce_manager::NonceManagerMiddleware, signer::SignerMiddleware}; +use ethers_providers::Middleware; +use ethers_signers::{LocalWallet, Signer}; +use std::time::Duration; + +#[tokio::test] +async fn nonce_manager() { let provider = ethers_providers::GOERLI.provider().interval(Duration::from_millis(2000u64)); let chain_id = provider.get_chainid().await.unwrap().as_u64(); let wallet = std::env::var("GOERLI_PRIVATE_KEY") - .unwrap() + .expect("GOERLI_PRIVATE_KEY is not defined") .parse::() .unwrap() .with_chain_id(chain_id); diff --git a/ethers-middleware/tests/signer.rs b/ethers-middleware/tests/signer.rs index a7c16a8c..9c2176ed 100644 --- a/ethers-middleware/tests/signer.rs +++ b/ethers-middleware/tests/signer.rs @@ -1,14 +1,22 @@ #![allow(unused)] -use ethers_providers::{Http, JsonRpcClient, Middleware, Provider, GOERLI}; +use ethers_contract::ContractFactory; use ethers_core::{ - types::{BlockNumber, TransactionRequest}, - utils::parse_units, + abi::Abi, + types::*, + utils::{parse_ether, parse_units, Anvil}, }; use ethers_middleware::signer::SignerMiddleware; +use ethers_providers::{Http, JsonRpcClient, Middleware, Provider, GOERLI}; use ethers_signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer}; +use ethers_solc::Solc; use once_cell::sync::Lazy; -use std::{convert::TryFrom, iter::Cycle, sync::atomic::AtomicU8, time::Duration}; +use std::{ + convert::TryFrom, + iter::Cycle, + sync::{atomic::AtomicU8, Arc}, + time::Duration, +}; static WALLETS: Lazy = Lazy::new(|| { TestWallets { @@ -22,8 +30,6 @@ static WALLETS: Lazy = Lazy::new(|| { #[tokio::test] #[cfg(not(feature = "celo"))] async fn send_eth() { - use ethers_core::utils::Anvil; - let anvil = Anvil::new().spawn(); // this private key belongs to the above mnemonic @@ -95,10 +101,6 @@ async fn pending_txs_with_confirmations_testnet() { generic_pending_txs_test(provider, address).await; } -#[cfg(not(feature = "celo"))] -use ethers_core::types::{Address, Eip1559TransactionRequest}; -use ethers_core::utils::parse_ether; - // different keys to avoid nonce errors #[tokio::test] #[cfg(not(feature = "celo"))] @@ -195,8 +197,6 @@ async fn test_send_transaction() { #[tokio::test] #[cfg(not(feature = "celo"))] async fn send_transaction_handles_tx_from_field() { - use ethers_core::utils::Anvil; - // launch anvil let anvil = Anvil::new().spawn(); @@ -240,14 +240,6 @@ async fn send_transaction_handles_tx_from_field() { #[tokio::test] #[cfg(feature = "celo")] async fn deploy_and_call_contract() { - use ethers_contract::ContractFactory; - use ethers_core::{ - abi::Abi, - types::{BlockNumber, Bytes, H256, U256}, - }; - use ethers_solc::Solc; - use std::sync::Arc; - // compiles the given contract and returns the ABI and Bytecode fn compile_contract(path: &str, name: &str) -> (Abi, Bytes) { let path = format!("./tests/solidity-contracts/{path}"); diff --git a/ethers-middleware/tests/stack.rs b/ethers-middleware/tests/stack.rs index c7cb1ea2..bf70056f 100644 --- a/ethers-middleware/tests/stack.rs +++ b/ethers-middleware/tests/stack.rs @@ -1,95 +1,93 @@ -#![cfg(not(target_arch = "wasm32"))] -#[cfg(not(feature = "celo"))] -mod tests { - use ethers_core::{rand::thread_rng, types::TransactionRequest, utils::Anvil}; - use ethers_middleware::{ - gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}, - gas_oracle::{EthGasStation, GasCategory, GasOracleMiddleware}, - nonce_manager::NonceManagerMiddleware, - signer::SignerMiddleware, - }; - use ethers_providers::{Http, Middleware, Provider}; - use ethers_signers::{LocalWallet, Signer}; - use std::convert::TryFrom; +#![cfg(all(not(target_arch = "wasm32"), not(feature = "celo")))] - #[tokio::test] - async fn mock_with_middleware() { - let (provider, mock) = Provider::mocked(); +use ethers_core::{rand::thread_rng, types::TransactionRequest, utils::Anvil}; +use ethers_middleware::{ + gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}, + gas_oracle::{GasCategory, GasNow, GasOracleMiddleware}, + nonce_manager::NonceManagerMiddleware, + signer::SignerMiddleware, +}; +use ethers_providers::{Http, Middleware, Provider}; +use ethers_signers::{LocalWallet, Signer}; +use std::convert::TryFrom; - // add a bunch of middlewares - let gas_oracle = EthGasStation::new(None).category(GasCategory::SafeLow); - let signer = LocalWallet::new(&mut thread_rng()); - let address = signer.address(); - let escalator = GeometricGasPrice::new(1.125, 60u64, None::); - let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); - let provider = GasOracleMiddleware::new(provider, gas_oracle); - let provider = SignerMiddleware::new(provider, signer); - let provider = NonceManagerMiddleware::new(provider, address); +#[tokio::test] +async fn mock_with_middleware() { + let (provider, mock) = Provider::mocked(); - // push a response - use ethers_core::types::U64; - mock.push(U64::from(12u64)).unwrap(); - let blk = provider.get_block_number().await.unwrap(); - assert_eq!(blk.as_u64(), 12); + // add a bunch of middlewares + let gas_oracle = GasNow::new().category(GasCategory::SafeLow); + let signer = LocalWallet::new(&mut thread_rng()); + let address = signer.address(); + let escalator = GeometricGasPrice::new(1.125, 60u64, None::); + let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); + let provider = GasOracleMiddleware::new(provider, gas_oracle); + let provider = SignerMiddleware::new(provider, signer); + let provider = NonceManagerMiddleware::new(provider, address); - // now that the response is gone, there's nothing left - // TODO: This returns: - // MiddlewareError( - // MiddlewareError( - // MiddlewareError( - // MiddlewareError( - // JsonRpcClientError(EmptyResponses) - // )))) - // Can we flatten it in any way? Maybe inherent to the middleware - // infrastructure - provider.get_block_number().await.unwrap_err(); + // push a response + use ethers_core::types::U64; + mock.push(U64::from(12u64)).unwrap(); + let blk = provider.get_block_number().await.unwrap(); + assert_eq!(blk.as_u64(), 12); - // 2 calls were made - mock.assert_request("eth_blockNumber", ()).unwrap(); - mock.assert_request("eth_blockNumber", ()).unwrap(); - mock.assert_request("eth_blockNumber", ()).unwrap_err(); - } + // now that the response is gone, there's nothing left + // TODO: This returns: + // MiddlewareError( + // MiddlewareError( + // MiddlewareError( + // MiddlewareError( + // JsonRpcClientError(EmptyResponses) + // )))) + // Can we flatten it in any way? Maybe inherent to the middleware + // infrastructure + provider.get_block_number().await.unwrap_err(); - #[tokio::test] - async fn can_stack_middlewares() { - let anvil = Anvil::new().block_time(5u64).spawn(); - let gas_oracle = EthGasStation::new(None).category(GasCategory::SafeLow); - let signer: LocalWallet = anvil.keys()[0].clone().into(); - let address = signer.address(); - - // the base provider - let provider = Arc::new(Provider::::try_from(anvil.endpoint()).unwrap()); - let chain_id = provider.get_chainid().await.unwrap().as_u64(); - let signer = signer.with_chain_id(chain_id); - - // the Gas Price escalator middleware is the first middleware above the provider, - // so that it receives the transaction last, after all the other middleware - // have modified it accordingly - let escalator = GeometricGasPrice::new(1.125, 60u64, None::); - let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); - - // The gas price middleware MUST be below the signing middleware for things to work - let provider = GasOracleMiddleware::new(provider, gas_oracle); - - // The signing middleware signs txs - use std::sync::Arc; - let provider = Arc::new(SignerMiddleware::new(provider, signer)); - - // The nonce manager middleware MUST be above the signing middleware so that it overrides - // the nonce and the signer does not make any eth_getTransaction count calls - let provider = NonceManagerMiddleware::new(provider, address); - - let tx = TransactionRequest::new(); - let mut pending_txs = Vec::new(); - for _ in 0..10 { - let pending = provider.send_transaction(tx.clone(), None).await.unwrap(); - let hash = *pending; - let gas_price = provider.get_transaction(hash).await.unwrap().unwrap().gas_price; - dbg!(gas_price); - pending_txs.push(pending); - } - - let receipts = futures_util::future::join_all(pending_txs); - dbg!(receipts.await); - } + // 2 calls were made + mock.assert_request("eth_blockNumber", ()).unwrap(); + mock.assert_request("eth_blockNumber", ()).unwrap(); + mock.assert_request("eth_blockNumber", ()).unwrap_err(); +} + +#[tokio::test] +async fn can_stack_middlewares() { + let anvil = Anvil::new().block_time(5u64).spawn(); + let gas_oracle = GasNow::new().category(GasCategory::SafeLow); + let signer: LocalWallet = anvil.keys()[0].clone().into(); + let address = signer.address(); + + // the base provider + let provider = Arc::new(Provider::::try_from(anvil.endpoint()).unwrap()); + let chain_id = provider.get_chainid().await.unwrap().as_u64(); + let signer = signer.with_chain_id(chain_id); + + // the Gas Price escalator middleware is the first middleware above the provider, + // so that it receives the transaction last, after all the other middleware + // have modified it accordingly + let escalator = GeometricGasPrice::new(1.125, 60u64, None::); + let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); + + // The gas price middleware MUST be below the signing middleware for things to work + let provider = GasOracleMiddleware::new(provider, gas_oracle); + + // The signing middleware signs txs + use std::sync::Arc; + let provider = Arc::new(SignerMiddleware::new(provider, signer)); + + // The nonce manager middleware MUST be above the signing middleware so that it overrides + // the nonce and the signer does not make any eth_getTransaction count calls + let provider = NonceManagerMiddleware::new(provider, address); + + let tx = TransactionRequest::new(); + let mut pending_txs = Vec::new(); + for _ in 0..10 { + let pending = provider.send_transaction(tx.clone(), None).await.unwrap(); + let hash = *pending; + let gas_price = provider.get_transaction(hash).await.unwrap().unwrap().gas_price; + dbg!(gas_price); + pending_txs.push(pending); + } + + let receipts = futures_util::future::join_all(pending_txs); + dbg!(receipts.await); } diff --git a/ethers-middleware/tests/transformer.rs b/ethers-middleware/tests/transformer.rs index f27ef7f0..c4b37c0a 100644 --- a/ethers-middleware/tests/transformer.rs +++ b/ethers-middleware/tests/transformer.rs @@ -1,5 +1,5 @@ -#![cfg(not(target_arch = "wasm32"))] -#![allow(unused)] +#![cfg(all(not(target_arch = "wasm32"), not(feature = "celo")))] + use ethers_contract::{BaseContract, ContractFactory}; use ethers_core::{abi::Abi, types::*, utils::Anvil}; use ethers_middleware::{ @@ -24,7 +24,6 @@ fn compile_contract(path: &str, name: &str) -> (Abi, Bytes) { } #[tokio::test] -#[cfg(not(feature = "celo"))] async fn ds_proxy_transformer() { // randomness let mut rng = rand::thread_rng(); @@ -83,7 +82,6 @@ async fn ds_proxy_transformer() { } #[tokio::test] -#[cfg(not(feature = "celo"))] async fn ds_proxy_code() { // randomness let mut rng = rand::thread_rng(); From 91cd6ccce8c71c82f462d8a8838a94087565623a Mon Sep 17 00:00:00 2001 From: Genysys Date: Mon, 19 Dec 2022 19:54:24 +0400 Subject: [PATCH 06/40] feat: adds bscscan as abi source (#1955) --- CHANGELOG.md | 2 +- .../ethers-contract-abigen/src/source.rs | 38 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b157dc5..88e51cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## ethers-core ### Unreleased - +- - Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815) - `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers. - An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract. diff --git a/ethers-contract/ethers-contract-abigen/src/source.rs b/ethers-contract/ethers-contract-abigen/src/source.rs index a1189cf3..2cedae73 100644 --- a/ethers-contract/ethers-contract-abigen/src/source.rs +++ b/ethers-contract/ethers-contract-abigen/src/source.rs @@ -20,6 +20,9 @@ pub enum Source { /// An ABI to be retrieved over HTTP(S). Http(Url), + /// An address of a mainnet contract that has been verified on Bscscan.com. + Bscscan(Address), + /// An address of a mainnet contract that has been verified on Etherscan.io. Etherscan(Address), @@ -54,7 +57,12 @@ impl Source { /// /// - `etherscan:0xXX..XX` or `https://etherscan.io/address/0xXX..XX`: a address or URL of a /// verified contract on Etherscan. - /// + /// - `bscscan:0xXX..XX` or `https://bscscan.io/address/0xXX..XX`: a address or URL of a + /// verified contract on Bscscan. + /// - `polygonscan:0xXX..XX` or `https://polygonscan.io/address/0xXX..XX`: a address or URL of a + /// verified contract on Polygonscan. + /// - `snowtrace:0xXX..XX` or `https://snowtrace.io/address/0xXX..XX`: a address or URL of a + /// verified contract on Snowtrace. /// - `npm:@org/package@1.0.0/path/to/contract.json` an npmjs package with an optional version /// and path (defaulting to the latest version and `index.js`). The contract ABI will be /// retrieved through `unpkg.io`. @@ -99,6 +107,12 @@ impl Source { match url.scheme() { "file" => Ok(Source::local(source)), "http" | "https" => match url.host_str() { + Some("bscscan.com") => Source::etherscan( + url.path() + .rsplit('/') + .next() + .ok_or_else(|| eyre!("HTTP URL does not have a path"))?, + ), Some("etherscan.io") => Source::etherscan( url.path() .rsplit('/') @@ -119,6 +133,7 @@ impl Source { ), _ => Ok(Source::Http(url)), }, + "bscscan" => Source::bscscan(url.path()), "etherscan" => Source::etherscan(url.path()), "polygonscan" => Source::polygonscan(url.path()), "snowtrace" => Source::snowtrace(url.path()), @@ -140,6 +155,16 @@ impl Source { Ok(Source::Http(Url::parse(url.as_ref())?)) } + /// Creates an Bscscan source from an address string. + pub fn bscscan(address: S) -> Result + where + S: AsRef, + { + let address = + util::parse_address(address).context("failed to parse address for Bscscan source")?; + Ok(Source::Bscscan(address)) + } + /// Creates an Etherscan source from an address string. pub fn etherscan(address: S) -> Result where @@ -187,6 +212,7 @@ impl Source { match self { Source::Local(path) => get_local_contract(path), Source::Http(_) => panic!("Http abi location are not supported for wasm"), + Source::Bscscan(_) => panic!("Bscscan abi location are not supported for wasm"), Source::Etherscan(_) => panic!("Etherscan abi location are not supported for wasm"), Source::Polygonscan(_) => panic!("Polygonscan abi location are not supported for wasm"), Source::Snowtrace(_) => panic!("Snowtrace abi location are not supported for wasm"), @@ -197,6 +223,7 @@ impl Source { match self { Source::Local(path) => get_local_contract(path), Source::Http(url) => get_http_contract(url), + Source::Bscscan(address) => get_etherscan_contract(*address, "bscscan.com"), Source::Etherscan(address) => get_etherscan_contract(*address, "etherscan.io"), Source::Polygonscan(address) => get_etherscan_contract(*address, "polygonscan.com"), Source::Snowtrace(address) => get_etherscan_contract(*address, "snowtrace.io"), @@ -261,6 +288,7 @@ fn get_etherscan_contract(address: Address, domain: &str) -> Result { // probably don't reference anything when deploying on other networks. let api_key = { let key_res = match domain { + "bscscan.com" => env::var("BSCSCAN_API_KEY").ok(), "etherscan.io" => env::var("ETHERSCAN_API_KEY").ok(), "polygonscan.com" => env::var("POLYGONSCAN_API_KEY").ok(), "snowtrace.io" => env::var("SNOWTRACE_API_KEY").ok(), @@ -311,6 +339,10 @@ mod tests { "https://my.domain.eth/path/to/Contract.json", Source::http("https://my.domain.eth/path/to/Contract.json").unwrap(), ), + ( + "bscscan:0x0001020304050607080910111213141516171819", + Source::bscscan("0x0001020304050607080910111213141516171819").unwrap(), + ), ( "etherscan:0x0001020304050607080910111213141516171819", Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(), @@ -323,6 +355,10 @@ mod tests { "snowtrace:0x0001020304050607080910111213141516171819", Source::snowtrace("0x0001020304050607080910111213141516171819").unwrap(), ), + ( + "https://bscscan.io/address/0x0001020304050607080910111213141516171819", + Source::bscscan("0x0001020304050607080910111213141516171819").unwrap(), + ), ( "https://etherscan.io/address/0x0001020304050607080910111213141516171819", Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(), From 813600e6c92a13ba1945b28b6c1cb61d8c4da43b Mon Sep 17 00:00:00 2001 From: Yiannis M Date: Wed, 21 Dec 2022 16:44:42 +0200 Subject: [PATCH 07/40] fix: Add `openssl` and `rustls` feature flags in ethers-middleware (#1961) * fix: ethers-middleware: Add `openssl` and `rustls` feature flags * fix: ethers-contract-derive: Disable default features of ethers-contract-abigen Without this fix, `rustls` was enabled by default even if user had `openssl` feature flag --- CHANGELOG.md | 2 ++ Cargo.toml | 2 ++ ethers-contract/ethers-contract-derive/Cargo.toml | 2 +- ethers-middleware/Cargo.toml | 6 +++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88e51cc4..ba768abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -341,6 +341,8 @@ ### Unreleased +- Added `openssl` and `rustls` feature flags + [#1961](https://github.com/gakonst/ethers-rs/pull/1961) - Relax Clone requirements when Arc is used [#1183](https://github.com/gakonst/ethers-rs/pull/1183) - Ensure a consistent chain ID between a Signer and Provider in SignerMiddleware diff --git a/Cargo.toml b/Cargo.toml index 3205a175..d0ec85e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,12 +63,14 @@ eip712 = ["ethers-contract/eip712", "ethers-core/eip712"] ws = ["ethers-providers/ws"] ipc = ["ethers-providers/ipc"] rustls = [ + "ethers-middleware/rustls", "ethers-providers/rustls", "ethers-etherscan/rustls", "ethers-contract/rustls", "ethers-solc/rustls", ] openssl = [ + "ethers-middleware/openssl", "ethers-providers/openssl", "ethers-etherscan/openssl", "ethers-contract/openssl", diff --git a/ethers-contract/ethers-contract-derive/Cargo.toml b/ethers-contract/ethers-contract-derive/Cargo.toml index 85da947d..1c49c995 100644 --- a/ethers-contract/ethers-contract-derive/Cargo.toml +++ b/ethers-contract/ethers-contract-derive/Cargo.toml @@ -17,7 +17,7 @@ proc-macro = true [dependencies] ethers-core = { version = "^1.0.0", path = "../../ethers-core" } -ethers-contract-abigen = { version = "^1.0.0", path = "../ethers-contract-abigen" } +ethers-contract-abigen = { version = "^1.0.0", path = "../ethers-contract-abigen", default-features = false } serde_json = "1.0.53" hex = { version = "0.4.3", default-features = false, features = ["std"] } diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml index 9fc5775c..0dc3e9d9 100644 --- a/ethers-middleware/Cargo.toml +++ b/ethers-middleware/Cargo.toml @@ -31,7 +31,7 @@ tracing = { version = "0.1.37", default-features = false } tracing-futures = { version = "0.2.5", default-features = false } # for gas oracles -reqwest = { version = "0.11.13", default-features = false, features = ["json", "rustls-tls"] } +reqwest = { version = "0.11.13", default-features = false, features = ["json"] } url = { version = "2.3.1", default-features = false } serde_json = { version = "1.0.64", default-features = false } @@ -50,9 +50,13 @@ ethers-providers = { version = "^1.0.0", path = "../ethers-providers", default-f once_cell = "1.16.0" ethers-solc = { version = "^1.0.0", path = "../ethers-solc" } serial_test = "0.9.0" +reqwest = { version = "0.11.13", default-features = false, features = ["json", "rustls"] } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] tokio = { version = "1.18", default-features = false, features = ["rt", "macros", "time"] } [features] +default = ["rustls"] celo = ["ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo", "ethers-contract/celo"] +openssl = ["reqwest/native-tls"] +rustls = ["reqwest/rustls-tls"] From e007ea01b1bc95be91d0b37e230df7f005170c4b Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 22 Dec 2022 13:44:51 +0100 Subject: [PATCH 08/40] feat(core): chain macros and impls (#1958) --- Cargo.lock | 22 ++ ethers-core/Cargo.toml | 1 + ethers-core/src/types/chain.rs | 602 ++++++++++++++------------------- 3 files changed, 272 insertions(+), 353 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a885ded..cf19ecb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1420,6 +1420,7 @@ dependencies = [ "hex", "hex-literal", "k256", + "num_enum", "once_cell", "open-fastrlp", "proc-macro2", @@ -2576,6 +2577,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num_threads" version = "0.1.3" diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml index 9dd1c927..f2c67a0e 100644 --- a/ethers-core/Cargo.toml +++ b/ethers-core/Cargo.toml @@ -42,6 +42,7 @@ cargo_metadata = { version = "0.15.2", optional = true } convert_case = { version = "0.6.0", optional = true } syn = { version = "1.0.105", optional = true } proc-macro2 = { version = "1.0.47", optional = true } +num_enum = "0.5.7" [dev-dependencies] tempfile = { version = "3.3.0", default-features = false } diff --git a/ethers-core/src/types/chain.rs b/ethers-core/src/types/chain.rs index 70dd6a10..11417376 100644 --- a/ethers-core/src/types/chain.rs +++ b/ethers-core/src/types/chain.rs @@ -1,138 +1,160 @@ -use super::U256; +use super::{U128, U256, U512, U64}; +use num_enum::{TryFromPrimitive, TryFromPrimitiveError}; use serde::{Deserialize, Serialize, Serializer}; use std::{ convert::{TryFrom, TryInto}, fmt, - str::FromStr, time::Duration, }; -use strum::EnumVariantNames; -use thiserror::Error; - -#[derive(Debug, Clone, Error)] -#[error("Failed to parse chain: {0}")] -pub struct ParseChainError(String); +use strum::{AsRefStr, EnumString, EnumVariantNames}; // When adding a new chain: // 1. add new variant to the Chain enum; -// 2. update Display/FromStr impl; -// 3. add etherscan_keys if supported. +// 2. add extra information in the last `impl` block (explorer URLs, block time) when applicable; +// 3. (optional) add aliases: `#[strum(serialize = "main", serialize = "alias", ...)]`; +// "main" must be present and will be used in `Display`, `Serialize` and `FromStr`, +// while the aliases will be added only to `FromStr`. -/// Enum for all known chains. -#[repr(u64)] -#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, Deserialize, EnumVariantNames)] +/// An Ethereum EIP-155 chain. +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + AsRefStr, // also for fmt::Display and serde::Serialize + EnumVariantNames, // Self::VARIANTS + EnumString, // FromStr, TryFrom<&str> + TryFromPrimitive, // TryFrom + Deserialize, +)] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "kebab-case")] +#[repr(u64)] pub enum Chain { - #[default] Mainnet = 1, Morden = 2, Ropsten = 3, Rinkeby = 4, Goerli = 5, - Optimism = 10, - Cronos = 25, - Rsk = 30, Kovan = 42, - #[strum(serialize = "bsc")] - BinanceSmartChain = 56, + Sepolia = 11155111, + + Optimism = 10, OptimismKovan = 69, - Sokol = 77, - #[strum(serialize = "bsc-testnet")] - BinanceSmartChainTestnet = 97, - Poa = 99, - #[strum(serialize = "gnosis")] - XDai = 100, - Polygon = 137, - Fantom = 250, - CronosTestnet = 338, OptimismGoerli = 420, - MoonbeamDev = 1281, - Moonbeam = 1284, - Moonriver = 1285, - Moonbase = 1287, - Dev = 1337, - FantomTestnet = 4002, - EvmosTestnet = 9000, - Evmos = 9001, - Chiado = 10200, - Oasis = 26863, - AnvilHardhat = 31337, + Arbitrum = 42161, - EmeraldTestnet = 42261, - Emerald = 42262, - AvalancheFuji = 43113, - Avalanche = 43114, - PolygonMumbai = 80001, ArbitrumTestnet = 421611, ArbitrumGoerli = 421613, - Sepolia = 11155111, - Aurora = 1313161554, - AuroraTestnet = 1313161555, + + Cronos = 25, + CronosTestnet = 338, + + Rsk = 30, + + #[strum(serialize = "bsc")] + BinanceSmartChain = 56, + #[strum(serialize = "bsc-testnet")] + BinanceSmartChainTestnet = 97, + + Poa = 99, + Sokol = 77, + + #[strum(serialize = "gnosis", serialize = "xdai", serialize = "gnosis-chain")] + XDai = 100, + + Polygon = 137, + #[strum(serialize = "mumbai", serialize = "polygon-mumbai")] + PolygonMumbai = 80001, + + Fantom = 250, + FantomTestnet = 4002, + + Moonbeam = 1284, + MoonbeamDev = 1281, + + Moonriver = 1285, + + Moonbase = 1287, + + #[strum(serialize = "dev")] + Dev = 1337, + #[strum(serialize = "anvil-hardhat", serialize = "anvil", serialize = "hardhat")] + AnvilHardhat = 31337, + + Evmos = 9001, + EvmosTestnet = 9000, + + Chiado = 10200, + + Oasis = 26863, + + Emerald = 42262, + EmeraldTestnet = 42261, + + Avalanche = 43114, + #[strum(serialize = "fuji", serialize = "avalanche-fuji")] + AvalancheFuji = 43113, + Celo = 42220, CeloAlfajores = 44787, CeloBaklava = 62320, + + Aurora = 1313161554, + AuroraTestnet = 1313161555, } // === impl Chain === -impl fmt::Display for Chain { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let chain = match self { - Chain::Mainnet => "mainnet", - Chain::Morden => "morden", - Chain::Ropsten => "ropsten", - Chain::Rinkeby => "rinkeby", - Chain::Goerli => "goerli", - Chain::Kovan => "kovan", - Chain::XDai => "gnosis", - Chain::Chiado => "chiado", - Chain::Polygon => "polygon", - Chain::PolygonMumbai => "mumbai", - Chain::Avalanche => "avalanche", - Chain::AvalancheFuji => "fuji", - Chain::Sepolia => "sepolia", - Chain::Moonbeam => "moonbeam", - Chain::Moonbase => "moonbase", - Chain::MoonbeamDev => "moonbeam-dev", - Chain::Moonriver => "moonriver", - Chain::Optimism => "optimism", - Chain::OptimismGoerli => "optimism-goerli", - Chain::OptimismKovan => "optimism-kovan", - Chain::Fantom => "fantom", - Chain::Dev => "dev", - Chain::FantomTestnet => "fantom-testnet", - Chain::BinanceSmartChain => "bsc", - Chain::BinanceSmartChainTestnet => "bsc-testnet", - Chain::Arbitrum => "arbitrum", - Chain::ArbitrumTestnet => "arbitrum-testnet", - Chain::ArbitrumGoerli => "arbitrum-goerli", - Chain::Cronos => "cronos", - Chain::CronosTestnet => "cronos-testnet", - Chain::Poa => "poa", - Chain::Sokol => "sokol", - Chain::Rsk => "rsk", - Chain::Oasis => "oasis", - Chain::Emerald => "emerald", - Chain::EmeraldTestnet => "emerald-testnet", - Chain::AnvilHardhat => "anvil-hardhat", - Chain::Evmos => "evmos", - Chain::EvmosTestnet => "evmos-testnet", - Chain::Aurora => "aurora", - Chain::AuroraTestnet => "aurora-testnet", - Chain::Celo => "celo", - Chain::CeloAlfajores => "celo-alfajores", - Chain::CeloBaklava => "celo-baklava", - }; - - f.pad(chain) +// This must be implemented manually so we avoid a conflict with `TryFromPrimitive` where it treats +// the `#[default]` attribute as its own `#[num_enum(default)]` +impl Default for Chain { + fn default() -> Self { + Self::Mainnet } } -impl From for u32 { - fn from(chain: Chain) -> Self { - chain as u32 - } +macro_rules! impl_into_numeric { + ($($ty:ty)+) => {$( + impl From for $ty { + fn from(chain: Chain) -> Self { + u64::from(chain).into() + } + } + )+}; +} + +macro_rules! impl_try_from_numeric { + ($($native:ty)+ ; $($primitive:ty)*) => { + $( + impl TryFrom<$native> for Chain { + type Error = TryFromPrimitiveError; + + fn try_from(value: $native) -> Result { + (value as u64).try_into() + } + } + )+ + + $( + impl TryFrom<$primitive> for Chain { + type Error = TryFromPrimitiveError; + + fn try_from(value: $primitive) -> Result { + if value.bits() > 64 { + // `TryFromPrimitiveError` only has a `number` field which has the same type + // as the `#[repr(_)]` attribute on the enum. + return Err(TryFromPrimitiveError { number: value.low_u64() }) + } + value.low_u64().try_into() + } + } + )* + }; } impl From for u64 { @@ -141,134 +163,21 @@ impl From for u64 { } } -impl From for U256 { - fn from(chain: Chain) -> Self { - u64::from(chain).into() +impl_into_numeric!(u128 U64 U128 U256 U512); + +impl TryFrom for Chain { + type Error = TryFromPrimitiveError; + + fn try_from(value: U64) -> Result { + value.low_u64().try_into() } } -impl TryFrom for Chain { - type Error = ParseChainError; +impl_try_from_numeric!(u8 u16 u32 usize; U128 U256 U512); - fn try_from(chain: u32) -> Result { - (chain as u64).try_into() - } -} - -impl TryFrom for Chain { - type Error = ParseChainError; - - fn try_from(chain: u64) -> Result { - Ok(match chain { - 1 => Chain::Mainnet, - 2 => Chain::Morden, - 3 => Chain::Ropsten, - 4 => Chain::Rinkeby, - 5 => Chain::Goerli, - 42 => Chain::Kovan, - 100 => Chain::XDai, - 10200 => Chain::Chiado, - 137 => Chain::Polygon, - 1337 => Chain::Dev, - 31337 => Chain::AnvilHardhat, - 250 => Chain::Fantom, - 4002 => Chain::FantomTestnet, - 80001 => Chain::PolygonMumbai, - 43114 => Chain::Avalanche, - 43113 => Chain::AvalancheFuji, - 11155111 => Chain::Sepolia, - 1284 => Chain::Moonbeam, - 1287 => Chain::Moonbase, - 1281 => Chain::MoonbeamDev, - 1285 => Chain::Moonriver, - 10 => Chain::Optimism, - 420 => Chain::OptimismGoerli, - 69 => Chain::OptimismKovan, - 56 => Chain::BinanceSmartChain, - 97 => Chain::BinanceSmartChainTestnet, - 42161 => Chain::Arbitrum, - 421611 => Chain::ArbitrumTestnet, - 421613 => Chain::ArbitrumGoerli, - 25 => Chain::Cronos, - 338 => Chain::CronosTestnet, - 99 => Chain::Poa, - 77 => Chain::Sokol, - 30 => Chain::Rsk, - 26863 => Chain::Oasis, - 42262 => Chain::Emerald, - 42261 => Chain::EmeraldTestnet, - 9001 => Chain::Evmos, - 9000 => Chain::EvmosTestnet, - 1313161554 => Chain::Aurora, - 1313161555 => Chain::AuroraTestnet, - 42220 => Chain::Celo, - 44787 => Chain::CeloAlfajores, - 62320 => Chain::CeloBaklava, - _ => return Err(ParseChainError(chain.to_string())), - }) - } -} - -impl TryFrom for Chain { - type Error = ParseChainError; - - fn try_from(chain: U256) -> Result { - if chain.bits() > 64 { - return Err(ParseChainError(chain.to_string())) - } - chain.as_u64().try_into() - } -} - -impl FromStr for Chain { - type Err = ParseChainError; - - fn from_str(chain: &str) -> Result { - Ok(match chain { - "mainnet" => Chain::Mainnet, - "morden" => Chain::Morden, - "ropsten" => Chain::Ropsten, - "rinkeby" => Chain::Rinkeby, - "goerli" => Chain::Goerli, - "kovan" => Chain::Kovan, - "xdai" | "gnosis" | "gnosis-chain" => Chain::XDai, - "chiado" => Chain::Chiado, - "polygon" => Chain::Polygon, - "mumbai" | "polygon-mumbai" => Chain::PolygonMumbai, - "avalanche" => Chain::Avalanche, - "fuji" | "avalanche-fuji" => Chain::AvalancheFuji, - "sepolia" => Chain::Sepolia, - "moonbeam" => Chain::Moonbeam, - "moonbase" => Chain::Moonbase, - "moonbeam-dev" => Chain::MoonbeamDev, - "moonriver" => Chain::Moonriver, - "optimism" => Chain::Optimism, - "optimism-goerli" => Chain::OptimismGoerli, - "optimism-kovan" => Chain::OptimismKovan, - "fantom" => Chain::Fantom, - "fantom-testnet" => Chain::FantomTestnet, - "dev" => Chain::Dev, - "anvil" | "hardhat" | "anvil-hardhat" => Chain::AnvilHardhat, - "bsc" => Chain::BinanceSmartChain, - "bsc-testnet" => Chain::BinanceSmartChainTestnet, - "arbitrum" => Chain::Arbitrum, - "arbitrum-testnet" => Chain::ArbitrumTestnet, - "arbitrum-goerli" => Chain::ArbitrumGoerli, - "cronos" => Chain::Cronos, - "cronos-testnet" => Chain::CronosTestnet, - "poa" => Chain::Poa, - "sokol" => Chain::Sokol, - "rsk" => Chain::Rsk, - "oasis" => Chain::Oasis, - "emerald" => Chain::Emerald, - "emerald-testnet" => Chain::EmeraldTestnet, - "aurora" => Chain::Aurora, - "aurora-testnet" => Chain::AuroraTestnet, - "celo" => Chain::Celo, - "celo-alfajores" => Chain::CeloAlfajores, - "celo-baklava" => Chain::CeloBaklava, - _ => return Err(ParseChainError(chain.to_owned())), - }) +impl fmt::Display for Chain { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad(self.as_ref()) } } @@ -277,163 +186,135 @@ impl Serialize for Chain { where S: Serializer, { - s.serialize_str(self.to_string().as_ref()) + s.serialize_str(self.as_ref()) } } +// NB: all utility functions *should* be explicitly exhaustive (not use `_` matcher) so we don't +// forget to update them when adding a new `Chain` variant. impl Chain { - /// The blocktime varies from chain to chain. + /// Returns the chain's average blocktime, if applicable. /// /// It can be beneficial to know the average blocktime to adjust the polling of an HTTP provider /// for example. /// - /// **Note:** this will not return the accurate average depending on the time but is rather a - /// sensible default derived from blocktime charts like - /// - pub fn average_blocktime_hint(&self) -> Option { + /// **Note:** this is not an accurate average, but is rather a sensible default derived from + /// blocktime charts such as [Etherscan's](https://etherscan.com/chart/blocktime) + /// or [Polygonscan's](https://polygonscan.com/chart/blocktime). + pub const fn average_blocktime_hint(&self) -> Option { + use Chain::*; + let ms = match self { - Chain::Arbitrum | Chain::ArbitrumTestnet | Chain::ArbitrumGoerli => 1_300, - Chain::Mainnet | Chain::Optimism => 13_000, - Chain::Polygon | Chain::PolygonMumbai => 2_100, - Chain::Moonbeam | Chain::Moonriver => 12_500, - Chain::BinanceSmartChain | Chain::BinanceSmartChainTestnet => 3_000, - Chain::Avalanche | Chain::AvalancheFuji => 2_000, - Chain::Fantom | Chain::FantomTestnet => 1_200, - Chain::Cronos | Chain::CronosTestnet => 5_700, - Chain::Evmos | Chain::EvmosTestnet => 1_900, - Chain::Aurora | Chain::AuroraTestnet => 1_100, - Chain::Oasis => 5_500, - Chain::Emerald => 6_000, - Chain::Dev | Chain::AnvilHardhat => 200, - Chain::Celo | Chain::CeloAlfajores | Chain::CeloBaklava => 5_000, + Arbitrum | ArbitrumTestnet | ArbitrumGoerli => 1_300, + Mainnet | Optimism => 13_000, + Polygon | PolygonMumbai => 2_100, + Moonbeam | Moonriver => 12_500, + BinanceSmartChain | BinanceSmartChainTestnet => 3_000, + Avalanche | AvalancheFuji => 2_000, + Fantom | FantomTestnet => 1_200, + Cronos | CronosTestnet => 5_700, + Evmos | EvmosTestnet => 1_900, + Aurora | AuroraTestnet => 1_100, + Oasis => 5_500, + Emerald => 6_000, + Dev | AnvilHardhat => 200, + Celo | CeloAlfajores | CeloBaklava => 5_000, // Explictly handle all network to make it easier not to forget this match when new // networks are added. - Chain::Morden | - Chain::Ropsten | - Chain::Rinkeby | - Chain::Goerli | - Chain::Kovan | - Chain::XDai | - Chain::Chiado | - Chain::Sepolia | - Chain::Moonbase | - Chain::MoonbeamDev | - Chain::OptimismGoerli | - Chain::OptimismKovan | - Chain::Poa | - Chain::Sokol | - Chain::Rsk | - Chain::EmeraldTestnet => return None, + Morden | Ropsten | Rinkeby | Goerli | Kovan | XDai | Chiado | Sepolia | Moonbase | + MoonbeamDev | OptimismGoerli | OptimismKovan | Poa | Sokol | Rsk | EmeraldTestnet => { + return None + } }; Some(Duration::from_millis(ms)) } - /// Returns the corresponding etherscan URLs + /// Returns the chain's blockchain explorer and its API (Etherscan and Etherscan-like) URLs. /// /// Returns `(API URL, BASE_URL)`, like `("https://api(-chain).etherscan.io/api", "https://etherscan.io")` - pub fn etherscan_urls(&self) -> Option<(&'static str, &'static str)> { + pub const fn etherscan_urls(&self) -> Option<(&'static str, &'static str)> { + use Chain::*; + let urls = match self { - Chain::Mainnet => ("https://api.etherscan.io/api", "https://etherscan.io"), - Chain::Ropsten => { - ("https://api-ropsten.etherscan.io/api", "https://ropsten.etherscan.io") - } - Chain::Kovan => ("https://api-kovan.etherscan.io/api", "https://kovan.etherscan.io"), - Chain::Rinkeby => { - ("https://api-rinkeby.etherscan.io/api", "https://rinkeby.etherscan.io") - } - Chain::Goerli => ("https://api-goerli.etherscan.io/api", "https://goerli.etherscan.io"), - Chain::Sepolia => { - ("https://api-sepolia.etherscan.io/api", "https://sepolia.etherscan.io") - } - Chain::Polygon => ("https://api.polygonscan.com/api", "https://polygonscan.com"), - Chain::PolygonMumbai => { + Mainnet => ("https://api.etherscan.io/api", "https://etherscan.io"), + Ropsten => ("https://api-ropsten.etherscan.io/api", "https://ropsten.etherscan.io"), + Kovan => ("https://api-kovan.etherscan.io/api", "https://kovan.etherscan.io"), + Rinkeby => ("https://api-rinkeby.etherscan.io/api", "https://rinkeby.etherscan.io"), + Goerli => ("https://api-goerli.etherscan.io/api", "https://goerli.etherscan.io"), + Sepolia => ("https://api-sepolia.etherscan.io/api", "https://sepolia.etherscan.io"), + Polygon => ("https://api.polygonscan.com/api", "https://polygonscan.com"), + PolygonMumbai => { ("https://api-testnet.polygonscan.com/api", "https://mumbai.polygonscan.com") } - Chain::Avalanche => ("https://api.snowtrace.io/api", "https://snowtrace.io"), - Chain::AvalancheFuji => { + Avalanche => ("https://api.snowtrace.io/api", "https://snowtrace.io"), + AvalancheFuji => { ("https://api-testnet.snowtrace.io/api", "https://testnet.snowtrace.io") } - Chain::Optimism => { + Optimism => { ("https://api-optimistic.etherscan.io/api", "https://optimistic.etherscan.io") } - Chain::OptimismGoerli => ( + OptimismGoerli => ( "https://api-goerli-optimistic.etherscan.io/api", "https://goerli-optimism.etherscan.io", ), - Chain::OptimismKovan => ( + OptimismKovan => ( "https://api-kovan-optimistic.etherscan.io/api", "https://kovan-optimistic.etherscan.io", ), - Chain::Fantom => ("https://api.ftmscan.com/api", "https://ftmscan.com"), - Chain::FantomTestnet => { - ("https://api-testnet.ftmscan.com/api", "https://testnet.ftmscan.com") - } - Chain::BinanceSmartChain => ("https://api.bscscan.com/api", "https://bscscan.com"), - Chain::BinanceSmartChainTestnet => { + Fantom => ("https://api.ftmscan.com/api", "https://ftmscan.com"), + FantomTestnet => ("https://api-testnet.ftmscan.com/api", "https://testnet.ftmscan.com"), + BinanceSmartChain => ("https://api.bscscan.com/api", "https://bscscan.com"), + BinanceSmartChainTestnet => { ("https://api-testnet.bscscan.com/api", "https://testnet.bscscan.com") } - Chain::Arbitrum => ("https://api.arbiscan.io/api", "https://arbiscan.io"), - Chain::ArbitrumTestnet => { + Arbitrum => ("https://api.arbiscan.io/api", "https://arbiscan.io"), + ArbitrumTestnet => { ("https://api-testnet.arbiscan.io/api", "https://testnet.arbiscan.io") } - Chain::ArbitrumGoerli => ( + ArbitrumGoerli => ( "https://goerli-rollup-explorer.arbitrum.io/api", "https://goerli-rollup-explorer.arbitrum.io", ), - Chain::Cronos => ("https://api.cronoscan.com/api", "https://cronoscan.com"), - Chain::CronosTestnet => { + Cronos => ("https://api.cronoscan.com/api", "https://cronoscan.com"), + CronosTestnet => { ("https://api-testnet.cronoscan.com/api", "https://testnet.cronoscan.com") } - Chain::Moonbeam => { - ("https://api-moonbeam.moonscan.io/api", "https://moonbeam.moonscan.io/") - } - Chain::Moonbase => { - ("https://api-moonbase.moonscan.io/api", "https://moonbase.moonscan.io/") - } - Chain::Moonriver => { - ("https://api-moonriver.moonscan.io/api", "https://moonriver.moonscan.io") - } + Moonbeam => ("https://api-moonbeam.moonscan.io/api", "https://moonbeam.moonscan.io/"), + Moonbase => ("https://api-moonbase.moonscan.io/api", "https://moonbase.moonscan.io/"), + Moonriver => ("https://api-moonriver.moonscan.io/api", "https://moonriver.moonscan.io"), // blockscout API is etherscan compatible - Chain::XDai => { + XDai => { ("https://blockscout.com/xdai/mainnet/api", "https://blockscout.com/xdai/mainnet") } - Chain::Chiado => { + Chiado => { ("https://blockscout.chiadochain.net/api", "https://blockscout.chiadochain.net") } - Chain::Sokol => { - ("https://blockscout.com/poa/sokol/api", "https://blockscout.com/poa/sokol") - } - Chain::Poa => { - ("https://blockscout.com/poa/core/api", "https://blockscout.com/poa/core") - } - Chain::Rsk => { - ("https://blockscout.com/rsk/mainnet/api", "https://blockscout.com/rsk/mainnet") - } - Chain::Oasis => ("https://scan.oasischain.io/api", "https://scan.oasischain.io/"), - Chain::Emerald => { + Sokol => ("https://blockscout.com/poa/sokol/api", "https://blockscout.com/poa/sokol"), + Poa => ("https://blockscout.com/poa/core/api", "https://blockscout.com/poa/core"), + Rsk => ("https://blockscout.com/rsk/mainnet/api", "https://blockscout.com/rsk/mainnet"), + Oasis => ("https://scan.oasischain.io/api", "https://scan.oasischain.io/"), + Emerald => { ("https://explorer.emerald.oasis.dev/api", "https://explorer.emerald.oasis.dev/") } - Chain::EmeraldTestnet => ( + EmeraldTestnet => ( "https://testnet.explorer.emerald.oasis.dev/api", "https://testnet.explorer.emerald.oasis.dev/", ), - Chain::Aurora => ("https://api.aurorascan.dev/api", "https://aurorascan.dev"), - Chain::AuroraTestnet => { + Aurora => ("https://api.aurorascan.dev/api", "https://aurorascan.dev"), + AuroraTestnet => { ("https://testnet.aurorascan.dev/api", "https://testnet.aurorascan.dev") } - Chain::Evmos => ("https://evm.evmos.org/api", "https://evm.evmos.org/"), - Chain::EvmosTestnet => ("https://evm.evmos.dev/api", "https://evm.evmos.dev/"), - Chain::Celo => { - ("https://explorer.celo.org/mainnet", "https://explorer.celo.org/mainnet/api") - } - Chain::CeloAlfajores => { + Evmos => ("https://evm.evmos.org/api", "https://evm.evmos.org/"), + EvmosTestnet => ("https://evm.evmos.dev/api", "https://evm.evmos.dev/"), + Celo => ("https://explorer.celo.org/mainnet", "https://explorer.celo.org/mainnet/api"), + CeloAlfajores => { ("https://explorer.celo.org/alfajores", "https://explorer.celo.org/alfajores/api") } - Chain::CeloBaklava => { + CeloBaklava => { ("https://explorer.celo.org/baklava", "https://explorer.celo.org/baklava/api") } - Chain::AnvilHardhat | Chain::Dev | Chain::Morden | Chain::MoonbeamDev => { + AnvilHardhat | Dev | Morden | MoonbeamDev => { // this is explicitly exhaustive so we don't forget to add new urls when adding a // new chain return None @@ -443,34 +324,49 @@ impl Chain { Some(urls) } - /// Helper function for checking if a chainid corresponds to a legacy chainid - /// without eip1559 - pub fn is_legacy(&self) -> bool { - // TODO: Add other chains which do not support EIP1559. - matches!( - self, - Chain::Optimism | - Chain::OptimismGoerli | - Chain::OptimismKovan | - Chain::Fantom | - Chain::FantomTestnet | - Chain::BinanceSmartChain | - Chain::BinanceSmartChainTestnet | - Chain::Arbitrum | - Chain::ArbitrumTestnet | - Chain::ArbitrumGoerli | - Chain::Rsk | - Chain::Oasis | - Chain::Emerald | - Chain::EmeraldTestnet | - Chain::Celo | - Chain::CeloAlfajores | - Chain::CeloBaklava, - ) + /// Returns whether the chain implements EIP-1559 (with the type 2 EIP-2718 transaction type). + pub const fn is_legacy(&self) -> bool { + use Chain::*; + + match self { + // Known legacy chains / non EIP-1559 compliant + Optimism | + OptimismGoerli | + OptimismKovan | + Fantom | + FantomTestnet | + BinanceSmartChain | + BinanceSmartChainTestnet | + Arbitrum | + ArbitrumTestnet | + ArbitrumGoerli | + Rsk | + Oasis | + Emerald | + EmeraldTestnet | + Celo | + CeloAlfajores | + CeloBaklava => true, + + // Known EIP-1559 chains + Mainnet | Goerli | Sepolia | Polygon | PolygonMumbai | Avalanche | AvalancheFuji => { + false + } + + // Unknown / not applicable, default to false for backwards compatibility + Dev | AnvilHardhat | Morden | Ropsten | Rinkeby | Cronos | CronosTestnet | Kovan | + Sokol | Poa | XDai | Moonbeam | MoonbeamDev | Moonriver | Moonbase | Evmos | + EvmosTestnet | Chiado | Aurora | AuroraTestnet => false, + } } } -#[test] -fn test_default_chain() { - assert_eq!(serde_json::to_string(&Chain::Mainnet).unwrap(), "\"mainnet\""); +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_default_chain() { + assert_eq!(serde_json::to_string(&Chain::default()).unwrap(), "\"mainnet\""); + } } From d5531119063fbe7ecb614840ea09bb2ce0a3f0e1 Mon Sep 17 00:00:00 2001 From: Franfran <51274081+iFrostizz@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:22:57 +0100 Subject: [PATCH 09/40] fix: rebase to master for onbjerg's ast (#1943) --- Cargo.lock | 10 + ethers-solc/Cargo.toml | 3 +- .../src/artifact_output/configurable.rs | 8 +- ethers-solc/src/artifacts/ast.rs | 217 - ethers-solc/src/artifacts/ast/macros.rs | 104 + ethers-solc/src/artifacts/ast/misc.rs | 113 + ethers-solc/src/artifacts/ast/mod.rs | 1097 +++ ethers-solc/src/artifacts/ast/util.rs | 1 + ethers-solc/src/artifacts/ast/visitor.rs | 1 + ethers-solc/src/artifacts/ast/yul.rs | 192 + ethers-solc/src/artifacts/mod.rs | 7 +- .../test-data/ast/abstract_contract.json | 73 + .../test-data/ast/address_payable.json | 574 ++ .../test-data/ast/array_type_name.json | 79 + ethers-solc/test-data/ast/ast-erc4626.json | 6612 ----------------- .../test-data/ast/base_constructor_call.json | 226 + ethers-solc/test-data/ast/bit_not.json | 390 + ethers-solc/test-data/ast/call.json | 171 + ethers-solc/test-data/ast/constructor.json | 73 + .../test-data/ast/contract_dep_order.json | 218 + .../test-data/ast/documentation_1.json | 43 + .../test-data/ast/documentation_2.json | 43 + .../test-data/ast/documentation_3.json | 179 + .../ast/documentation_local_variable.json | 491 ++ .../ast/documentation_on_statements.json | 376 + .../test-data/ast/documentation_triple.json | 386 + ethers-solc/test-data/ast/empty_block.json | 96 + ethers-solc/test-data/ast/enum_value.json | 63 + .../test-data/ast/enum_value_declaration.json | 164 + .../test-data/ast/event_definition.json | 54 + ethers-solc/test-data/ast/fallback.json | 73 + .../ast/fallback_and_reveice_ether.json | 108 + .../test-data/ast/fallback_payable.json | 73 + ethers-solc/test-data/ast/function.json | 158 + ethers-solc/test-data/ast/function_type.json | 232 + ethers-solc/test-data/ast/global_enum.json | 34 + ethers-solc/test-data/ast/global_struct.json | 59 + .../test-data/ast/inheritance_specifier.json | 80 + ethers-solc/test-data/ast/leave.json | 108 + ethers-solc/test-data/ast/license.json | 37 + .../ast/long_type_name_binary_operation.json | 175 + .../ast/long_type_name_identifier.json | 184 + ethers-solc/test-data/ast/loop.json | 171 + ethers-solc/test-data/ast/mappings.json | 253 + .../test-data/ast/modifier_definition.json | 176 + .../test-data/ast/modifier_invocation.json | 176 + ethers-solc/test-data/ast/mutability.json | 185 + .../test-data/ast/nested_functions.json | 176 + ethers-solc/test-data/ast/non_utf8.json | 237 + ethers-solc/test-data/ast/override.json | 337 + .../test-data/ast/placeholder_statement.json | 68 + ethers-solc/test-data/ast/receive_ether.json | 73 + .../test-data/ast/short_type_name.json | 129 + .../test-data/ast/short_type_name_ref.json | 140 + ethers-solc/test-data/ast/slot_offset.json | 252 + ethers-solc/test-data/ast/smoke.json | 36 + .../test-data/ast/source_location.json | 172 + ethers-solc/test-data/ast/string.json | 136 + ethers-solc/test-data/ast/stringlit.json | 113 + ethers-solc/test-data/ast/switch.json | 204 + ethers-solc/test-data/ast/switch_default.json | 135 + .../test-data/ast/two_base_functions.json | 272 + ethers-solc/test-data/ast/unicode.json | 136 + ethers-solc/test-data/ast/used_errors.json | 235 + .../test-data/ast/userDefinedValueType.json | 355 + .../test-data/ast/using_for_directive.json | 186 + ethers-solc/test-data/ast/var_access.json | 162 + .../test-data/ast/yul_hex_literal.json | 155 + ethers-solc/test-data/bytes.sol | 0 69 files changed, 11219 insertions(+), 6836 deletions(-) delete mode 100644 ethers-solc/src/artifacts/ast.rs create mode 100644 ethers-solc/src/artifacts/ast/macros.rs create mode 100644 ethers-solc/src/artifacts/ast/misc.rs create mode 100644 ethers-solc/src/artifacts/ast/mod.rs create mode 100644 ethers-solc/src/artifacts/ast/util.rs create mode 100644 ethers-solc/src/artifacts/ast/visitor.rs create mode 100644 ethers-solc/src/artifacts/ast/yul.rs create mode 100644 ethers-solc/test-data/ast/abstract_contract.json create mode 100644 ethers-solc/test-data/ast/address_payable.json create mode 100644 ethers-solc/test-data/ast/array_type_name.json delete mode 100644 ethers-solc/test-data/ast/ast-erc4626.json create mode 100644 ethers-solc/test-data/ast/base_constructor_call.json create mode 100644 ethers-solc/test-data/ast/bit_not.json create mode 100644 ethers-solc/test-data/ast/call.json create mode 100644 ethers-solc/test-data/ast/constructor.json create mode 100644 ethers-solc/test-data/ast/contract_dep_order.json create mode 100644 ethers-solc/test-data/ast/documentation_1.json create mode 100644 ethers-solc/test-data/ast/documentation_2.json create mode 100644 ethers-solc/test-data/ast/documentation_3.json create mode 100644 ethers-solc/test-data/ast/documentation_local_variable.json create mode 100644 ethers-solc/test-data/ast/documentation_on_statements.json create mode 100644 ethers-solc/test-data/ast/documentation_triple.json create mode 100644 ethers-solc/test-data/ast/empty_block.json create mode 100644 ethers-solc/test-data/ast/enum_value.json create mode 100644 ethers-solc/test-data/ast/enum_value_declaration.json create mode 100644 ethers-solc/test-data/ast/event_definition.json create mode 100644 ethers-solc/test-data/ast/fallback.json create mode 100644 ethers-solc/test-data/ast/fallback_and_reveice_ether.json create mode 100644 ethers-solc/test-data/ast/fallback_payable.json create mode 100644 ethers-solc/test-data/ast/function.json create mode 100644 ethers-solc/test-data/ast/function_type.json create mode 100644 ethers-solc/test-data/ast/global_enum.json create mode 100644 ethers-solc/test-data/ast/global_struct.json create mode 100644 ethers-solc/test-data/ast/inheritance_specifier.json create mode 100644 ethers-solc/test-data/ast/leave.json create mode 100644 ethers-solc/test-data/ast/license.json create mode 100644 ethers-solc/test-data/ast/long_type_name_binary_operation.json create mode 100644 ethers-solc/test-data/ast/long_type_name_identifier.json create mode 100644 ethers-solc/test-data/ast/loop.json create mode 100644 ethers-solc/test-data/ast/mappings.json create mode 100644 ethers-solc/test-data/ast/modifier_definition.json create mode 100644 ethers-solc/test-data/ast/modifier_invocation.json create mode 100644 ethers-solc/test-data/ast/mutability.json create mode 100644 ethers-solc/test-data/ast/nested_functions.json create mode 100644 ethers-solc/test-data/ast/non_utf8.json create mode 100644 ethers-solc/test-data/ast/override.json create mode 100644 ethers-solc/test-data/ast/placeholder_statement.json create mode 100644 ethers-solc/test-data/ast/receive_ether.json create mode 100644 ethers-solc/test-data/ast/short_type_name.json create mode 100644 ethers-solc/test-data/ast/short_type_name_ref.json create mode 100644 ethers-solc/test-data/ast/slot_offset.json create mode 100644 ethers-solc/test-data/ast/smoke.json create mode 100644 ethers-solc/test-data/ast/source_location.json create mode 100644 ethers-solc/test-data/ast/string.json create mode 100644 ethers-solc/test-data/ast/stringlit.json create mode 100644 ethers-solc/test-data/ast/switch.json create mode 100644 ethers-solc/test-data/ast/switch_default.json create mode 100644 ethers-solc/test-data/ast/two_base_functions.json create mode 100644 ethers-solc/test-data/ast/unicode.json create mode 100644 ethers-solc/test-data/ast/used_errors.json create mode 100644 ethers-solc/test-data/ast/userDefinedValueType.json create mode 100644 ethers-solc/test-data/ast/using_for_directive.json create mode 100644 ethers-solc/test-data/ast/var_access.json create mode 100644 ethers-solc/test-data/ast/yul_hex_literal.json create mode 100644 ethers-solc/test-data/bytes.sol diff --git a/Cargo.lock b/Cargo.lock index cf19ecb7..fcb49656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1595,6 +1595,7 @@ dependencies = [ "semver", "serde", "serde_json", + "serde_path_to_error", "sha2 0.10.6", "solang-parser", "svm-rs", @@ -3748,6 +3749,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "184c643044780f7ceb59104cef98a5a6f12cb2288a7bc701ab93a362b49fd47d" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index 9caca7d4..32b0f99d 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -38,7 +38,7 @@ fs_extra = { version = "1.2.0", optional = true } sha2 = { version = "0.10.6", default-features = false, optional = true } dunce = "1.0.3" solang-parser = { default-features = false, version = "=0.1.18" } -rayon = "1.6.1" +rayon = "1.6.0" rand = { version = "0.8.5", optional = true } path-slash = "0.2.1" cfg-if = "1.0.0" @@ -62,6 +62,7 @@ rand = "0.8.5" pretty_assertions = "1.3.0" tempfile = "3.3.0" tokio = { version = "1.18", features = ["full"] } +serde_path_to_error = "0.1.8" [[bench]] name = "compile_many" diff --git a/ethers-solc/src/artifact_output/configurable.rs b/ethers-solc/src/artifact_output/configurable.rs index 7d4fb06c..3d3d0bae 100644 --- a/ethers-solc/src/artifact_output/configurable.rs +++ b/ethers-solc/src/artifact_output/configurable.rs @@ -16,9 +16,9 @@ use crate::{ BytecodeOutputSelection, ContractOutputSelection, EvmOutputSelection, EwasmOutputSelection, }, - Ast, CompactContractBytecodeCow, DevDoc, Evm, Ewasm, FunctionDebugData, GasEstimates, - GeneratedSource, LosslessAbi, LosslessMetadata, Metadata, Offsets, Settings, StorageLayout, - UserDoc, + CompactContractBytecodeCow, DevDoc, Evm, Ewasm, FunctionDebugData, GasEstimates, + GeneratedSource, LosslessAbi, LosslessMetadata, Metadata, Offsets, Settings, SourceUnit, + StorageLayout, UserDoc, }, sources::VersionedSourceFile, ArtifactOutput, SolcConfig, SolcError, SourceFile, @@ -68,7 +68,7 @@ pub struct ConfigurableContractArtifact { #[serde(default, skip_serializing_if = "Option::is_none")] pub ewasm: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub ast: Option, + pub ast: Option, /// The identifier of the source file #[serde(default, skip_serializing_if = "Option::is_none")] pub id: Option, diff --git a/ethers-solc/src/artifacts/ast.rs b/ethers-solc/src/artifacts/ast.rs deleted file mode 100644 index 122054f8..00000000 --- a/ethers-solc/src/artifacts/ast.rs +++ /dev/null @@ -1,217 +0,0 @@ -//! Bindings for solc's `ast` output field - -use crate::artifacts::serde_helpers; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::{collections::BTreeMap, fmt, fmt::Write, str::FromStr}; - -/// Represents the AST field in the solc output -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Ast { - #[serde(rename = "absolutePath")] - pub absolute_path: String, - pub id: usize, - #[serde(default, rename = "exportedSymbols")] - pub exported_symbols: BTreeMap>, - #[serde(rename = "nodeType")] - pub node_type: NodeType, - #[serde(with = "serde_helpers::display_from_str")] - pub src: SourceLocation, - #[serde(default)] - pub nodes: Vec, - - /// Node attributes that were not deserialized. - #[serde(flatten)] - pub other: BTreeMap, -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Node { - /// The node ID. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub id: Option, - - /// The node type. - #[serde(rename = "nodeType")] - pub node_type: NodeType, - - /// The location of the node in the source file. - #[serde(with = "serde_helpers::display_from_str")] - pub src: SourceLocation, - - /// Child nodes for some node types. - #[serde(default)] - pub nodes: Vec, - - /// Body node for some node types. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub body: Option>, - - /// Node attributes that were not deserialized. - #[serde(flatten)] - pub other: BTreeMap, -} - -impl Node { - /// Deserialize a serialized node attribute. - pub fn attribute(&self, key: impl AsRef) -> Option { - // TODO: Can we avoid this clone? - self.other.get(key.as_ref()).and_then(|v| serde_json::from_value(v.clone()).ok()) - } -} - -/// Represents the source location of a node: `::`. -/// -/// The `length` and `index` can be -1 which is represented as `None` -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct SourceLocation { - pub start: usize, - pub length: Option, - pub index: Option, -} - -impl FromStr for SourceLocation { - type Err = String; - - fn from_str(s: &str) -> Result { - let invalid_location = move || format!("{s} invalid source location"); - - let mut split = s.split(':'); - let start = split - .next() - .ok_or_else(invalid_location)? - .parse::() - .map_err(|_| invalid_location())?; - let length = split - .next() - .ok_or_else(invalid_location)? - .parse::() - .map_err(|_| invalid_location())?; - let index = split - .next() - .ok_or_else(invalid_location)? - .parse::() - .map_err(|_| invalid_location())?; - - let length = if length < 0 { None } else { Some(length as usize) }; - let index = if index < 0 { None } else { Some(index as usize) }; - - Ok(Self { start, length, index }) - } -} - -impl fmt::Display for SourceLocation { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.start.fmt(f)?; - f.write_char(':')?; - if let Some(length) = self.length { - length.fmt(f)?; - } else { - f.write_str("-1")?; - } - f.write_char(':')?; - if let Some(index) = self.index { - index.fmt(f)?; - } else { - f.write_str("-1")?; - } - Ok(()) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum NodeType { - // Expressions - Assignment, - BinaryOperation, - Conditional, - ElementaryTypeNameExpression, - FunctionCall, - FunctionCallOptions, - Identifier, - IndexAccess, - IndexRangeAccess, - Literal, - MemberAccess, - NewExpression, - TupleExpression, - UnaryOperation, - - // Statements - Block, - Break, - Continue, - DoWhileStatement, - EmitStatement, - ExpressionStatement, - ForStatement, - IfStatement, - InlineAssembly, - PlaceholderStatement, - Return, - RevertStatement, - TryStatement, - UncheckedBlock, - VariableDeclarationStatement, - VariableDeclaration, - WhileStatement, - - // Yul statements - YulAssignment, - YulBlock, - YulBreak, - YulContinue, - YulExpressionStatement, - YulLeave, - YulForLoop, - YulFunctionDefinition, - YulIf, - YulSwitch, - YulVariableDeclaration, - - // Yul expressions - YulFunctionCall, - YulIdentifier, - YulLiteral, - - // Yul literals - YulLiteralValue, - YulHexValue, - - // Definitions - ContractDefinition, - FunctionDefinition, - EventDefinition, - ErrorDefinition, - ModifierDefinition, - StructDefinition, - EnumDefinition, - UserDefinedValueTypeDefinition, - - // Directives - PragmaDirective, - ImportDirective, - UsingForDirective, - - // Misc - SourceUnit, - InheritanceSpecifier, - ElementaryTypeName, - FunctionTypeName, - ParameterList, - TryCatchClause, - ModifierInvocation, - - /// An unknown AST node type. - Other(String), -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn can_parse_ast() { - let ast = include_str!("../../test-data/ast/ast-erc4626.json"); - let _ast: Ast = serde_json::from_str(ast).unwrap(); - } -} diff --git a/ethers-solc/src/artifacts/ast/macros.rs b/ethers-solc/src/artifacts/ast/macros.rs new file mode 100644 index 00000000..5302e268 --- /dev/null +++ b/ethers-solc/src/artifacts/ast/macros.rs @@ -0,0 +1,104 @@ +/// Macro that expands to a struct with common AST node fields. +macro_rules! ast_node { + ( + $(#[$struct_meta:meta])* + struct $name:ident { + $( + $(#[$field_meta:meta])* + $field:ident: $ty:ty + ),* $(,)* + } + ) => { + $(#[$struct_meta])* + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub struct $name { + pub id: usize, + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + $( + $(#[$field_meta])* + pub $field: $ty + ),* + } + }; +} + +/// A macro that expands to a struct with common expression node fields. +macro_rules! expr_node { + ( + $(#[$struct_meta:meta])* + struct $name:ident { + $( + $(#[$field_meta:meta])* + $field:ident: $ty:ty + ),* $(,)* + } + ) => { + ast_node!( + $(#[$struct_meta])* + struct $name { + #[serde(default, deserialize_with = "serde_helpers::default_for_null")] + argument_types: Vec, + #[serde(default)] + is_constant: bool, + #[serde(default)] + is_l_value: bool, + #[serde(default)] + is_pure: bool, + #[serde(default)] + l_value_requested: bool, + type_descriptions: TypeDescriptions, + $( + $(#[$field_meta])* + $field: $ty + ),* + } + ); + } +} + +/// A macro that expands to a struct with common statement node fields. +macro_rules! stmt_node { + ( + $(#[$struct_meta:meta])* + struct $name:ident { + $( + $(#[$field_meta:meta])* + $field:ident: $ty:ty + ),* $(,)* + } + ) => { + ast_node!( + $(#[$struct_meta])* + struct $name { + // TODO + documentation: Option, + $( + $(#[$field_meta])* + $field: $ty + ),* + } + ); + } +} + +/// A macro that expands to an enum where each variant also contains a struct of the same name. +/// +/// The inner value of each variant is boxed since AST types are inherently recursive. +macro_rules! node_group { + ($group:ident; $( $name:ident ),* $(,)*) => { + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] + #[serde(tag = "nodeType")] + pub enum $group { + $( + $name(Box<$name>), + )* + } + }; +} + +pub(crate) use ast_node; +pub(crate) use expr_node; +pub(crate) use node_group; +pub(crate) use stmt_node; diff --git a/ethers-solc/src/artifacts/ast/misc.rs b/ethers-solc/src/artifacts/ast/misc.rs new file mode 100644 index 00000000..ced7f7a2 --- /dev/null +++ b/ethers-solc/src/artifacts/ast/misc.rs @@ -0,0 +1,113 @@ +use serde::{Deserialize, Serialize}; +use std::{fmt, fmt::Write, str::FromStr}; + +/// Represents the source location of a node: `::`. +/// +/// The `start`, `length` and `index` can be -1 which is represented as `None` +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SourceLocation { + pub start: Option, + pub length: Option, + pub index: Option, +} + +impl FromStr for SourceLocation { + type Err = String; + + fn from_str(s: &str) -> Result { + let invalid_location = move || format!("{s} invalid source location"); + + let mut split = s.split(':'); + let start = split + .next() + .ok_or_else(invalid_location)? + .parse::() + .map_err(|_| invalid_location())?; + let length = split + .next() + .ok_or_else(invalid_location)? + .parse::() + .map_err(|_| invalid_location())?; + let index = split + .next() + .ok_or_else(invalid_location)? + .parse::() + .map_err(|_| invalid_location())?; + + let start = if start < 0 { None } else { Some(start as usize) }; + let length = if length < 0 { None } else { Some(length as usize) }; + let index = if index < 0 { None } else { Some(index as usize) }; + + Ok(Self { start, length, index }) + } +} + +impl fmt::Display for SourceLocation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(start) = self.start { + start.fmt(f)?; + } else { + f.write_str("-1")?; + } + f.write_char(':')?; + if let Some(length) = self.length { + length.fmt(f)?; + } else { + f.write_str("-1")?; + } + f.write_char(':')?; + if let Some(index) = self.index { + index.fmt(f)?; + } else { + f.write_str("-1")?; + } + Ok(()) + } +} + +/// Function mutability specifier. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum StateMutability { + Payable, + Pure, + Nonpayable, + View, +} + +/// Variable mutability specifier. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum Mutability { + Mutable, + Immutable, + Constant, +} + +/// Storage location specifier. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum StorageLocation { + Calldata, + Default, + Memory, + Storage, +} + +/// Visibility specifier. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum Visibility { + External, + Public, + Internal, + Private, +} + +/// A type description. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TypeDescriptions { + pub type_identifier: Option, + pub type_string: Option, +} diff --git a/ethers-solc/src/artifacts/ast/mod.rs b/ethers-solc/src/artifacts/ast/mod.rs new file mode 100644 index 00000000..31f3a496 --- /dev/null +++ b/ethers-solc/src/artifacts/ast/mod.rs @@ -0,0 +1,1097 @@ +//! Bindings for the Solidity and Yul ASTs. +//! +//! The Yul AST bindings are available in the [yul] module. +//! +//! To gain an overview of the AST, it might be helpful to start at the entry point of a complete +//! Solidity AST: the [SourceUnit] node. +//! +//! # Version Support +//! +//! These types should be compatible with at least Solidity 0.5.x and above, but may also support +//! 0.4.x-0.5.x in most cases. +//! +//! The legacy Solidity AST is not supported. +mod macros; +mod misc; +pub use misc::*; +pub mod util; +pub mod visitor; + +/// Types for the Yul AST. +/// +/// The Yul AST is embedded into the Solidity AST for inline assembly blocks. +pub mod yul; + +use crate::artifacts::serde_helpers; +use macros::{ast_node, expr_node, node_group, stmt_node}; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; +use yul::YulBlock; + +ast_node!( + /// The root node of a Solidity AST. + struct SourceUnit { + #[serde(rename = "absolutePath")] + absolute_path: String, + #[serde(default, rename = "exportedSymbols")] + exported_symbols: BTreeMap>, + #[serde(default)] + license: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + nodes: Vec, + } +); + +node_group! { + SourceUnitPart; + + PragmaDirective, + ImportDirective, + UsingForDirective, + VariableDeclaration, + EnumDefinition, + ErrorDefinition, + FunctionDefinition, + StructDefinition, + UserDefinedValueTypeDefinition, + ContractDefinition, +} + +node_group! { + Expression; + + Assignment, + BinaryOperation, + Conditional, + ElementaryTypeNameExpression, + FunctionCall, + FunctionCallOptions, + Identifier, + IndexAccess, + IndexRangeAccess, + Literal, + MemberAccess, + NewExpression, + TupleExpression, + UnaryOperation, +} + +node_group! { + Statement; + + Block, + Break, + Continue, + DoWhileStatement, + EmitStatement, + ExpressionStatement, + ForStatement, + IfStatement, + InlineAssembly, + PlaceholderStatement, + Return, + RevertStatement, + TryStatement, + UncheckedBlock, + VariableDeclarationStatement, + WhileStatement, + +} + +node_group! { + ContractDefinitionPart; + + EnumDefinition, + ErrorDefinition, + EventDefinition, + FunctionDefinition, + ModifierDefinition, + StructDefinition, + UserDefinedValueTypeDefinition, + UsingForDirective, + VariableDeclaration, +} + +node_group! { + TypeName; + + ArrayTypeName, + ElementaryTypeName, + FunctionTypeName, + Mapping, + UserDefinedTypeName, +} + +// TODO: Better name +node_group! { + UserDefinedTypeNameOrIdentifierPath; + + UserDefinedTypeName, + IdentifierPath, +} + +// TODO: Better name +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum BlockOrStatement { + Statement(Statement), + Block(Block), +} + +// TODO: Better name +node_group! { + ExpressionOrVariableDeclarationStatement; + + ExpressionStatement, + VariableDeclarationStatement +} + +// TODO: Better name +node_group! { + IdentifierOrIdentifierPath; + + Identifier, + IdentifierPath +} + +ast_node!( + /// A contract definition. + struct ContractDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + #[serde(default, rename = "abstract")] + is_abstract: bool, + base_contracts: Vec, + canonical_name: Option, + contract_dependencies: Vec, + #[serde(rename = "contractKind")] + kind: ContractKind, + documentation: Option, + fully_implemented: bool, + linearized_base_contracts: Vec, + nodes: Vec, + scope: usize, + #[serde(default)] + used_errors: Vec, + } +); + +/// All Solidity contract kinds. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum ContractKind { + /// A normal contract. + Contract, + /// An interface. + Interface, + /// A library. + Library, +} + +ast_node!( + /// An inheritance specifier. + struct InheritanceSpecifier { + #[serde(default, deserialize_with = "serde_helpers::default_for_null")] + arguments: Vec, + base_name: UserDefinedTypeNameOrIdentifierPath, + } +); + +expr_node!( + /// An assignment expression. + struct Assignment { + #[serde(rename = "leftHandSide")] + lhs: Expression, + operator: AssignmentOperator, + #[serde(rename = "rightHandSide")] + rhs: Expression, + } +); + +/// Assignment operators. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum AssignmentOperator { + /// Simple assignment (`=`) + #[serde(rename = "=")] + Assign, + /// Add and assign (`+=`) + #[serde(rename = "+=")] + AddAssign, + /// Subtract and assign (`-=`) + #[serde(rename = "-=")] + SubAssign, + /// Multiply and assign (`*=`) + #[serde(rename = "*=")] + MulAssign, + /// Divide and assign (`/=`) + #[serde(rename = "/=")] + DivAssign, + /// Modulo and assign (`%=`) + #[serde(rename = "%=")] + ModAssign, + /// Bitwise or and assign (`|=`) + #[serde(rename = "|=")] + OrAssign, + /// Bitwise and and assign (`&=`) + #[serde(rename = "&=")] + AndAssign, + /// Bitwise xor and assign (`^=`) + #[serde(rename = "^=")] + XorAssign, + /// Right shift and assign (`>>=`) + #[serde(rename = ">>=")] + ShrAssign, + /// Left shift and assign (`<<=`) + #[serde(rename = "<<=")] + ShlAssign, +} + +ast_node!( + /// A binary operation. + struct BinaryOperation { + common_type: TypeDescriptions, + #[serde(rename = "leftExpression")] + lhs: Expression, + operator: BinaryOperator, + #[serde(rename = "rightExpression")] + rhs: Expression, + } +); + +/// Binary operators. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum BinaryOperator { + /// Addition (`+`) + #[serde(rename = "+")] + Add, + /// Subtraction (`-`) + #[serde(rename = "-")] + Sub, + /// Multiplication (`*`) + #[serde(rename = "*")] + Mul, + /// Division (`/`) + #[serde(rename = "/")] + Div, + /// Modulo (`%`) + #[serde(rename = "%")] + Mod, + /// Exponentiation (`**`) + #[serde(rename = "**")] + Pow, + /// Logical and (`&&`) + #[serde(rename = "&&")] + And, + /// Logical or (`||`) + #[serde(rename = "||")] + Or, + /// Not equals (`!=`) + #[serde(rename = "!=")] + NotEqual, + /// Equals (`==`) + #[serde(rename = "==")] + Equal, + /// Less than (`<`) + #[serde(rename = "<")] + LessThan, + /// Less than or equal (`<=`) + #[serde(rename = "<=")] + LessThanOrEqual, + /// Greater than (`>`) + #[serde(rename = ">")] + GreaterThan, + /// Greater than or equal (`>=`) + #[serde(rename = ">=")] + GreaterThanOrEqual, + /// Bitwise xor (`^`) + #[serde(rename = "^")] + Xor, + /// Bitwise not (`~`) + #[serde(rename = "~")] + BitNot, + /// Bitwise and (`&`) + #[serde(rename = "&")] + BitAnd, + /// Bitwise or (`|`) + #[serde(rename = "|")] + BitOr, + /// Shift left (`<<`) + #[serde(rename = "<<")] + Shl, + /// Shift right (`>>`) + #[serde(rename = ">>")] + Shr, +} + +expr_node!( + /// A conditional expression. + struct Conditional { + /// The condition. + condition: Expression, + /// The expression to evaluate if falsy. + false_expression: Expression, + /// The expression to evaluate if truthy. + true_expression: Expression, + } +); + +expr_node!( + struct ElementaryTypeNameExpression { + type_name: ElementaryOrRawTypeName, + } +); + +// TODO: Better name +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ElementaryOrRawTypeName { + /// An [ElementaryTypeName] node that describes the type. + /// + /// This variant applies to newer compiler versions. + ElementaryTypeName(ElementaryTypeName), + /// A string representing the type name. + /// + /// This variant applies to older compiler versions. + Raw(String), +} + +ast_node!( + struct ElementaryTypeName { + type_descriptions: TypeDescriptions, + name: String, + state_mutability: Option, + } +); + +expr_node!( + /// A function call expression. + struct FunctionCall { + arguments: Vec, + expression: Expression, + kind: FunctionCallKind, + names: Vec, + #[serde(default)] + try_call: bool, + } +); + +/// Function call kinds. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum FunctionCallKind { + /// A regular function call. + FunctionCall, + /// A type conversion (e.g. `bytes(x)`). + TypeConversion, + /// A struct constructor call (e.g. `MyStruct({ ... })`). + StructConstructorCall, +} + +expr_node!( + /// A function call options expression (e.g. `x.f{gas: 1}`). + struct FunctionCallOptions { + expression: Expression, + names: Vec, + options: Vec, + } +); + +ast_node!( + /// An identifier. + struct Identifier { + #[serde(default, deserialize_with = "serde_helpers::default_for_null")] + argument_types: Vec, + name: String, + overloaded_declarations: Vec, + referenced_declaration: Option, + type_descriptions: TypeDescriptions, + } +); + +expr_node!( + /// An index access. + struct IndexAccess { + base_expression: Expression, + index_expression: Option, + } +); + +expr_node!( + /// An index range access. + struct IndexRangeAccess { + base_expression: Expression, + start_expression: Option, + end_expression: Option, + } +); + +expr_node!( + /// A literal value. + struct Literal { + // TODO + hex_value: String, + kind: LiteralKind, + subdenomination: Option, // TODO + value: Option, // TODO + } +); + +/// Literal kinds. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum LiteralKind { + /// A boolean. + Bool, + /// A number. + Number, + /// A string. + String, + /// A hexadecimal string. + HexString, + /// A unicode string. + UnicodeString, +} + +expr_node!( + /// Member access. + struct MemberAccess { + expression: Expression, + member_name: String, + referenced_declaration: Option, + } +); + +expr_node!( + /// A `new` expression. + struct NewExpression { + type_name: TypeName, + } +); + +ast_node!( + /// An array type name. + struct ArrayTypeName { + type_descriptions: TypeDescriptions, + base_type: TypeName, + length: Option, + } +); + +ast_node!( + /// A function type name. + struct FunctionTypeName { + type_descriptions: TypeDescriptions, + parameter_types: ParameterList, + return_parameter_types: ParameterList, + state_mutability: StateMutability, + visibility: Visibility, + } +); + +ast_node!( + /// A parameter list. + struct ParameterList { + parameters: Vec, + } +); + +ast_node!( + /// A variable declaration. + struct VariableDeclaration { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + #[serde(default, deserialize_with = "serde_helpers::default_for_null")] + base_functions: Vec, + /// Marks whether or not the variable is a constant before Solidity 0.7.x. + /// + /// After 0.7.x you must use `mutability`. For cross-version compatibility use + /// [`VariableDeclaration::mutability()`]. + #[serde(default)] + constant: bool, + /// Marks whether or not the variable is a state variable before Solidity 0.7.x. + /// + /// After 0.7.x you must use `mutability`. For cross-version compatibility use + /// [`VariableDeclaration::mutability()`]. + #[serde(default)] + state_variable: bool, + documentation: Option, + function_selector: Option, // TODO + #[serde(default)] + indexed: bool, + /// Marks the variable's mutability from Solidity 0.7.x onwards. + /// For cross-version compatibility use [`VariableDeclaration::mutability()`]. + #[serde(default)] + mutability: Option, + overrides: Option, + scope: usize, + storage_location: StorageLocation, + type_descriptions: TypeDescriptions, + type_name: Option, + value: Option, + visibility: Visibility, + } +); + +impl VariableDeclaration { + /// Returns the mutability of the variable that was declared. + /// + /// This is a helper to check variable mutability across Solidity versions. + pub fn mutability(&self) -> &Mutability { + if let Some(mutability) = &self.mutability { + mutability + } else if self.constant { + &Mutability::Constant + } else if self.state_variable { + &Mutability::Mutable + } else { + unreachable!() + } + } +} + +/// Structured documentation (NatSpec). +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum StructuredDocumentation { + /// The documentation is provided in the form of an AST node. + Parsed { text: String }, + /// The documentation is provided in the form of a string literal. + Text(String), +} + +ast_node!( + /// An override specifier. + struct OverrideSpecifier { + overrides: Vec, + } +); + +ast_node!( + /// A user defined type name. + struct UserDefinedTypeName { + type_descriptions: TypeDescriptions, + contract_scope: Option, // TODO + name: Option, + path_node: Option, + referenced_declaration: isize, + } +); + +ast_node!( + /// An identifier path. + struct IdentifierPath { + name: String, + referenced_declaration: isize, + } +); + +ast_node!( + /// A mapping type. + struct Mapping { + type_descriptions: TypeDescriptions, + key_type: TypeName, + value_type: TypeName, + } +); + +expr_node!( + /// A tuple expression. + struct TupleExpression { + components: Vec, + is_inline_array: bool, + } +); + +expr_node!( + /// A unary operation. + struct UnaryOperation { + operator: UnaryOperator, + /// Whether the unary operator is before or after the expression (e.g. `x++` vs. `++x`) + prefix: bool, + sub_expression: Expression, + } +); + +/// Unary operators. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum UnaryOperator { + /// Increment (`++`) + #[serde(rename = "++")] + Increment, + /// Decrement (`--`) + #[serde(rename = "--")] + Decrement, + /// Negate (`-`) + #[serde(rename = "-")] + Negate, + /// Not (`!`) + #[serde(rename = "!")] + Not, + /// Bitwise not (`~`) + #[serde(rename = "~")] + BitNot, + /// `delete` + #[serde(rename = "delete")] + Delete, +} + +ast_node!( + /// An enum definition. + struct EnumDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + canonical_name: String, + members: Vec, + } +); + +ast_node!( + /// An enum value. + struct EnumValue { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + } +); + +ast_node!( + /// A custom error definition. + struct ErrorDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + documentation: Option, + error_selector: Option, // TODO + parameters: ParameterList, + } +); + +ast_node!( + /// An event definition. + struct EventDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + anonymous: bool, + event_selector: Option, // TODO + documentation: Option, + parameters: ParameterList, + } +); + +ast_node!( + /// A function definition. + struct FunctionDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + #[serde(default)] + base_functions: Vec, + body: Option, + documentation: Option, + function_selector: Option, // TODO + implemented: bool, + modifiers: Vec, + overrides: Option, + parameters: ParameterList, + return_parameters: ParameterList, + scope: usize, + visibility: Visibility, + /// The kind of function this node defines. Only valid for Solidity versions 0.5.x and + /// above. + /// + /// For cross-version compatibility use [`FunctionDefinition::kind()`]. + kind: Option, + /// The state mutability of the function. + /// + /// Note: This was introduced in Solidity 0.5.x. For cross-version compatibility use + /// [`FunctionDefinition::state_mutability()`]. + #[serde(default)] + state_mutability: Option, + #[serde(default, rename = "virtual")] + is_virtual: bool, + /// Whether or not this function is the constructor. Only valid for Solidity versions below + /// 0.5.x. + /// + /// After 0.5.x you must use `kind`. For cross-version compatibility use + /// [`FunctionDefinition::kind()`]. + #[serde(default)] + is_constructor: bool, + /// Whether or not this function is constant (view or pure). Only valid for Solidity + /// versions below 0.5.x. + /// + /// After 0.5.x you must use `state_mutability`. For cross-version compatibility use + /// [`FunctionDefinition::state_mutability()`]. + #[serde(default)] + is_declared_const: bool, + /// Whether or not this function is payable. Only valid for Solidity versions below + /// 0.5.x. + /// + /// After 0.5.x you must use `state_mutability`. For cross-version compatibility use + /// [`FunctionDefinition::state_mutability()`]. + #[serde(default)] + is_payable: bool, + } +); + +impl FunctionDefinition { + /// The kind of function this node defines. + pub fn kind(&self) -> &FunctionKind { + if let Some(kind) = &self.kind { + kind + } else if self.is_constructor { + &FunctionKind::Constructor + } else { + &FunctionKind::Function + } + } + + /// The state mutability of the function. + /// + /// Note: Before Solidity 0.5.x, this is an approximation, as there was no distinction between + /// `view` and `pure`. + pub fn state_mutability(&self) -> &StateMutability { + if let Some(state_mutability) = &self.state_mutability { + state_mutability + } else if self.is_declared_const { + &StateMutability::View + } else if self.is_payable { + &StateMutability::Payable + } else { + &StateMutability::Nonpayable + } + } +} + +/// Function kinds. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum FunctionKind { + /// A contract function. + Function, + /// A receive function. + Receive, + /// A constructor. + Constructor, + /// A fallback function. + Fallback, + /// A free-standing function. + FreeFunction, +} + +ast_node!( + /// A block of statements. + struct Block { + documentation: Option, + #[serde(default, deserialize_with = "serde_helpers::default_for_null")] + statements: Vec, + } +); + +stmt_node!( + /// The break keyword. + struct Break {} +); + +stmt_node!( + /// The continue keyword. + struct Continue {} +); + +stmt_node!( + /// A do while statement. + struct DoWhileStatement { + block: Block, + condition: Expression, + } +); + +stmt_node!( + /// An emit statement. + struct EmitStatement { + event_call: FunctionCall, + } +); + +stmt_node!( + /// An expression statement. + struct ExpressionStatement { + expression: Expression, + } +); + +stmt_node!( + /// A for statement. + struct ForStatement { + body: BlockOrStatement, + condition: Option, + initialization_expression: Option, + loop_expression: Option, + } +); + +stmt_node!( + /// A variable declaration statement. + struct VariableDeclarationStatement { + assignments: Vec>, + declarations: Vec>, + initial_value: Option, + } +); + +stmt_node!( + /// An if statement. + struct IfStatement { + condition: Expression, + false_body: Option, + true_body: BlockOrStatement, + } +); + +ast_node!( + /// A block of inline assembly. + /// + /// Refer to the [yul] module for Yul AST nodes. + struct InlineAssembly { + documentation: Option, + #[serde(rename = "AST")] + ast: YulBlock, + // TODO: We need this camel case for the AST, but pascal case other places in ethers-solc + //evm_version: EvmVersion, + external_references: Vec, + #[serde(default)] + flags: Vec, + } +); + +/// A reference to an external variable or slot in an inline assembly block. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ExternalInlineAssemblyReference { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub declaration: usize, + #[serde(default)] + pub offset: bool, + #[serde(default)] + pub slot: bool, + #[serde(default)] + pub length: bool, + pub value_size: usize, + pub suffix: Option, +} + +/// An assembly reference suffix. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum AssemblyReferenceSuffix { + /// The reference refers to a storage slot. + Slot, + /// The reference refers to an offset. + Offset, + /// The reference refers to a length. + Length, +} + +/// Inline assembly flags. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum InlineAssemblyFlag { + MemorySafe, +} + +stmt_node!( + /// A placeholder statement (`_`) + struct PlaceholderStatement {} +); + +stmt_node!( + /// A return statement. + struct Return { + expression: Option, + function_return_parameters: usize, + } +); + +stmt_node!( + /// A revert statement. + struct RevertStatement { + error_call: FunctionCall, + } +); + +stmt_node!( + /// A try/catch statement. + struct TryStatement { + clauses: Vec, + external_call: FunctionCall, + } +); + +ast_node!( + /// A try/catch clause. + struct TryCatchClause { + block: Block, + error_name: String, + #[serde(default)] + parameters: Vec, + } +); + +stmt_node!( + /// An unchecked block. + struct UncheckedBlock { + statements: Vec, + } +); + +stmt_node!( + /// A while statement. + struct WhileStatement { + body: BlockOrStatement, + condition: Expression, + } +); + +ast_node!( + /// A modifier or base constructor invocation. + struct ModifierInvocation { + #[serde(default)] + arguments: Vec, + kind: Option, + modifier_name: IdentifierOrIdentifierPath, + } +); + +/// Modifier invocation kinds. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum ModifierInvocationKind { + /// A regular modifier invocation. + ModifierInvocation, + /// A base constructor invocation. + BaseConstructorSpecifier, +} + +ast_node!( + /// A modifier definition. + struct ModifierDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + #[serde(default, deserialize_with = "serde_helpers::default_for_null")] + base_modifiers: Vec, + body: Block, + documentation: Option, + overrides: Option, + parameters: ParameterList, + #[serde(default, rename = "virtual")] + is_virtual: bool, + visibility: Visibility, + } +); + +ast_node!( + /// A struct definition. + struct StructDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + canonical_name: String, + members: Vec, + scope: usize, + visibility: Visibility, + } +); + +ast_node!( + /// A user defined value type definition. + struct UserDefinedValueTypeDefinition { + name: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + canonical_name: Option, + underlying_type: TypeName, + } +); + +ast_node!( + /// A using for directive. + struct UsingForDirective { + #[serde(default)] + function_list: Vec, + #[serde(default)] + global: bool, + library_name: Option, + type_name: Option, + } +); + +/// A wrapper around [IdentifierPath] for the [UsingForDirective]. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct FunctionIdentifierPath { + pub function: IdentifierPath, +} + +ast_node!( + /// An import directive. + struct ImportDirective { + absolute_path: String, + file: String, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + name_location: Option, + scope: usize, + source_unit: usize, + symbol_aliases: Vec, + unit_alias: String, + } +); + +/// A symbol alias. +/// +/// Symbol aliases can be defined using the [ImportDirective]. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SymbolAlias { + pub foreign: Identifier, + pub local: Option, + #[serde(default, with = "serde_helpers::display_from_str_opt")] + pub name_location: Option, +} + +ast_node!( + /// A pragma directive. + struct PragmaDirective { + literals: Vec, + } +); + +#[cfg(test)] +mod tests { + use super::*; + use std::{fs, path::PathBuf}; + + #[test] + fn can_parse_ast() { + fs::read_dir(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test-data").join("ast")) + .unwrap() + .for_each(|path| { + let path = path.unwrap().path(); + let path_str = path.to_string_lossy(); + + let input = fs::read_to_string(&path).unwrap(); + let deserializer = &mut serde_json::Deserializer::from_str(&input); + let result: Result = serde_path_to_error::deserialize(deserializer); + match result { + Err(e) => { + println!("... {} fail: {e}", path_str); + panic!(); + } + Ok(_) => { + println!("... {} ok", path_str); + } + } + }) + } +} diff --git a/ethers-solc/src/artifacts/ast/util.rs b/ethers-solc/src/artifacts/ast/util.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/ethers-solc/src/artifacts/ast/util.rs @@ -0,0 +1 @@ + diff --git a/ethers-solc/src/artifacts/ast/visitor.rs b/ethers-solc/src/artifacts/ast/visitor.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/ethers-solc/src/artifacts/ast/visitor.rs @@ -0,0 +1 @@ + diff --git a/ethers-solc/src/artifacts/ast/yul.rs b/ethers-solc/src/artifacts/ast/yul.rs new file mode 100644 index 00000000..556083cb --- /dev/null +++ b/ethers-solc/src/artifacts/ast/yul.rs @@ -0,0 +1,192 @@ +use super::{macros::node_group, misc::SourceLocation}; +use crate::artifacts::serde_helpers; +use serde::{Deserialize, Serialize}; + +node_group! { + YulStatement; + + YulAssignment, + YulBlock, + YulBreak, + YulContinue, + YulExpressionStatement, + YulLeave, + YulForLoop, + YulFunctionDefinition, + YulIf, + YulSwitch, + YulVariableDeclaration, +} + +node_group! { + YulExpression; + + YulFunctionCall, + YulIdentifier, + YulLiteral, +} + +/// A Yul block. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulBlock { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub statements: Vec, +} + +/// A Yul assignment statement. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct YulAssignment { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub value: YulExpression, + pub variable_names: Vec, +} + +/// A Yul function call. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct YulFunctionCall { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub arguments: Vec, + pub function_name: YulIdentifier, +} + +/// A Yul identifier. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulIdentifier { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub name: String, +} + +/// A literal Yul value. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct YulLiteral { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub hex_value: Option, // TODO + pub value: Option, // TODO + pub kind: YulLiteralKind, + pub type_name: Option, // TODO +} + +/// Yul literal value kinds. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum YulLiteralKind { + /// A number literal. + Number, + /// A string literal. + String, + /// A boolean literal. + Bool, +} + +/// A Yul keyword. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulKeyword { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, +} + +/// The Yul break keyword. +pub type YulBreak = YulKeyword; +/// The Yul continue keyword. +pub type YulContinue = YulKeyword; +/// The Yul leave keyword. +pub type YulLeave = YulKeyword; + +/// A Yul expression statement. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulExpressionStatement { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub expression: YulExpression, +} + +/// A Yul for loop. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulForLoop { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub body: YulBlock, + pub condition: YulExpression, + pub post: YulBlock, + pub pre: YulBlock, +} + +/// A Yul function definition. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct YulFunctionDefinition { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub body: YulBlock, + pub name: String, + #[serde(default)] + pub parameters: Vec, + #[serde(default)] + pub return_variables: Vec, +} + +/// A Yul type name. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct YulTypedName { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub name: String, + #[serde(rename = "type")] + pub type_name: String, // TODO +} + +/// A Yul if statement. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulIf { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub body: YulBlock, + pub condition: YulExpression, +} + +/// A Yul switch statement. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulSwitch { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub cases: Vec, + pub expression: YulExpression, +} + +/// A Yul switch statement case. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulCase { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub body: YulBlock, + pub value: YulCaseValue, +} + +/// A Yul switch case value. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum YulCaseValue { + /// A case defined by a literal value. + YulLiteral(YulLiteral), + /// The default case + // TODO: How do we make this only match "default"? + Default(String), +} + +/// A Yul variable declaration. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct YulVariableDeclaration { + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + pub value: Option, + pub variables: Vec, +} diff --git a/ethers-solc/src/artifacts/mod.rs b/ethers-solc/src/artifacts/mod.rs index 0a0d1dd0..7de6b01b 100644 --- a/ethers-solc/src/artifacts/mod.rs +++ b/ethers-solc/src/artifacts/mod.rs @@ -1835,7 +1835,7 @@ pub struct SecondarySourceLocation { pub struct SourceFile { pub id: u32, #[serde(default, with = "serde_helpers::empty_json_object_opt")] - pub ast: Option, + pub ast: Option, } // === impl SourceFile === @@ -1846,7 +1846,10 @@ impl SourceFile { pub fn contains_contract_definition(&self) -> bool { if let Some(ref ast) = self.ast { // contract definitions are only allowed at the source-unit level - return ast.nodes.iter().any(|node| node.node_type == NodeType::ContractDefinition) + return ast + .nodes + .iter() + .any(|node| matches!(node, SourceUnitPart::ContractDefinition(_))) // abstract contract, interfaces: ContractDefinition } diff --git a/ethers-solc/test-data/ast/abstract_contract.json b/ethers-solc/test-data/ast/abstract_contract.json new file mode 100644 index 00000000..168433eb --- /dev/null +++ b/ethers-solc/test-data/ast/abstract_contract.json @@ -0,0 +1,73 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": true, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nameLocation": "18:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "37:4:1", + "statements": [] + }, + "id": 4, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "34:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "37:0:1" + }, + "scope": 5, + "src": "23:18:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 6, + "src": "0:43:1", + "usedErrors": [] + } + ], + "src": "0:44:1" +} diff --git a/ethers-solc/test-data/ast/address_payable.json b/ethers-solc/test-data/ast/address_payable.json new file mode 100644 index 00000000..cc87fc3b --- /dev/null +++ b/ethers-solc/test-data/ast/address_payable.json @@ -0,0 +1,574 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 39 + ] + }, + "id": 40, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 39, + "linearizedBaseContracts": + [ + 39 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "functionSelector": "97682884", + "id": 4, + "mutability": "mutable", + "name": "m", + "nameLocation": "60:1:1", + "nodeType": "VariableDeclaration", + "scope": 39, + "src": "17:44:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + }, + "typeName": + { + "id": 3, + "keyType": + { + "id": 1, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "25:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "17:35:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + }, + "valueType": + { + "id": 2, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "36:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + } + }, + "visibility": "public" + }, + { + "body": + { + "id": 37, + "nodeType": "Block", + "src": "134:122:1", + "statements": + [ + { + "assignments": + [ + 12 + ], + "declarations": + [ + { + "constant": false, + "id": 12, + "mutability": "mutable", + "name": "a", + "nameLocation": "160:1:1", + "nodeType": "VariableDeclaration", + "scope": 37, + "src": "144:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + }, + "typeName": + { + "id": 11, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "144:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "visibility": "internal" + } + ], + "id": 16, + "initialValue": + { + "baseExpression": + { + "id": 13, + "name": "m", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "164:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + } + }, + "id": 15, + "indexExpression": + { + "id": 14, + "name": "arg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "166:3:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "164:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "144:26:1" + }, + { + "expression": + { + "id": 19, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 17, + "name": "r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9, + "src": "180:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "id": 18, + "name": "arg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "184:3:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "src": "180:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "id": 20, + "nodeType": "ExpressionStatement", + "src": "180:7:1" + }, + { + "assignments": + [ + 22 + ], + "declarations": + [ + { + "constant": false, + "id": 22, + "mutability": "mutable", + "name": "c", + "nameLocation": "205:1:1", + "nodeType": "VariableDeclaration", + "scope": 37, + "src": "197:9:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 21, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "197:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 27, + "initialValue": + { + "arguments": + [ + { + "id": 25, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "217:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C_$39", + "typeString": "contract C" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_C_$39", + "typeString": "contract C" + } + ], + "id": 24, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "209:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": + { + "id": 23, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "209:7:1", + "typeDescriptions": {} + } + }, + "id": 26, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "209:13:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "197:25:1" + }, + { + "expression": + { + "id": 35, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "baseExpression": + { + "id": 28, + "name": "m", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "232:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + } + }, + "id": 30, + "indexExpression": + { + "id": 29, + "name": "c", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22, + "src": "234:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "232:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "arguments": + [ + { + "hexValue": "30", + "id": 33, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "247:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 32, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "239:8:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_payable_$", + "typeString": "type(address payable)" + }, + "typeName": + { + "id": 31, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "239:8:1", + "stateMutability": "payable", + "typeDescriptions": {} + } + }, + "id": 34, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "239:10:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "src": "232:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "id": 36, + "nodeType": "ExpressionStatement", + "src": "232:17:1" + } + ] + }, + "functionSelector": "fc68521a", + "id": 38, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "76:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "arg", + "nameLocation": "94:3:1", + "nodeType": "VariableDeclaration", + "scope": 38, + "src": "78:19:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + }, + "typeName": + { + "id": 5, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "78:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "visibility": "internal" + } + ], + "src": "77:21:1" + }, + "returnParameters": + { + "id": 10, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 9, + "mutability": "mutable", + "name": "r", + "nameLocation": "131:1:1", + "nodeType": "VariableDeclaration", + "scope": 38, + "src": "115:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + }, + "typeName": + { + "id": 8, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "115:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "visibility": "internal" + } + ], + "src": "114:19:1" + }, + "scope": 39, + "src": "67:189:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 40, + "src": "0:258:1", + "usedErrors": [] + } + ], + "src": "0:259:1" +} diff --git a/ethers-solc/test-data/ast/array_type_name.json b/ethers-solc/test-data/ast/array_type_name.json new file mode 100644 index 00000000..c1bcaa98 --- /dev/null +++ b/ethers-solc/test-data/ast/array_type_name.json @@ -0,0 +1,79 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 4 + ] + }, + "id": 5, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "i", + "nameLocation": "20:1:1", + "nodeType": "VariableDeclaration", + "scope": 4, + "src": "13:8:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "13:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2, + "nodeType": "ArrayTypeName", + "src": "13:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "visibility": "internal" + } + ], + "scope": 5, + "src": "0:24:1", + "usedErrors": [] + } + ], + "src": "0:25:1" +} diff --git a/ethers-solc/test-data/ast/ast-erc4626.json b/ethers-solc/test-data/ast/ast-erc4626.json deleted file mode 100644 index cc733b85..00000000 --- a/ethers-solc/test-data/ast/ast-erc4626.json +++ /dev/null @@ -1,6612 +0,0 @@ -{ - "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/mixins/ERC4626.sol", - "id": 2954, - "exportedSymbols": { - "ERC20": [ - 31408 - ], - "ERC4626": [ - 2953 - ], - "FixedPointMathLib": [ - 32321 - ], - "SafeTransferLib": [ - 32785 - ] - }, - "nodeType": "SourceUnit", - "src": "42:6474:4", - "nodes": [ - { - "id": 2434, - "nodeType": "PragmaDirective", - "src": "42:24:4", - "literals": [ - "solidity", - ">=", - "0.8", - ".0" - ] - }, - { - "id": 2436, - "nodeType": "ImportDirective", - "src": "68:42:4", - "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/tokens/ERC20.sol", - "file": "../tokens/ERC20.sol", - "nameLocation": "-1:-1:-1", - "scope": 2954, - "sourceUnit": 31409, - "symbolAliases": [ - { - "foreign": { - "id": 2435, - "name": "ERC20", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "src": "76:5:4", - "typeDescriptions": {} - }, - "nameLocation": "-1:-1:-1" - } - ], - "unitAlias": "" - }, - { - "id": 2438, - "nodeType": "ImportDirective", - "src": "111:61:4", - "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/utils/SafeTransferLib.sol", - "file": "../utils/SafeTransferLib.sol", - "nameLocation": "-1:-1:-1", - "scope": 2954, - "sourceUnit": 32786, - "symbolAliases": [ - { - "foreign": { - "id": 2437, - "name": "SafeTransferLib", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "src": "119:15:4", - "typeDescriptions": {} - }, - "nameLocation": "-1:-1:-1" - } - ], - "unitAlias": "" - }, - { - "id": 2440, - "nodeType": "ImportDirective", - "src": "173:65:4", - "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/utils/FixedPointMathLib.sol", - "file": "../utils/FixedPointMathLib.sol", - "nameLocation": "-1:-1:-1", - "scope": 2954, - "sourceUnit": 32322, - "symbolAliases": [ - { - "foreign": { - "id": 2439, - "name": "FixedPointMathLib", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "src": "181:17:4", - "typeDescriptions": {} - }, - "nameLocation": "-1:-1:-1" - } - ], - "unitAlias": "" - }, - { - "id": 2953, - "nodeType": "ContractDefinition", - "src": "395:6120:4", - "nodes": [ - { - "id": 2447, - "nodeType": "UsingForDirective", - "src": "436:32:4", - "libraryName": { - "id": 2444, - "name": "SafeTransferLib", - "nodeType": "IdentifierPath", - "referencedDeclaration": 32785, - "src": "442:15:4" - }, - "typeName": { - "id": 2446, - "nodeType": "UserDefinedTypeName", - "pathNode": { - "id": 2445, - "name": "ERC20", - "nodeType": "IdentifierPath", - "referencedDeclaration": 31408, - "src": "462:5:4" - }, - "referencedDeclaration": 31408, - "src": "462:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - } - }, - { - "id": 2450, - "nodeType": "UsingForDirective", - "src": "473:36:4", - "libraryName": { - "id": 2448, - "name": "FixedPointMathLib", - "nodeType": "IdentifierPath", - "referencedDeclaration": 32321, - "src": "479:17:4" - }, - "typeName": { - "id": 2449, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "501:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - }, - { - "id": 2460, - "nodeType": "EventDefinition", - "src": "694:93:4", - "anonymous": false, - "name": "Deposit", - "nameLocation": "700:7:4", - "parameters": { - "id": 2459, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2452, - "indexed": true, - "mutability": "mutable", - "name": "caller", - "nameLocation": "724:6:4", - "nodeType": "VariableDeclaration", - "scope": 2460, - "src": "708:22:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2451, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "708:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2454, - "indexed": true, - "mutability": "mutable", - "name": "owner", - "nameLocation": "748:5:4", - "nodeType": "VariableDeclaration", - "scope": 2460, - "src": "732:21:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2453, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "732:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2456, - "indexed": false, - "mutability": "mutable", - "name": "assets", - "nameLocation": "763:6:4", - "nodeType": "VariableDeclaration", - "scope": 2460, - "src": "755:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2455, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "755:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2458, - "indexed": false, - "mutability": "mutable", - "name": "shares", - "nameLocation": "779:6:4", - "nodeType": "VariableDeclaration", - "scope": 2460, - "src": "771:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2457, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "771:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "707:79:4" - } - }, - { - "id": 2472, - "nodeType": "EventDefinition", - "src": "793:166:4", - "anonymous": false, - "name": "Withdraw", - "nameLocation": "799:8:4", - "parameters": { - "id": 2471, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2462, - "indexed": true, - "mutability": "mutable", - "name": "caller", - "nameLocation": "833:6:4", - "nodeType": "VariableDeclaration", - "scope": 2472, - "src": "817:22:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2461, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "817:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2464, - "indexed": true, - "mutability": "mutable", - "name": "receiver", - "nameLocation": "865:8:4", - "nodeType": "VariableDeclaration", - "scope": 2472, - "src": "849:24:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2463, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "849:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2466, - "indexed": true, - "mutability": "mutable", - "name": "owner", - "nameLocation": "899:5:4", - "nodeType": "VariableDeclaration", - "scope": 2472, - "src": "883:21:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2465, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "883:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2468, - "indexed": false, - "mutability": "mutable", - "name": "assets", - "nameLocation": "922:6:4", - "nodeType": "VariableDeclaration", - "scope": 2472, - "src": "914:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2467, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "914:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2470, - "indexed": false, - "mutability": "mutable", - "name": "shares", - "nameLocation": "946:6:4", - "nodeType": "VariableDeclaration", - "scope": 2472, - "src": "938:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2469, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "938:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "807:151:4" - } - }, - { - "id": 2475, - "nodeType": "VariableDeclaration", - "src": "1146:28:4", - "constant": false, - "functionSelector": "38d52e0f", - "mutability": "immutable", - "name": "asset", - "nameLocation": "1169:5:4", - "scope": 2953, - "stateVariable": true, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - }, - "typeName": { - "id": 2474, - "nodeType": "UserDefinedTypeName", - "pathNode": { - "id": 2473, - "name": "ERC20", - "nodeType": "IdentifierPath", - "referencedDeclaration": 31408, - "src": "1146:5:4" - }, - "referencedDeclaration": 31408, - "src": "1146:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "visibility": "public" - }, - { - "id": 2497, - "nodeType": "FunctionDefinition", - "src": "1181:172:4", - "body": { - "id": 2496, - "nodeType": "Block", - "src": "1322:31:4", - "statements": [ - { - "expression": { - "id": 2494, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftHandSide": { - "id": 2492, - "name": "asset", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2475, - "src": "1332:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "nodeType": "Assignment", - "operator": "=", - "rightHandSide": { - "id": 2493, - "name": "_asset", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2478, - "src": "1340:6:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "src": "1332:14:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "id": 2495, - "nodeType": "ExpressionStatement", - "src": "1332:14:4" - } - ] - }, - "implemented": true, - "kind": "constructor", - "modifiers": [ - { - "arguments": [ - { - "id": 2485, - "name": "_name", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2480, - "src": "1287:5:4", - "typeDescriptions": { - "typeIdentifier": "t_string_memory_ptr", - "typeString": "string memory" - } - }, - { - "id": 2486, - "name": "_symbol", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2482, - "src": "1294:7:4", - "typeDescriptions": { - "typeIdentifier": "t_string_memory_ptr", - "typeString": "string memory" - } - }, - { - "arguments": [], - "expression": { - "argumentTypes": [], - "expression": { - "id": 2487, - "name": "_asset", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2478, - "src": "1303:6:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "id": 2488, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "decimals", - "nodeType": "MemberAccess", - "referencedDeclaration": 31045, - "src": "1303:15:4", - "typeDescriptions": { - "typeIdentifier": "t_function_external_view$__$returns$_t_uint8_$", - "typeString": "function () view external returns (uint8)" - } - }, - "id": 2489, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "1303:17:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint8", - "typeString": "uint8" - } - } - ], - "id": 2490, - "kind": "baseConstructorSpecifier", - "modifierName": { - "id": 2484, - "name": "ERC20", - "nodeType": "IdentifierPath", - "referencedDeclaration": 31408, - "src": "1281:5:4" - }, - "nodeType": "ModifierInvocation", - "src": "1281:40:4" - } - ], - "name": "", - "nameLocation": "-1:-1:-1", - "parameters": { - "id": 2483, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2478, - "mutability": "mutable", - "name": "_asset", - "nameLocation": "1208:6:4", - "nodeType": "VariableDeclaration", - "scope": 2497, - "src": "1202:12:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - }, - "typeName": { - "id": 2477, - "nodeType": "UserDefinedTypeName", - "pathNode": { - "id": 2476, - "name": "ERC20", - "nodeType": "IdentifierPath", - "referencedDeclaration": 31408, - "src": "1202:5:4" - }, - "referencedDeclaration": 31408, - "src": "1202:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2480, - "mutability": "mutable", - "name": "_name", - "nameLocation": "1238:5:4", - "nodeType": "VariableDeclaration", - "scope": 2497, - "src": "1224:19:4", - "stateVariable": false, - "storageLocation": "memory", - "typeDescriptions": { - "typeIdentifier": "t_string_memory_ptr", - "typeString": "string" - }, - "typeName": { - "id": 2479, - "name": "string", - "nodeType": "ElementaryTypeName", - "src": "1224:6:4", - "typeDescriptions": { - "typeIdentifier": "t_string_storage_ptr", - "typeString": "string" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2482, - "mutability": "mutable", - "name": "_symbol", - "nameLocation": "1267:7:4", - "nodeType": "VariableDeclaration", - "scope": 2497, - "src": "1253:21:4", - "stateVariable": false, - "storageLocation": "memory", - "typeDescriptions": { - "typeIdentifier": "t_string_memory_ptr", - "typeString": "string" - }, - "typeName": { - "id": 2481, - "name": "string", - "nodeType": "ElementaryTypeName", - "src": "1253:6:4", - "typeDescriptions": { - "typeIdentifier": "t_string_storage_ptr", - "typeString": "string" - } - }, - "visibility": "internal" - } - ], - "src": "1192:88:4" - }, - "returnParameters": { - "id": 2491, - "nodeType": "ParameterList", - "parameters": [], - "src": "1322:0:4" - }, - "scope": 2953, - "stateMutability": "nonpayable", - "virtual": false, - "visibility": "internal" - }, - { - "id": 2549, - "nodeType": "FunctionDefinition", - "src": "1547:516:4", - "body": { - "id": 2548, - "nodeType": "Block", - "src": "1638:425:4", - "statements": [ - { - "expression": { - "arguments": [ - { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2514, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "components": [ - { - "id": 2511, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftHandSide": { - "id": 2507, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2504, - "src": "1732:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "Assignment", - "operator": "=", - "rightHandSide": { - "arguments": [ - { - "id": 2509, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2499, - "src": "1756:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2508, - "name": "previewDeposit", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2822, - "src": "1741:14:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", - "typeString": "function (uint256) view returns (uint256)" - } - }, - "id": 2510, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "1741:22:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "1732:31:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "id": 2512, - "isConstant": false, - "isInlineArray": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "nodeType": "TupleExpression", - "src": "1731:33:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "!=", - "rightExpression": { - "hexValue": "30", - "id": 2513, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "1768:1:4", - "typeDescriptions": { - "typeIdentifier": "t_rational_0_by_1", - "typeString": "int_const 0" - }, - "value": "0" - }, - "src": "1731:38:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - { - "hexValue": "5a45524f5f534841524553", - "id": 2515, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "string", - "lValueRequested": false, - "nodeType": "Literal", - "src": "1771:13:4", - "typeDescriptions": { - "typeIdentifier": "t_stringliteral_2119bd5d92259e418533f96b824fbd100e3dea453e6ac4c5f7315e6344368f2f", - "typeString": "literal_string \"ZERO_SHARES\"" - }, - "value": "ZERO_SHARES" - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_bool", - "typeString": "bool" - }, - { - "typeIdentifier": "t_stringliteral_2119bd5d92259e418533f96b824fbd100e3dea453e6ac4c5f7315e6344368f2f", - "typeString": "literal_string \"ZERO_SHARES\"" - } - ], - "id": 2506, - "name": "require", - "nodeType": "Identifier", - "overloadedDeclarations": [ - -18, - -18 - ], - "referencedDeclaration": -18, - "src": "1723:7:4", - "typeDescriptions": { - "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", - "typeString": "function (bool,string memory) pure" - } - }, - "id": 2516, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "1723:62:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2517, - "nodeType": "ExpressionStatement", - "src": "1723:62:4" - }, - { - "expression": { - "arguments": [ - { - "expression": { - "id": 2521, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "1888:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2522, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "1888:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "arguments": [ - { - "id": 2525, - "name": "this", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -28, - "src": "1908:4:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC4626_$2953", - "typeString": "contract ERC4626" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_contract$_ERC4626_$2953", - "typeString": "contract ERC4626" - } - ], - "id": 2524, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "nodeType": "ElementaryTypeNameExpression", - "src": "1900:7:4", - "typeDescriptions": { - "typeIdentifier": "t_type$_t_address_$", - "typeString": "type(address)" - }, - "typeName": { - "id": 2523, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "1900:7:4", - "typeDescriptions": {} - } - }, - "id": 2526, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "typeConversion", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "1900:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2527, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2499, - "src": "1915:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2518, - "name": "asset", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2475, - "src": "1865:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "id": 2520, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "safeTransferFrom", - "nodeType": "MemberAccess", - "referencedDeclaration": 32744, - "src": "1865:22:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", - "typeString": "function (contract ERC20,address,address,uint256)" - } - }, - "id": 2528, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "1865:57:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2529, - "nodeType": "ExpressionStatement", - "src": "1865:57:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2531, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2501, - "src": "1939:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2532, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2504, - "src": "1949:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2530, - "name": "_mint", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31379, - "src": "1933:5:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", - "typeString": "function (address,uint256)" - } - }, - "id": 2533, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "1933:23:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2534, - "nodeType": "ExpressionStatement", - "src": "1933:23:4" - }, - { - "eventCall": { - "arguments": [ - { - "expression": { - "id": 2536, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "1980:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2537, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "1980:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2538, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2501, - "src": "1992:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2539, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2499, - "src": "2002:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2540, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2504, - "src": "2010:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2535, - "name": "Deposit", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2460, - "src": "1972:7:4", - "typeDescriptions": { - "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (address,address,uint256,uint256)" - } - }, - "id": 2541, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "1972:45:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2542, - "nodeType": "EmitStatement", - "src": "1967:50:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2544, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2499, - "src": "2041:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2545, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2504, - "src": "2049:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2543, - "name": "afterDeposit", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2952, - "src": "2028:12:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (uint256,uint256)" - } - }, - "id": 2546, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2028:28:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2547, - "nodeType": "ExpressionStatement", - "src": "2028:28:4" - } - ] - }, - "functionSelector": "6e553f65", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "deposit", - "nameLocation": "1556:7:4", - "parameters": { - "id": 2502, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2499, - "mutability": "mutable", - "name": "assets", - "nameLocation": "1572:6:4", - "nodeType": "VariableDeclaration", - "scope": 2549, - "src": "1564:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2498, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "1564:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2501, - "mutability": "mutable", - "name": "receiver", - "nameLocation": "1588:8:4", - "nodeType": "VariableDeclaration", - "scope": 2549, - "src": "1580:16:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2500, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "1580:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "1563:34:4" - }, - "returnParameters": { - "id": 2505, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2504, - "mutability": "mutable", - "name": "shares", - "nameLocation": "1630:6:4", - "nodeType": "VariableDeclaration", - "scope": 2549, - "src": "1622:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2503, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "1622:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "1621:16:4" - }, - "scope": 2953, - "stateMutability": "nonpayable", - "virtual": true, - "visibility": "public" - }, - { - "id": 2595, - "nodeType": "FunctionDefinition", - "src": "2069:467:4", - "body": { - "id": 2594, - "nodeType": "Block", - "src": "2157:379:4", - "statements": [ - { - "expression": { - "id": 2562, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftHandSide": { - "id": 2558, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2556, - "src": "2167:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "Assignment", - "operator": "=", - "rightHandSide": { - "arguments": [ - { - "id": 2560, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2551, - "src": "2188:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2559, - "name": "previewMint", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2846, - "src": "2176:11:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", - "typeString": "function (uint256) view returns (uint256)" - } - }, - "id": 2561, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2176:19:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "2167:28:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2563, - "nodeType": "ExpressionStatement", - "src": "2167:28:4" - }, - { - "expression": { - "arguments": [ - { - "expression": { - "id": 2567, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "2361:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2568, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "2361:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "arguments": [ - { - "id": 2571, - "name": "this", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -28, - "src": "2381:4:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC4626_$2953", - "typeString": "contract ERC4626" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_contract$_ERC4626_$2953", - "typeString": "contract ERC4626" - } - ], - "id": 2570, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "nodeType": "ElementaryTypeNameExpression", - "src": "2373:7:4", - "typeDescriptions": { - "typeIdentifier": "t_type$_t_address_$", - "typeString": "type(address)" - }, - "typeName": { - "id": 2569, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "2373:7:4", - "typeDescriptions": {} - } - }, - "id": 2572, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "typeConversion", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2373:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2573, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2556, - "src": "2388:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2564, - "name": "asset", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2475, - "src": "2338:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "id": 2566, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "safeTransferFrom", - "nodeType": "MemberAccess", - "referencedDeclaration": 32744, - "src": "2338:22:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", - "typeString": "function (contract ERC20,address,address,uint256)" - } - }, - "id": 2574, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2338:57:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2575, - "nodeType": "ExpressionStatement", - "src": "2338:57:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2577, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2553, - "src": "2412:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2578, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2551, - "src": "2422:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2576, - "name": "_mint", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31379, - "src": "2406:5:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", - "typeString": "function (address,uint256)" - } - }, - "id": 2579, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2406:23:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2580, - "nodeType": "ExpressionStatement", - "src": "2406:23:4" - }, - { - "eventCall": { - "arguments": [ - { - "expression": { - "id": 2582, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "2453:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2583, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "2453:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2584, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2553, - "src": "2465:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2585, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2556, - "src": "2475:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2586, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2551, - "src": "2483:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2581, - "name": "Deposit", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2460, - "src": "2445:7:4", - "typeDescriptions": { - "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (address,address,uint256,uint256)" - } - }, - "id": 2587, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2445:45:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2588, - "nodeType": "EmitStatement", - "src": "2440:50:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2590, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2556, - "src": "2514:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2591, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2551, - "src": "2522:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2589, - "name": "afterDeposit", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2952, - "src": "2501:12:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (uint256,uint256)" - } - }, - "id": 2592, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2501:28:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2593, - "nodeType": "ExpressionStatement", - "src": "2501:28:4" - } - ] - }, - "functionSelector": "94bf804d", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "mint", - "nameLocation": "2078:4:4", - "parameters": { - "id": 2554, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2551, - "mutability": "mutable", - "name": "shares", - "nameLocation": "2091:6:4", - "nodeType": "VariableDeclaration", - "scope": 2595, - "src": "2083:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2550, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "2083:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2553, - "mutability": "mutable", - "name": "receiver", - "nameLocation": "2107:8:4", - "nodeType": "VariableDeclaration", - "scope": 2595, - "src": "2099:16:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2552, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "2099:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "2082:34:4" - }, - "returnParameters": { - "id": 2557, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2556, - "mutability": "mutable", - "name": "assets", - "nameLocation": "2149:6:4", - "nodeType": "VariableDeclaration", - "scope": 2595, - "src": "2141:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2555, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "2141:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "2140:16:4" - }, - "scope": 2953, - "stateMutability": "nonpayable", - "virtual": true, - "visibility": "public" - }, - { - "id": 2673, - "nodeType": "FunctionDefinition", - "src": "2542:679:4", - "body": { - "id": 2672, - "nodeType": "Block", - "src": "2679:542:4", - "statements": [ - { - "expression": { - "id": 2610, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftHandSide": { - "id": 2606, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2604, - "src": "2689:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "Assignment", - "operator": "=", - "rightHandSide": { - "arguments": [ - { - "id": 2608, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2597, - "src": "2714:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2607, - "name": "previewWithdraw", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2870, - "src": "2698:15:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", - "typeString": "function (uint256) view returns (uint256)" - } - }, - "id": 2609, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2698:23:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "2689:32:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2611, - "nodeType": "ExpressionStatement", - "src": "2689:32:4" - }, - { - "condition": { - "commonType": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "id": 2615, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "expression": { - "id": 2612, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "2803:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2613, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "2803:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "nodeType": "BinaryOperation", - "operator": "!=", - "rightExpression": { - "id": 2614, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2601, - "src": "2817:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "src": "2803:19:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "id": 2645, - "nodeType": "IfStatement", - "src": "2799:228:4", - "trueBody": { - "id": 2644, - "nodeType": "Block", - "src": "2824:203:4", - "statements": [ - { - "assignments": [ - 2617 - ], - "declarations": [ - { - "constant": false, - "id": 2617, - "mutability": "mutable", - "name": "allowed", - "nameLocation": "2846:7:4", - "nodeType": "VariableDeclaration", - "scope": 2644, - "src": "2838:15:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2616, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "2838:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "id": 2624, - "initialValue": { - "baseExpression": { - "baseExpression": { - "id": 2618, - "name": "allowance", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31057, - "src": "2856:9:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", - "typeString": "mapping(address => mapping(address => uint256))" - } - }, - "id": 2620, - "indexExpression": { - "id": 2619, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2601, - "src": "2866:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "2856:16:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", - "typeString": "mapping(address => uint256)" - } - }, - "id": 2623, - "indexExpression": { - "expression": { - "id": 2621, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "2873:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2622, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "2873:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "2856:28:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "VariableDeclarationStatement", - "src": "2838:46:4" - }, - { - "condition": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2631, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2625, - "name": "allowed", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2617, - "src": "2939:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "!=", - "rightExpression": { - "expression": { - "arguments": [ - { - "id": 2628, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "nodeType": "ElementaryTypeNameExpression", - "src": "2955:7:4", - "typeDescriptions": { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - }, - "typeName": { - "id": 2627, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "2955:7:4", - "typeDescriptions": {} - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - } - ], - "id": 2626, - "name": "type", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -27, - "src": "2950:4:4", - "typeDescriptions": { - "typeIdentifier": "t_function_metatype_pure$__$returns$__$", - "typeString": "function () pure" - } - }, - "id": 2629, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "2950:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_magic_meta_type_t_uint256", - "typeString": "type(uint256)" - } - }, - "id": 2630, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "memberName": "max", - "nodeType": "MemberAccess", - "src": "2950:17:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "2939:28:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "id": 2643, - "nodeType": "IfStatement", - "src": "2935:81:4", - "trueBody": { - "expression": { - "id": 2641, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftHandSide": { - "baseExpression": { - "baseExpression": { - "id": 2632, - "name": "allowance", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31057, - "src": "2969:9:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", - "typeString": "mapping(address => mapping(address => uint256))" - } - }, - "id": 2636, - "indexExpression": { - "id": 2633, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2601, - "src": "2979:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "2969:16:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", - "typeString": "mapping(address => uint256)" - } - }, - "id": 2637, - "indexExpression": { - "expression": { - "id": 2634, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "2986:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2635, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "2986:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": true, - "nodeType": "IndexAccess", - "src": "2969:28:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "Assignment", - "operator": "=", - "rightHandSide": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2640, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2638, - "name": "allowed", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2617, - "src": "3000:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "-", - "rightExpression": { - "id": 2639, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2604, - "src": "3010:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "3000:16:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "2969:47:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2642, - "nodeType": "ExpressionStatement", - "src": "2969:47:4" - } - } - ] - } - }, - { - "expression": { - "arguments": [ - { - "id": 2647, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2597, - "src": "3052:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2648, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2604, - "src": "3060:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2646, - "name": "beforeWithdraw", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2944, - "src": "3037:14:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (uint256,uint256)" - } - }, - "id": 2649, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3037:30:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2650, - "nodeType": "ExpressionStatement", - "src": "3037:30:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2652, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2601, - "src": "3084:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2653, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2604, - "src": "3091:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2651, - "name": "_burn", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31407, - "src": "3078:5:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", - "typeString": "function (address,uint256)" - } - }, - "id": 2654, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3078:20:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2655, - "nodeType": "ExpressionStatement", - "src": "3078:20:4" - }, - { - "eventCall": { - "arguments": [ - { - "expression": { - "id": 2657, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "3123:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2658, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "3123:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2659, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2599, - "src": "3135:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2660, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2601, - "src": "3145:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2661, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2597, - "src": "3152:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2662, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2604, - "src": "3160:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2656, - "name": "Withdraw", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2472, - "src": "3114:8:4", - "typeDescriptions": { - "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (address,address,address,uint256,uint256)" - } - }, - "id": 2663, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3114:53:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2664, - "nodeType": "EmitStatement", - "src": "3109:58:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2668, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2599, - "src": "3197:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2669, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2597, - "src": "3207:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2665, - "name": "asset", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2475, - "src": "3178:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "id": 2667, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "safeTransfer", - "nodeType": "MemberAccess", - "referencedDeclaration": 32764, - "src": "3178:18:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", - "typeString": "function (contract ERC20,address,uint256)" - } - }, - "id": 2670, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3178:36:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2671, - "nodeType": "ExpressionStatement", - "src": "3178:36:4" - } - ] - }, - "functionSelector": "b460af94", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "withdraw", - "nameLocation": "2551:8:4", - "parameters": { - "id": 2602, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2597, - "mutability": "mutable", - "name": "assets", - "nameLocation": "2577:6:4", - "nodeType": "VariableDeclaration", - "scope": 2673, - "src": "2569:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2596, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "2569:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2599, - "mutability": "mutable", - "name": "receiver", - "nameLocation": "2601:8:4", - "nodeType": "VariableDeclaration", - "scope": 2673, - "src": "2593:16:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2598, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "2593:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2601, - "mutability": "mutable", - "name": "owner", - "nameLocation": "2627:5:4", - "nodeType": "VariableDeclaration", - "scope": 2673, - "src": "2619:13:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2600, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "2619:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "2559:79:4" - }, - "returnParameters": { - "id": 2605, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2604, - "mutability": "mutable", - "name": "shares", - "nameLocation": "2671:6:4", - "nodeType": "VariableDeclaration", - "scope": 2673, - "src": "2663:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2603, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "2663:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "2662:16:4" - }, - "scope": 2953, - "stateMutability": "nonpayable", - "virtual": true, - "visibility": "public" - }, - { - "id": 2757, - "nodeType": "FunctionDefinition", - "src": "3227:713:4", - "body": { - "id": 2756, - "nodeType": "Block", - "src": "3362:578:4", - "statements": [ - { - "condition": { - "commonType": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "id": 2687, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "expression": { - "id": 2684, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "3376:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2685, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "3376:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "nodeType": "BinaryOperation", - "operator": "!=", - "rightExpression": { - "id": 2686, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2679, - "src": "3390:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "src": "3376:19:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "id": 2717, - "nodeType": "IfStatement", - "src": "3372:228:4", - "trueBody": { - "id": 2716, - "nodeType": "Block", - "src": "3397:203:4", - "statements": [ - { - "assignments": [ - 2689 - ], - "declarations": [ - { - "constant": false, - "id": 2689, - "mutability": "mutable", - "name": "allowed", - "nameLocation": "3419:7:4", - "nodeType": "VariableDeclaration", - "scope": 2716, - "src": "3411:15:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2688, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "3411:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "id": 2696, - "initialValue": { - "baseExpression": { - "baseExpression": { - "id": 2690, - "name": "allowance", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31057, - "src": "3429:9:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", - "typeString": "mapping(address => mapping(address => uint256))" - } - }, - "id": 2692, - "indexExpression": { - "id": 2691, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2679, - "src": "3439:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "3429:16:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", - "typeString": "mapping(address => uint256)" - } - }, - "id": 2695, - "indexExpression": { - "expression": { - "id": 2693, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "3446:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2694, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "3446:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "3429:28:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "VariableDeclarationStatement", - "src": "3411:46:4" - }, - { - "condition": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2703, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2697, - "name": "allowed", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2689, - "src": "3512:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "!=", - "rightExpression": { - "expression": { - "arguments": [ - { - "id": 2700, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "nodeType": "ElementaryTypeNameExpression", - "src": "3528:7:4", - "typeDescriptions": { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - }, - "typeName": { - "id": 2699, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "3528:7:4", - "typeDescriptions": {} - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - } - ], - "id": 2698, - "name": "type", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -27, - "src": "3523:4:4", - "typeDescriptions": { - "typeIdentifier": "t_function_metatype_pure$__$returns$__$", - "typeString": "function () pure" - } - }, - "id": 2701, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3523:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_magic_meta_type_t_uint256", - "typeString": "type(uint256)" - } - }, - "id": 2702, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "memberName": "max", - "nodeType": "MemberAccess", - "src": "3523:17:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "3512:28:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "id": 2715, - "nodeType": "IfStatement", - "src": "3508:81:4", - "trueBody": { - "expression": { - "id": 2713, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftHandSide": { - "baseExpression": { - "baseExpression": { - "id": 2704, - "name": "allowance", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31057, - "src": "3542:9:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", - "typeString": "mapping(address => mapping(address => uint256))" - } - }, - "id": 2708, - "indexExpression": { - "id": 2705, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2679, - "src": "3552:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "3542:16:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", - "typeString": "mapping(address => uint256)" - } - }, - "id": 2709, - "indexExpression": { - "expression": { - "id": 2706, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "3559:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2707, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "3559:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": true, - "nodeType": "IndexAccess", - "src": "3542:28:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "Assignment", - "operator": "=", - "rightHandSide": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2712, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2710, - "name": "allowed", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2689, - "src": "3573:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "-", - "rightExpression": { - "id": 2711, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2675, - "src": "3583:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "3573:16:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "3542:47:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2714, - "nodeType": "ExpressionStatement", - "src": "3542:47:4" - } - } - ] - } - }, - { - "expression": { - "arguments": [ - { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2726, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "components": [ - { - "id": 2723, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftHandSide": { - "id": 2719, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2682, - "src": "3693:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "Assignment", - "operator": "=", - "rightHandSide": { - "arguments": [ - { - "id": 2721, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2675, - "src": "3716:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2720, - "name": "previewRedeem", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2882, - "src": "3702:13:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", - "typeString": "function (uint256) view returns (uint256)" - } - }, - "id": 2722, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3702:21:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "src": "3693:30:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "id": 2724, - "isConstant": false, - "isInlineArray": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "nodeType": "TupleExpression", - "src": "3692:32:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "!=", - "rightExpression": { - "hexValue": "30", - "id": 2725, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "3728:1:4", - "typeDescriptions": { - "typeIdentifier": "t_rational_0_by_1", - "typeString": "int_const 0" - }, - "value": "0" - }, - "src": "3692:37:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - { - "hexValue": "5a45524f5f415353455453", - "id": 2727, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "string", - "lValueRequested": false, - "nodeType": "Literal", - "src": "3731:13:4", - "typeDescriptions": { - "typeIdentifier": "t_stringliteral_bf169ab2ef12d57708bb5afe72ea54ba3ad2eccb91dd95f37571afa377c52483", - "typeString": "literal_string \"ZERO_ASSETS\"" - }, - "value": "ZERO_ASSETS" - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_bool", - "typeString": "bool" - }, - { - "typeIdentifier": "t_stringliteral_bf169ab2ef12d57708bb5afe72ea54ba3ad2eccb91dd95f37571afa377c52483", - "typeString": "literal_string \"ZERO_ASSETS\"" - } - ], - "id": 2718, - "name": "require", - "nodeType": "Identifier", - "overloadedDeclarations": [ - -18, - -18 - ], - "referencedDeclaration": -18, - "src": "3684:7:4", - "typeDescriptions": { - "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", - "typeString": "function (bool,string memory) pure" - } - }, - "id": 2728, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3684:61:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2729, - "nodeType": "ExpressionStatement", - "src": "3684:61:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2731, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2682, - "src": "3771:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2732, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2675, - "src": "3779:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2730, - "name": "beforeWithdraw", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2944, - "src": "3756:14:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (uint256,uint256)" - } - }, - "id": 2733, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3756:30:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2734, - "nodeType": "ExpressionStatement", - "src": "3756:30:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2736, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2679, - "src": "3803:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2737, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2675, - "src": "3810:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2735, - "name": "_burn", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31407, - "src": "3797:5:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", - "typeString": "function (address,uint256)" - } - }, - "id": 2738, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3797:20:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2739, - "nodeType": "ExpressionStatement", - "src": "3797:20:4" - }, - { - "eventCall": { - "arguments": [ - { - "expression": { - "id": 2741, - "name": "msg", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -15, - "src": "3842:3:4", - "typeDescriptions": { - "typeIdentifier": "t_magic_message", - "typeString": "msg" - } - }, - "id": 2742, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "sender", - "nodeType": "MemberAccess", - "src": "3842:10:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2743, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2677, - "src": "3854:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2744, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2679, - "src": "3864:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2745, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2682, - "src": "3871:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2746, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2675, - "src": "3879:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2740, - "name": "Withdraw", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2472, - "src": "3833:8:4", - "typeDescriptions": { - "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", - "typeString": "function (address,address,address,uint256,uint256)" - } - }, - "id": 2747, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3833:53:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2748, - "nodeType": "EmitStatement", - "src": "3828:58:4" - }, - { - "expression": { - "arguments": [ - { - "id": 2752, - "name": "receiver", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2677, - "src": "3916:8:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - { - "id": 2753, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2682, - "src": "3926:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_address", - "typeString": "address" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2749, - "name": "asset", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2475, - "src": "3897:5:4", - "typeDescriptions": { - "typeIdentifier": "t_contract$_ERC20_$31408", - "typeString": "contract ERC20" - } - }, - "id": 2751, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "safeTransfer", - "nodeType": "MemberAccess", - "referencedDeclaration": 32764, - "src": "3897:18:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", - "typeString": "function (contract ERC20,address,uint256)" - } - }, - "id": 2754, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "3897:36:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_tuple$__$", - "typeString": "tuple()" - } - }, - "id": 2755, - "nodeType": "ExpressionStatement", - "src": "3897:36:4" - } - ] - }, - "functionSelector": "ba087652", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "redeem", - "nameLocation": "3236:6:4", - "parameters": { - "id": 2680, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2675, - "mutability": "mutable", - "name": "shares", - "nameLocation": "3260:6:4", - "nodeType": "VariableDeclaration", - "scope": 2757, - "src": "3252:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2674, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "3252:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2677, - "mutability": "mutable", - "name": "receiver", - "nameLocation": "3284:8:4", - "nodeType": "VariableDeclaration", - "scope": 2757, - "src": "3276:16:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2676, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "3276:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2679, - "mutability": "mutable", - "name": "owner", - "nameLocation": "3310:5:4", - "nodeType": "VariableDeclaration", - "scope": 2757, - "src": "3302:13:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2678, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "3302:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "3242:79:4" - }, - "returnParameters": { - "id": 2683, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2682, - "mutability": "mutable", - "name": "assets", - "nameLocation": "3354:6:4", - "nodeType": "VariableDeclaration", - "scope": 2757, - "src": "3346:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2681, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "3346:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "3345:16:4" - }, - "scope": 2953, - "stateMutability": "nonpayable", - "virtual": true, - "visibility": "public" - }, - { - "id": 2762, - "nodeType": "FunctionDefinition", - "src": "4130:61:4", - "functionSelector": "01e1d114", - "implemented": false, - "kind": "function", - "modifiers": [], - "name": "totalAssets", - "nameLocation": "4139:11:4", - "parameters": { - "id": 2758, - "nodeType": "ParameterList", - "parameters": [], - "src": "4150:2:4" - }, - "returnParameters": { - "id": 2761, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2760, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2762, - "src": "4182:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2759, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4182:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4181:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2786, - "nodeType": "FunctionDefinition", - "src": "4197:257:4", - "body": { - "id": 2785, - "nodeType": "Block", - "src": "4276:178:4", - "statements": [ - { - "assignments": [ - 2770 - ], - "declarations": [ - { - "constant": false, - "id": 2770, - "mutability": "mutable", - "name": "supply", - "nameLocation": "4294:6:4", - "nodeType": "VariableDeclaration", - "scope": 2785, - "src": "4286:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2769, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4286:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "id": 2772, - "initialValue": { - "id": 2771, - "name": "totalSupply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31047, - "src": "4303:11:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "VariableDeclarationStatement", - "src": "4286:28:4" - }, - { - "expression": { - "condition": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2775, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2773, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2770, - "src": "4384:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "==", - "rightExpression": { - "hexValue": "30", - "id": 2774, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "4394:1:4", - "typeDescriptions": { - "typeIdentifier": "t_rational_0_by_1", - "typeString": "int_const 0" - }, - "value": "0" - }, - "src": "4384:11:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "falseExpression": { - "arguments": [ - { - "id": 2779, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2770, - "src": "4425:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "arguments": [], - "expression": { - "argumentTypes": [], - "id": 2780, - "name": "totalAssets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2762, - "src": "4433:11:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", - "typeString": "function () view returns (uint256)" - } - }, - "id": 2781, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "4433:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2777, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2764, - "src": "4407:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2778, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "mulDivDown", - "nodeType": "MemberAccess", - "referencedDeclaration": 32285, - "src": "4407:17:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", - "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" - } - }, - "id": 2782, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "4407:40:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2783, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "nodeType": "Conditional", - "src": "4384:63:4", - "trueExpression": { - "id": 2776, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2764, - "src": "4398:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2768, - "id": 2784, - "nodeType": "Return", - "src": "4377:70:4" - } - ] - }, - "functionSelector": "c6e6f592", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "convertToShares", - "nameLocation": "4206:15:4", - "parameters": { - "id": 2765, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2764, - "mutability": "mutable", - "name": "assets", - "nameLocation": "4230:6:4", - "nodeType": "VariableDeclaration", - "scope": 2786, - "src": "4222:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2763, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4222:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4221:16:4" - }, - "returnParameters": { - "id": 2768, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2767, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2786, - "src": "4267:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2766, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4267:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4266:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2810, - "nodeType": "FunctionDefinition", - "src": "4460:257:4", - "body": { - "id": 2809, - "nodeType": "Block", - "src": "4539:178:4", - "statements": [ - { - "assignments": [ - 2794 - ], - "declarations": [ - { - "constant": false, - "id": 2794, - "mutability": "mutable", - "name": "supply", - "nameLocation": "4557:6:4", - "nodeType": "VariableDeclaration", - "scope": 2809, - "src": "4549:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2793, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4549:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "id": 2796, - "initialValue": { - "id": 2795, - "name": "totalSupply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31047, - "src": "4566:11:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "VariableDeclarationStatement", - "src": "4549:28:4" - }, - { - "expression": { - "condition": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2799, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2797, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2794, - "src": "4647:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "==", - "rightExpression": { - "hexValue": "30", - "id": 2798, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "4657:1:4", - "typeDescriptions": { - "typeIdentifier": "t_rational_0_by_1", - "typeString": "int_const 0" - }, - "value": "0" - }, - "src": "4647:11:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "falseExpression": { - "arguments": [ - { - "arguments": [], - "expression": { - "argumentTypes": [], - "id": 2803, - "name": "totalAssets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2762, - "src": "4688:11:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", - "typeString": "function () view returns (uint256)" - } - }, - "id": 2804, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "4688:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2805, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2794, - "src": "4703:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2801, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2788, - "src": "4670:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2802, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "mulDivDown", - "nodeType": "MemberAccess", - "referencedDeclaration": 32285, - "src": "4670:17:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", - "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" - } - }, - "id": 2806, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "4670:40:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2807, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "nodeType": "Conditional", - "src": "4647:63:4", - "trueExpression": { - "id": 2800, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2788, - "src": "4661:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2792, - "id": 2808, - "nodeType": "Return", - "src": "4640:70:4" - } - ] - }, - "functionSelector": "07a2d13a", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "convertToAssets", - "nameLocation": "4469:15:4", - "parameters": { - "id": 2789, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2788, - "mutability": "mutable", - "name": "shares", - "nameLocation": "4493:6:4", - "nodeType": "VariableDeclaration", - "scope": 2810, - "src": "4485:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2787, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4485:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4484:16:4" - }, - "returnParameters": { - "id": 2792, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2791, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2810, - "src": "4530:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2790, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4530:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4529:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2822, - "nodeType": "FunctionDefinition", - "src": "4723:125:4", - "body": { - "id": 2821, - "nodeType": "Block", - "src": "4801:47:4", - "statements": [ - { - "expression": { - "arguments": [ - { - "id": 2818, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2812, - "src": "4834:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2817, - "name": "convertToShares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2786, - "src": "4818:15:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", - "typeString": "function (uint256) view returns (uint256)" - } - }, - "id": 2819, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "4818:23:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2816, - "id": 2820, - "nodeType": "Return", - "src": "4811:30:4" - } - ] - }, - "functionSelector": "ef8b30f7", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "previewDeposit", - "nameLocation": "4732:14:4", - "parameters": { - "id": 2813, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2812, - "mutability": "mutable", - "name": "assets", - "nameLocation": "4755:6:4", - "nodeType": "VariableDeclaration", - "scope": 2822, - "src": "4747:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2811, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4747:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4746:16:4" - }, - "returnParameters": { - "id": 2816, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2815, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2822, - "src": "4792:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2814, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4792:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4791:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2846, - "nodeType": "FunctionDefinition", - "src": "4854:251:4", - "body": { - "id": 2845, - "nodeType": "Block", - "src": "4929:176:4", - "statements": [ - { - "assignments": [ - 2830 - ], - "declarations": [ - { - "constant": false, - "id": 2830, - "mutability": "mutable", - "name": "supply", - "nameLocation": "4947:6:4", - "nodeType": "VariableDeclaration", - "scope": 2845, - "src": "4939:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2829, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4939:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "id": 2832, - "initialValue": { - "id": 2831, - "name": "totalSupply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31047, - "src": "4956:11:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "VariableDeclarationStatement", - "src": "4939:28:4" - }, - { - "expression": { - "condition": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2835, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2833, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2830, - "src": "5037:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "==", - "rightExpression": { - "hexValue": "30", - "id": 2834, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "5047:1:4", - "typeDescriptions": { - "typeIdentifier": "t_rational_0_by_1", - "typeString": "int_const 0" - }, - "value": "0" - }, - "src": "5037:11:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "falseExpression": { - "arguments": [ - { - "arguments": [], - "expression": { - "argumentTypes": [], - "id": 2839, - "name": "totalAssets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2762, - "src": "5076:11:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", - "typeString": "function () view returns (uint256)" - } - }, - "id": 2840, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "5076:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "id": 2841, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2830, - "src": "5091:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2837, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2824, - "src": "5060:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2838, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "mulDivUp", - "nodeType": "MemberAccess", - "referencedDeclaration": 32298, - "src": "5060:15:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", - "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" - } - }, - "id": 2842, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "5060:38:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2843, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "nodeType": "Conditional", - "src": "5037:61:4", - "trueExpression": { - "id": 2836, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2824, - "src": "5051:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2828, - "id": 2844, - "nodeType": "Return", - "src": "5030:68:4" - } - ] - }, - "functionSelector": "b3d7f6b9", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "previewMint", - "nameLocation": "4863:11:4", - "parameters": { - "id": 2825, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2824, - "mutability": "mutable", - "name": "shares", - "nameLocation": "4883:6:4", - "nodeType": "VariableDeclaration", - "scope": 2846, - "src": "4875:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2823, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4875:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4874:16:4" - }, - "returnParameters": { - "id": 2828, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2827, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2846, - "src": "4920:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2826, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "4920:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "4919:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2870, - "nodeType": "FunctionDefinition", - "src": "5111:255:4", - "body": { - "id": 2869, - "nodeType": "Block", - "src": "5190:176:4", - "statements": [ - { - "assignments": [ - 2854 - ], - "declarations": [ - { - "constant": false, - "id": 2854, - "mutability": "mutable", - "name": "supply", - "nameLocation": "5208:6:4", - "nodeType": "VariableDeclaration", - "scope": 2869, - "src": "5200:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2853, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5200:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "id": 2856, - "initialValue": { - "id": 2855, - "name": "totalSupply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31047, - "src": "5217:11:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "VariableDeclarationStatement", - "src": "5200:28:4" - }, - { - "expression": { - "condition": { - "commonType": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "id": 2859, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "leftExpression": { - "id": 2857, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2854, - "src": "5298:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "nodeType": "BinaryOperation", - "operator": "==", - "rightExpression": { - "hexValue": "30", - "id": 2858, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "number", - "lValueRequested": false, - "nodeType": "Literal", - "src": "5308:1:4", - "typeDescriptions": { - "typeIdentifier": "t_rational_0_by_1", - "typeString": "int_const 0" - }, - "value": "0" - }, - "src": "5298:11:4", - "typeDescriptions": { - "typeIdentifier": "t_bool", - "typeString": "bool" - } - }, - "falseExpression": { - "arguments": [ - { - "id": 2863, - "name": "supply", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2854, - "src": "5337:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - { - "arguments": [], - "expression": { - "argumentTypes": [], - "id": 2864, - "name": "totalAssets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2762, - "src": "5345:11:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", - "typeString": "function () view returns (uint256)" - } - }, - "id": 2865, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "5345:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "expression": { - "id": 2861, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2848, - "src": "5321:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2862, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "memberName": "mulDivUp", - "nodeType": "MemberAccess", - "referencedDeclaration": 32298, - "src": "5321:15:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", - "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" - } - }, - "id": 2866, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "5321:38:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "id": 2867, - "isConstant": false, - "isLValue": false, - "isPure": false, - "lValueRequested": false, - "nodeType": "Conditional", - "src": "5298:61:4", - "trueExpression": { - "id": 2860, - "name": "assets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2848, - "src": "5312:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2852, - "id": 2868, - "nodeType": "Return", - "src": "5291:68:4" - } - ] - }, - "functionSelector": "0a28a477", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "previewWithdraw", - "nameLocation": "5120:15:4", - "parameters": { - "id": 2849, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2848, - "mutability": "mutable", - "name": "assets", - "nameLocation": "5144:6:4", - "nodeType": "VariableDeclaration", - "scope": 2870, - "src": "5136:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2847, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5136:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "5135:16:4" - }, - "returnParameters": { - "id": 2852, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2851, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2870, - "src": "5181:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2850, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5181:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "5180:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2882, - "nodeType": "FunctionDefinition", - "src": "5372:124:4", - "body": { - "id": 2881, - "nodeType": "Block", - "src": "5449:47:4", - "statements": [ - { - "expression": { - "arguments": [ - { - "id": 2878, - "name": "shares", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2872, - "src": "5482:6:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2877, - "name": "convertToAssets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2810, - "src": "5466:15:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", - "typeString": "function (uint256) view returns (uint256)" - } - }, - "id": 2879, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "5466:23:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2876, - "id": 2880, - "nodeType": "Return", - "src": "5459:30:4" - } - ] - }, - "functionSelector": "4cdad506", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "previewRedeem", - "nameLocation": "5381:13:4", - "parameters": { - "id": 2873, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2872, - "mutability": "mutable", - "name": "shares", - "nameLocation": "5403:6:4", - "nodeType": "VariableDeclaration", - "scope": 2882, - "src": "5395:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2871, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5395:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "5394:16:4" - }, - "returnParameters": { - "id": 2876, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2875, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2882, - "src": "5440:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2874, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5440:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "5439:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2896, - "nodeType": "FunctionDefinition", - "src": "5693:108:4", - "body": { - "id": 2895, - "nodeType": "Block", - "src": "5760:41:4", - "statements": [ - { - "expression": { - "expression": { - "arguments": [ - { - "id": 2891, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "nodeType": "ElementaryTypeNameExpression", - "src": "5782:7:4", - "typeDescriptions": { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - }, - "typeName": { - "id": 2890, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5782:7:4", - "typeDescriptions": {} - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - } - ], - "id": 2889, - "name": "type", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -27, - "src": "5777:4:4", - "typeDescriptions": { - "typeIdentifier": "t_function_metatype_pure$__$returns$__$", - "typeString": "function () pure" - } - }, - "id": 2892, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "5777:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_magic_meta_type_t_uint256", - "typeString": "type(uint256)" - } - }, - "id": 2893, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "memberName": "max", - "nodeType": "MemberAccess", - "src": "5777:17:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2888, - "id": 2894, - "nodeType": "Return", - "src": "5770:24:4" - } - ] - }, - "functionSelector": "402d267d", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "maxDeposit", - "nameLocation": "5702:10:4", - "parameters": { - "id": 2885, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2884, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2896, - "src": "5713:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2883, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "5713:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "5712:9:4" - }, - "returnParameters": { - "id": 2888, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2887, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2896, - "src": "5751:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2886, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5751:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "5750:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2910, - "nodeType": "FunctionDefinition", - "src": "5807:105:4", - "body": { - "id": 2909, - "nodeType": "Block", - "src": "5871:41:4", - "statements": [ - { - "expression": { - "expression": { - "arguments": [ - { - "id": 2905, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "nodeType": "ElementaryTypeNameExpression", - "src": "5893:7:4", - "typeDescriptions": { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - }, - "typeName": { - "id": 2904, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5893:7:4", - "typeDescriptions": {} - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_type$_t_uint256_$", - "typeString": "type(uint256)" - } - ], - "id": 2903, - "name": "type", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": -27, - "src": "5888:4:4", - "typeDescriptions": { - "typeIdentifier": "t_function_metatype_pure$__$returns$__$", - "typeString": "function () pure" - } - }, - "id": 2906, - "isConstant": false, - "isLValue": false, - "isPure": true, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "5888:13:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_magic_meta_type_t_uint256", - "typeString": "type(uint256)" - } - }, - "id": 2907, - "isConstant": false, - "isLValue": false, - "isPure": true, - "lValueRequested": false, - "memberName": "max", - "nodeType": "MemberAccess", - "src": "5888:17:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2902, - "id": 2908, - "nodeType": "Return", - "src": "5881:24:4" - } - ] - }, - "functionSelector": "c63d75b6", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "maxMint", - "nameLocation": "5816:7:4", - "parameters": { - "id": 2899, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2898, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2910, - "src": "5824:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2897, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "5824:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "5823:9:4" - }, - "returnParameters": { - "id": 2902, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2901, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2910, - "src": "5862:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2900, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5862:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "5861:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2924, - "nodeType": "FunctionDefinition", - "src": "5918:131:4", - "body": { - "id": 2923, - "nodeType": "Block", - "src": "5992:57:4", - "statements": [ - { - "expression": { - "arguments": [ - { - "baseExpression": { - "id": 2918, - "name": "balanceOf", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31051, - "src": "6025:9:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", - "typeString": "mapping(address => uint256)" - } - }, - "id": 2920, - "indexExpression": { - "id": 2919, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2912, - "src": "6035:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "6025:16:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - } - ], - "expression": { - "argumentTypes": [ - { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - ], - "id": 2917, - "name": "convertToAssets", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2810, - "src": "6009:15:4", - "typeDescriptions": { - "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", - "typeString": "function (uint256) view returns (uint256)" - } - }, - "id": 2921, - "isConstant": false, - "isLValue": false, - "isPure": false, - "kind": "functionCall", - "lValueRequested": false, - "names": [], - "nodeType": "FunctionCall", - "src": "6009:33:4", - "tryCall": false, - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2916, - "id": 2922, - "nodeType": "Return", - "src": "6002:40:4" - } - ] - }, - "functionSelector": "ce96cb77", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "maxWithdraw", - "nameLocation": "5927:11:4", - "parameters": { - "id": 2913, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2912, - "mutability": "mutable", - "name": "owner", - "nameLocation": "5947:5:4", - "nodeType": "VariableDeclaration", - "scope": 2924, - "src": "5939:13:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2911, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "5939:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "5938:15:4" - }, - "returnParameters": { - "id": 2916, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2915, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2924, - "src": "5983:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2914, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "5983:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "5982:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2936, - "nodeType": "FunctionDefinition", - "src": "6055:112:4", - "body": { - "id": 2935, - "nodeType": "Block", - "src": "6127:40:4", - "statements": [ - { - "expression": { - "baseExpression": { - "id": 2931, - "name": "balanceOf", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 31051, - "src": "6144:9:4", - "typeDescriptions": { - "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", - "typeString": "mapping(address => uint256)" - } - }, - "id": 2933, - "indexExpression": { - "id": 2932, - "name": "owner", - "nodeType": "Identifier", - "overloadedDeclarations": [], - "referencedDeclaration": 2926, - "src": "6154:5:4", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "isConstant": false, - "isLValue": true, - "isPure": false, - "lValueRequested": false, - "nodeType": "IndexAccess", - "src": "6144:16:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "functionReturnParameters": 2930, - "id": 2934, - "nodeType": "Return", - "src": "6137:23:4" - } - ] - }, - "functionSelector": "d905777e", - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "maxRedeem", - "nameLocation": "6064:9:4", - "parameters": { - "id": 2927, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2926, - "mutability": "mutable", - "name": "owner", - "nameLocation": "6082:5:4", - "nodeType": "VariableDeclaration", - "scope": 2936, - "src": "6074:13:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - }, - "typeName": { - "id": 2925, - "name": "address", - "nodeType": "ElementaryTypeName", - "src": "6074:7:4", - "stateMutability": "nonpayable", - "typeDescriptions": { - "typeIdentifier": "t_address", - "typeString": "address" - } - }, - "visibility": "internal" - } - ], - "src": "6073:15:4" - }, - "returnParameters": { - "id": 2930, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2929, - "mutability": "mutable", - "name": "", - "nameLocation": "-1:-1:-1", - "nodeType": "VariableDeclaration", - "scope": 2936, - "src": "6118:7:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2928, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "6118:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "6117:9:4" - }, - "scope": 2953, - "stateMutability": "view", - "virtual": true, - "visibility": "public" - }, - { - "id": 2944, - "nodeType": "FunctionDefinition", - "src": "6359:75:4", - "body": { - "id": 2943, - "nodeType": "Block", - "src": "6432:2:4", - "statements": [] - }, - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "beforeWithdraw", - "nameLocation": "6368:14:4", - "parameters": { - "id": 2941, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2938, - "mutability": "mutable", - "name": "assets", - "nameLocation": "6391:6:4", - "nodeType": "VariableDeclaration", - "scope": 2944, - "src": "6383:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2937, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "6383:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2940, - "mutability": "mutable", - "name": "shares", - "nameLocation": "6407:6:4", - "nodeType": "VariableDeclaration", - "scope": 2944, - "src": "6399:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2939, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "6399:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "6382:32:4" - }, - "returnParameters": { - "id": 2942, - "nodeType": "ParameterList", - "parameters": [], - "src": "6432:0:4" - }, - "scope": 2953, - "stateMutability": "nonpayable", - "virtual": true, - "visibility": "internal" - }, - { - "id": 2952, - "nodeType": "FunctionDefinition", - "src": "6440:73:4", - "body": { - "id": 2951, - "nodeType": "Block", - "src": "6511:2:4", - "statements": [] - }, - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "afterDeposit", - "nameLocation": "6449:12:4", - "parameters": { - "id": 2949, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2946, - "mutability": "mutable", - "name": "assets", - "nameLocation": "6470:6:4", - "nodeType": "VariableDeclaration", - "scope": 2952, - "src": "6462:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2945, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "6462:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - }, - { - "constant": false, - "id": 2948, - "mutability": "mutable", - "name": "shares", - "nameLocation": "6486:6:4", - "nodeType": "VariableDeclaration", - "scope": 2952, - "src": "6478:14:4", - "stateVariable": false, - "storageLocation": "default", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - }, - "typeName": { - "id": 2947, - "name": "uint256", - "nodeType": "ElementaryTypeName", - "src": "6478:7:4", - "typeDescriptions": { - "typeIdentifier": "t_uint256", - "typeString": "uint256" - } - }, - "visibility": "internal" - } - ], - "src": "6461:32:4" - }, - "returnParameters": { - "id": 2950, - "nodeType": "ParameterList", - "parameters": [], - "src": "6511:0:4" - }, - "scope": 2953, - "stateMutability": "nonpayable", - "virtual": true, - "visibility": "internal" - } - ], - "abstract": true, - "baseContracts": [ - { - "baseName": { - "id": 2442, - "name": "ERC20", - "nodeType": "IdentifierPath", - "referencedDeclaration": 31408, - "src": "424:5:4" - }, - "id": 2443, - "nodeType": "InheritanceSpecifier", - "src": "424:5:4" - } - ], - "canonicalName": "ERC4626", - "contractDependencies": [], - "contractKind": "contract", - "documentation": { - "id": 2441, - "nodeType": "StructuredDocumentation", - "src": "240:155:4", - "text": "@notice Minimal ERC4626 tokenized Vault implementation.\n @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)" - }, - "fullyImplemented": false, - "linearizedBaseContracts": [ - 2953, - 31408 - ], - "name": "ERC4626", - "nameLocation": "413:7:4", - "scope": 2954, - "usedErrors": [] - } - ], - "license": "AGPL-3.0-only" -} diff --git a/ethers-solc/test-data/ast/base_constructor_call.json b/ethers-solc/test-data/ast/base_constructor_call.json new file mode 100644 index 00000000..774981fa --- /dev/null +++ b/ethers-solc/test-data/ast/base_constructor_call.json @@ -0,0 +1,226 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 7 + ], + "C": + [ + 17 + ] + }, + "id": 18, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "A", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 7, + "linearizedBaseContracts": + [ + 7 + ], + "name": "A", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 5, + "nodeType": "Block", + "src": "31:2:1", + "statements": [] + }, + "id": 6, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 6, + "src": "25:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "25:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "24:6:1" + }, + "returnParameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "31:0:1" + }, + "scope": 7, + "src": "13:20:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 18, + "src": "0:35:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 8, + "name": "A", + "nameLocations": + [ + "50:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 7, + "src": "50:1:1" + }, + "id": 9, + "nodeType": "InheritanceSpecifier", + "src": "50:1:1" + } + ], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 17, + "linearizedBaseContracts": + [ + 17, + 7 + ], + "name": "C", + "nameLocation": "45:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 15, + "nodeType": "Block", + "src": "73:2:1", + "statements": [] + }, + "id": 16, + "implemented": true, + "kind": "constructor", + "modifiers": + [ + { + "arguments": + [ + { + "hexValue": "32", + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "70:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "id": 13, + "kind": "baseConstructorSpecifier", + "modifierName": + { + "id": 11, + "name": "A", + "nameLocations": + [ + "68:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 7, + "src": "68:1:1" + }, + "nodeType": "ModifierInvocation", + "src": "68:4:1" + } + ], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 10, + "nodeType": "ParameterList", + "parameters": [], + "src": "65:2:1" + }, + "returnParameters": + { + "id": 14, + "nodeType": "ParameterList", + "parameters": [], + "src": "73:0:1" + }, + "scope": 17, + "src": "54:21:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 18, + "src": "36:41:1", + "usedErrors": [] + } + ], + "src": "0:78:1" +} diff --git a/ethers-solc/test-data/ast/bit_not.json b/ethers-solc/test-data/ast/bit_not.json new file mode 100644 index 00000000..1f9708a9 --- /dev/null +++ b/ethers-solc/test-data/ast/bit_not.json @@ -0,0 +1,390 @@ +{ + "absolutePath": "Bytes.sol", + "exportedSymbols": + { + "Bytes": + [ + 25 + ] + }, + "id": 26, + "license": "UNLICENSED", + "nodeType": "SourceUnit", + "nodes": + [ + { + "id": 1, + "literals": + [ + "solidity", + "0.8", + ".13" + ], + "nodeType": "PragmaDirective", + "src": "40:23:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "Bytes", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 25, + "linearizedBaseContracts": + [ + 25 + ], + "name": "Bytes", + "nameLocation": "73:5:0", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 23, + "nodeType": "Block", + "src": "207:164:0", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + }, + "id": 21, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 12, + "name": "_packedBools", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "314:12:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "nodeType": "BinaryOperation", + "operator": "&", + "rightExpression": + { + "id": 20, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "~", + "prefix": true, + "src": "329:28:0", + "subExpression": + { + "components": + [ + { + "commonType": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + }, + "id": 18, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "arguments": + [ + { + "hexValue": "31", + "id": 15, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "339:1:0", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "331:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_uint192_$", + "typeString": "type(uint192)" + }, + "typeName": + { + "id": 13, + "name": "uint192", + "nodeType": "ElementaryTypeName", + "src": "331:7:0", + "typeDescriptions": {} + } + }, + "id": 16, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "331:10:0", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "nodeType": "BinaryOperation", + "operator": "<<", + "rightExpression": + { + "id": 17, + "name": "_boolNumber", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "345:11:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "src": "331:25:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + } + ], + "id": 19, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "330:27:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "src": "314:43:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "functionReturnParameters": 11, + "id": 22, + "nodeType": "Return", + "src": "307:50:0" + } + ] + }, + "id": 24, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "setBoolean", + "nameLocation": "92:10:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "_packedBools", + "nameLocation": "116:12:0", + "nodeType": "VariableDeclaration", + "scope": 24, + "src": "108:20:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + }, + "typeName": + { + "id": 2, + "name": "uint192", + "nodeType": "ElementaryTypeName", + "src": "108:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 5, + "mutability": "mutable", + "name": "_boolNumber", + "nameLocation": "142:11:0", + "nodeType": "VariableDeclaration", + "scope": 24, + "src": "134:19:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + }, + "typeName": + { + "id": 4, + "name": "uint192", + "nodeType": "ElementaryTypeName", + "src": "134:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 7, + "mutability": "mutable", + "name": "_value", + "nameLocation": "164:6:0", + "nodeType": "VariableDeclaration", + "scope": 24, + "src": "159:11:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": + { + "id": 6, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "159:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "102:72:0" + }, + "returnParameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 10, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 24, + "src": "198:7:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + }, + "typeName": + { + "id": 9, + "name": "uint192", + "nodeType": "ElementaryTypeName", + "src": "198:7:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint192", + "typeString": "uint192" + } + }, + "visibility": "internal" + } + ], + "src": "197:9:0" + }, + "scope": 25, + "src": "83:288:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 26, + "src": "65:308:0", + "usedErrors": [] + } + ], + "src": "40:334:0" +} \ No newline at end of file diff --git a/ethers-solc/test-data/ast/call.json b/ethers-solc/test-data/ast/call.json new file mode 100644 index 00000000..9d318604 --- /dev/null +++ b/ethers-solc/test-data/ast/call.json @@ -0,0 +1,171 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "37:59:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "56:34:1", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "67:1:1", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "70:1:1", + "type": "", + "value": "1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "73:1:1", + "type": "", + "value": "2" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "76:1:1", + "type": "", + "value": "3" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "79:1:1", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "82:1:1", + "type": "", + "value": "5" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "85:1:1", + "type": "", + "value": "6" + } + ], + "functionName": + { + "name": "call", + "nodeType": "YulIdentifier", + "src": "62:4:1" + }, + "nodeType": "YulFunctionCall", + "src": "62:25:1" + } + ], + "functionName": + { + "name": "pop", + "nodeType": "YulIdentifier", + "src": "58:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "58:30:1" + }, + "nodeType": "YulExpressionStatement", + "src": "58:30:1" + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "47:43:1" + } + ] + }, + "functionSelector": "b582ec5f", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "j", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "37:0:1" + }, + "scope": 6, + "src": "17:79:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:98:1", + "usedErrors": [] + } + ], + "src": "0:99:1" +} diff --git a/ethers-solc/test-data/ast/constructor.json b/ethers-solc/test-data/ast/constructor.json new file mode 100644 index 00000000..9ac4ac9c --- /dev/null +++ b/ethers-solc/test-data/ast/constructor.json @@ -0,0 +1,73 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "28:4:1", + "statements": [] + }, + "id": 4, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "25:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "28:0:1" + }, + "scope": 5, + "src": "14:18:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 6, + "src": "0:34:1", + "usedErrors": [] + } + ], + "src": "0:35:1" +} diff --git a/ethers-solc/test-data/ast/contract_dep_order.json b/ethers-solc/test-data/ast/contract_dep_order.json new file mode 100644 index 00000000..83865d7d --- /dev/null +++ b/ethers-solc/test-data/ast/contract_dep_order.json @@ -0,0 +1,218 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 1 + ], + "B": + [ + 4 + ], + "C": + [ + 7 + ], + "D": + [ + 10 + ], + "E": + [ + 13 + ] + }, + "id": 14, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "A", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "A", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "0:14:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 2, + "name": "A", + "nameLocations": + [ + "29:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1, + "src": "29:1:1" + }, + "id": 3, + "nodeType": "InheritanceSpecifier", + "src": "29:1:1" + } + ], + "canonicalName": "B", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4, + 1 + ], + "name": "B", + "nameLocation": "24:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "15:19:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 5, + "name": "B", + "nameLocations": + [ + "49:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 4, + "src": "49:1:1" + }, + "id": 6, + "nodeType": "InheritanceSpecifier", + "src": "49:1:1" + } + ], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 7, + "linearizedBaseContracts": + [ + 7, + 4, + 1 + ], + "name": "C", + "nameLocation": "44:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "35:19:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 8, + "name": "C", + "nameLocations": + [ + "69:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 7, + "src": "69:1:1" + }, + "id": 9, + "nodeType": "InheritanceSpecifier", + "src": "69:1:1" + } + ], + "canonicalName": "D", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 10, + "linearizedBaseContracts": + [ + 10, + 7, + 4, + 1 + ], + "name": "D", + "nameLocation": "64:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "55:19:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 11, + "name": "D", + "nameLocations": + [ + "89:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 10, + "src": "89:1:1" + }, + "id": 12, + "nodeType": "InheritanceSpecifier", + "src": "89:1:1" + } + ], + "canonicalName": "E", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 13, + "linearizedBaseContracts": + [ + 13, + 10, + 7, + 4, + 1 + ], + "name": "E", + "nameLocation": "84:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "75:19:1", + "usedErrors": [] + } + ], + "src": "0:95:1" +} diff --git a/ethers-solc/test-data/ast/documentation_1.json b/ethers-solc/test-data/ast/documentation_1.json new file mode 100644 index 00000000..3d51055a --- /dev/null +++ b/ethers-solc/test-data/ast/documentation_1.json @@ -0,0 +1,43 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 2 + ] + }, + "id": 3, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "documentation": + { + "id": 1, + "nodeType": "StructuredDocumentation", + "src": "0:27:1", + "text": "This contract is empty" + }, + "fullyImplemented": true, + "id": 2, + "linearizedBaseContracts": + [ + 2 + ], + "name": "C", + "nameLocation": "37:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 3, + "src": "28:13:1", + "usedErrors": [] + } + ], + "src": "28:14:1" +} diff --git a/ethers-solc/test-data/ast/documentation_2.json b/ethers-solc/test-data/ast/documentation_2.json new file mode 100644 index 00000000..822c5eac --- /dev/null +++ b/ethers-solc/test-data/ast/documentation_2.json @@ -0,0 +1,43 @@ +{ + "absolutePath": "b", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "documentation": + { + "id": 4, + "nodeType": "StructuredDocumentation", + "src": "0:61:2", + "text": "This contract is empty\nand has a line-breaking comment." + }, + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nameLocation": "71:1:2", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 6, + "src": "62:13:2", + "usedErrors": [] + } + ], + "src": "62:14:2" +} diff --git a/ethers-solc/test-data/ast/documentation_3.json b/ethers-solc/test-data/ast/documentation_3.json new file mode 100644 index 00000000..dee8b83f --- /dev/null +++ b/ethers-solc/test-data/ast/documentation_3.json @@ -0,0 +1,179 @@ +{ + "absolutePath": "c", + "exportedSymbols": + { + "C": + [ + 23 + ] + }, + "id": 24, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 23, + "linearizedBaseContracts": + [ + 23 + ], + "name": "C", + "nameLocation": "9:1:3", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "documentation": + { + "id": 7, + "nodeType": "StructuredDocumentation", + "src": "15:32:3", + "text": "Some comment on state var." + }, + "functionSelector": "c19d93fb", + "id": 9, + "mutability": "mutable", + "name": "state", + "nameLocation": "60:5:3", + "nodeType": "VariableDeclaration", + "scope": 23, + "src": "48:17:3", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 8, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "48:4:3", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "public" + }, + { + "anonymous": false, + "documentation": + { + "id": 10, + "nodeType": "StructuredDocumentation", + "src": "69:26:3", + "text": "Some comment on Evt." + }, + "eventSelector": "a69007916fc1145953e5a7032d7c3eab4b8e2f33ec59b0f71e732904eeede3a4", + "id": 12, + "name": "Evt", + "nameLocation": "102:3:3", + "nodeType": "EventDefinition", + "parameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "105:2:3" + }, + "src": "96:12:3" + }, + { + "body": + { + "id": 16, + "nodeType": "Block", + "src": "153:6:3", + "statements": + [ + { + "id": 15, + "nodeType": "PlaceholderStatement", + "src": "155:1:3" + } + ] + }, + "documentation": + { + "id": 13, + "nodeType": "StructuredDocumentation", + "src": "111:26:3", + "text": "Some comment on mod." + }, + "id": 17, + "name": "mod", + "nameLocation": "147:3:3", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 14, + "nodeType": "ParameterList", + "parameters": [], + "src": "150:2:3" + }, + "src": "138:21:3", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 21, + "nodeType": "Block", + "src": "209:2:3", + "statements": [] + }, + "documentation": + { + "id": 18, + "nodeType": "StructuredDocumentation", + "src": "162:25:3", + "text": "Some comment on fn." + }, + "functionSelector": "a4a2c40b", + "id": 22, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "fn", + "nameLocation": "197:2:3", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "199:2:3" + }, + "returnParameters": + { + "id": 20, + "nodeType": "ParameterList", + "parameters": [], + "src": "209:0:3" + }, + "scope": 23, + "src": "188:23:3", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 24, + "src": "0:213:3", + "usedErrors": [] + } + ], + "src": "0:214:3" +} diff --git a/ethers-solc/test-data/ast/documentation_local_variable.json b/ethers-solc/test-data/ast/documentation_local_variable.json new file mode 100644 index 00000000..24e38eb1 --- /dev/null +++ b/ethers-solc/test-data/ast/documentation_local_variable.json @@ -0,0 +1,491 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 41 + ] + }, + "id": 42, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 41, + "linearizedBaseContracts": + [ + 41 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 26, + "nodeType": "Block", + "src": "42:330:1", + "statements": + [ + { + "assignments": + [ + 5 + ], + "declarations": + [ + { + "constant": false, + "id": 5, + "mutability": "mutable", + "name": "x", + "nameLocation": "114:1:1", + "nodeType": "VariableDeclaration", + "scope": 26, + "src": "109:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "109:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "documentation": "Documentation for x; will appear in ast json", + "id": 7, + "initialValue": + { + "hexValue": "31", + "id": 6, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "118:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "nodeType": "VariableDeclarationStatement", + "src": "109:10:1" + }, + { + "body": + { + "id": 24, + "nodeType": "Block", + "src": "270:96:1", + "statements": + [ + { + "assignments": + [ + 21 + ], + "declarations": + [ + { + "constant": false, + "id": 21, + "mutability": "mutable", + "name": "j", + "nameLocation": "350:1:1", + "nodeType": "VariableDeclaration", + "scope": 24, + "src": "345:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 20, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "345:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "documentation": "documentation for j; will appear in ast json", + "id": 23, + "initialValue": + { + "hexValue": "30", + "id": 22, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "354:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "345:10:1" + } + ] + }, + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 15, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 13, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10, + "src": "236:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "hexValue": "3130", + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "240:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_10_by_1", + "typeString": "int_const 10" + }, + "value": "10" + }, + "src": "236:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 25, + "initializationExpression": + { + "assignments": + [ + 10 + ], + "declarations": + [ + { + "constant": false, + "id": 10, + "mutability": "mutable", + "name": "i", + "nameLocation": "217:1:1", + "nodeType": "VariableDeclaration", + "scope": 25, + "src": "212:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 9, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "212:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 12, + "initialValue": + { + "hexValue": "30", + "id": 11, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "221:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "212:10:1" + }, + "loopExpression": + { + "expression": + { + "id": 17, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": true, + "src": "256:3:1", + "subExpression": + { + "id": 16, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 10, + "src": "258:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 18, + "nodeType": "ExpressionStatement", + "src": "256:3:1" + }, + "nodeType": "ForStatement", + "src": "129:237:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 27, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 41, + "src": "17:355:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + }, + { + "body": + { + "id": 39, + "nodeType": "Block", + "src": "662:2:1", + "statements": [] + }, + "functionSelector": "191157d1", + "id": 40, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "g", + "nameLocation": "386:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 37, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 30, + "mutability": "mutable", + "name": "param1", + "nameLocation": "468:6:1", + "nodeType": "VariableDeclaration", + "scope": 40, + "src": "463:11:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 29, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "463:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 33, + "mutability": "mutable", + "name": "param2", + "nameLocation": "555:6:1", + "nodeType": "VariableDeclaration", + "scope": 40, + "src": "550:11:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 32, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "550:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 36, + "mutability": "mutable", + "name": "param3", + "nameLocation": "642:6:1", + "nodeType": "VariableDeclaration", + "scope": 40, + "src": "637:11:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 35, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "637:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "387:267:1" + }, + "returnParameters": + { + "id": 38, + "nodeType": "ParameterList", + "parameters": [], + "src": "662:0:1" + }, + "scope": 41, + "src": "377:287:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 42, + "src": "0:666:1", + "usedErrors": [] + } + ], + "src": "0:667:1" +} diff --git a/ethers-solc/test-data/ast/documentation_on_statements.json b/ethers-solc/test-data/ast/documentation_on_statements.json new file mode 100644 index 00000000..bb3ee28d --- /dev/null +++ b/ethers-solc/test-data/ast/documentation_on_statements.json @@ -0,0 +1,376 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 27 + ] + }, + "id": 28, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 27, + "linearizedBaseContracts": + [ + 27 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "a", + "nameLocation": "50:1:1", + "nodeType": "VariableDeclaration", + "scope": 27, + "src": "45:6:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "45:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "body": + { + "id": 25, + "nodeType": "Block", + "src": "99:229:1", + "statements": + [ + { + "body": + { + "id": 21, + "nodeType": "Block", + "src": "156:66:1", + "statements": + [ + { + "expression": + { + "id": 19, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 17, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "205:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "hexValue": "32", + "id": 18, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "210:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "205:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 20, + "nodeType": "ExpressionStatement", + "src": "205:6:1" + } + ] + }, + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 13, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 11, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8, + "src": "143:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "hexValue": "3230", + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "147:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_20_by_1", + "typeString": "int_const 20" + }, + "value": "20" + }, + "src": "143:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 22, + "initializationExpression": + { + "assignments": + [ + 8 + ], + "declarations": + [ + { + "constant": false, + "id": 8, + "mutability": "mutable", + "name": "i", + "nameLocation": "136:1:1", + "nodeType": "VariableDeclaration", + "scope": 22, + "src": "131:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 7, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "131:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 10, + "initialValue": + { + "hexValue": "30", + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "140:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "131:10:1" + }, + "loopExpression": + { + "expression": + { + "id": 15, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "151:3:1", + "subExpression": + { + "id": 14, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 8, + "src": "151:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 16, + "nodeType": "ExpressionStatement", + "src": "151:3:1" + }, + "nodeType": "ForStatement", + "src": "126:96:1" + }, + { + "expression": + { + "id": 23, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "320:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 6, + "id": 24, + "nodeType": "Return", + "src": "313:8:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 26, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "66:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": [], + "src": "67:2:1" + }, + "returnParameters": + { + "id": 6, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 5, + "mutability": "mutable", + "name": "x", + "nameLocation": "96:1:1", + "nodeType": "VariableDeclaration", + "scope": 26, + "src": "91:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "91:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "90:8:1" + }, + "scope": 27, + "src": "57:271:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 28, + "src": "0:330:1", + "usedErrors": [] + } + ], + "src": "0:331:1" +} diff --git a/ethers-solc/test-data/ast/documentation_triple.json b/ethers-solc/test-data/ast/documentation_triple.json new file mode 100644 index 00000000..9124e68b --- /dev/null +++ b/ethers-solc/test-data/ast/documentation_triple.json @@ -0,0 +1,386 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 28 + ] + }, + "id": 29, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 28, + "linearizedBaseContracts": + [ + 28 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "documentation": + { + "id": 1, + "nodeType": "StructuredDocumentation", + "src": "17:8:1", + "text": "test" + }, + "id": 3, + "mutability": "mutable", + "name": "a", + "nameLocation": "35:1:1", + "nodeType": "VariableDeclaration", + "scope": 28, + "src": "30:6:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "30:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "body": + { + "id": 26, + "nodeType": "Block", + "src": "84:181:1", + "statements": + [ + { + "body": + { + "id": 22, + "nodeType": "Block", + "src": "142:75:1", + "statements": + [ + { + "documentation": "tee\n s \"t\" 3", + "expression": + { + "id": 20, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "id": 18, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "200:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "*=", + "rightHandSide": + { + "hexValue": "32", + "id": 19, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "205:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "src": "200:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 21, + "nodeType": "ExpressionStatement", + "src": "200:6:1" + } + ] + }, + "condition": + { + "commonType": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "id": 12, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9, + "src": "129:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": + { + "hexValue": "3230", + "id": 13, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "133:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_20_by_1", + "typeString": "int_const 20" + }, + "value": "20" + }, + "src": "129:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "documentation": "test2", + "id": 23, + "initializationExpression": + { + "assignments": + [ + 9 + ], + "declarations": + [ + { + "constant": false, + "id": 9, + "mutability": "mutable", + "name": "i", + "nameLocation": "122:1:1", + "nodeType": "VariableDeclaration", + "scope": 23, + "src": "117:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 8, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "117:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 11, + "initialValue": + { + "hexValue": "30", + "id": 10, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "126:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "117:10:1" + }, + "loopExpression": + { + "expression": + { + "id": 16, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "137:3:1", + "subExpression": + { + "id": 15, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9, + "src": "137:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 17, + "nodeType": "ExpressionStatement", + "src": "137:3:1" + }, + "nodeType": "ForStatement", + "src": "112:105:1" + }, + { + "documentation": "tes \"t4\" ", + "expression": + { + "id": 24, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "257:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 7, + "id": 25, + "nodeType": "Return", + "src": "250:8:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 27, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "51:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "52:2:1" + }, + "returnParameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "x", + "nameLocation": "81:1:1", + "nodeType": "VariableDeclaration", + "scope": 27, + "src": "76:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 5, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "76:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "75:8:1" + }, + "scope": 28, + "src": "42:223:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 29, + "src": "0:267:1", + "usedErrors": [] + } + ], + "src": "0:268:1" +} diff --git a/ethers-solc/test-data/ast/empty_block.json b/ethers-solc/test-data/ast/empty_block.json new file mode 100644 index 00000000..2c23e43c --- /dev/null +++ b/ethers-solc/test-data/ast/empty_block.json @@ -0,0 +1,96 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "42:31:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "61:6:1", + "statements": + [ + { + "nodeType": "YulBlock", + "src": "63:2:1", + "statements": [] + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "52:15:1" + } + ] + }, + "functionSelector": "e2179b8e", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "g", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 6, + "src": "17:56:1", + "stateMutability": "view", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:75:1", + "usedErrors": [] + } + ], + "src": "0:76:1" +} diff --git a/ethers-solc/test-data/ast/enum_value.json b/ethers-solc/test-data/ast/enum_value.json new file mode 100644 index 00000000..2cca0090 --- /dev/null +++ b/ethers-solc/test-data/ast/enum_value.json @@ -0,0 +1,63 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 4 + ] + }, + "id": 5, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "canonicalName": "C.E", + "id": 3, + "members": + [ + { + "id": 1, + "name": "A", + "nameLocation": "22:1:1", + "nodeType": "EnumValue", + "src": "22:1:1" + }, + { + "id": 2, + "name": "B", + "nameLocation": "25:1:1", + "nodeType": "EnumValue", + "src": "25:1:1" + } + ], + "name": "E", + "nameLocation": "18:1:1", + "nodeType": "EnumDefinition", + "src": "13:15:1" + } + ], + "scope": 5, + "src": "0:30:1", + "usedErrors": [] + } + ], + "src": "0:31:1" +} diff --git a/ethers-solc/test-data/ast/enum_value_declaration.json b/ethers-solc/test-data/ast/enum_value_declaration.json new file mode 100644 index 00000000..acdcc736 --- /dev/null +++ b/ethers-solc/test-data/ast/enum_value_declaration.json @@ -0,0 +1,164 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 3 + ], + "f": + [ + 13 + ] + }, + "id": 14, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "A", + "id": 3, + "members": + [ + { + "id": 1, + "name": "X", + "nameLocation": "9:1:1", + "nodeType": "EnumValue", + "src": "9:1:1" + }, + { + "id": 2, + "name": "Y", + "nameLocation": "12:1:1", + "nodeType": "EnumValue", + "src": "12:1:1" + } + ], + "name": "A", + "nameLocation": "5:1:1", + "nodeType": "EnumDefinition", + "src": "0:15:1" + }, + { + "body": + { + "id": 12, + "nodeType": "Block", + "src": "46:15:1", + "statements": + [ + { + "expression": + { + "expression": + { + "id": 9, + "name": "A", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "55:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_enum$_A_$3_$", + "typeString": "type(enum A)" + } + }, + "id": 10, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "57:1:1", + "memberName": "X", + "nodeType": "MemberAccess", + "referencedDeclaration": 1, + "src": "55:3:1", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_A_$3", + "typeString": "enum A" + } + }, + "functionReturnParameters": 8, + "id": 11, + "nodeType": "Return", + "src": "48:10:1" + } + ] + }, + "id": 13, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "f", + "nameLocation": "25:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "26:2:1" + }, + "returnParameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 7, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 13, + "src": "43:1:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_A_$3", + "typeString": "enum A" + }, + "typeName": + { + "id": 6, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 5, + "name": "A", + "nameLocations": + [ + "43:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 3, + "src": "43:1:1" + }, + "referencedDeclaration": 3, + "src": "43:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_A_$3", + "typeString": "enum A" + } + }, + "visibility": "internal" + } + ], + "src": "42:3:1" + }, + "scope": 14, + "src": "16:45:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "src": "0:62:1" +} diff --git a/ethers-solc/test-data/ast/event_definition.json b/ethers-solc/test-data/ast/event_definition.json new file mode 100644 index 00000000..0bb614c2 --- /dev/null +++ b/ethers-solc/test-data/ast/event_definition.json @@ -0,0 +1,54 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 3 + ] + }, + "id": 4, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 3, + "linearizedBaseContracts": + [ + 3 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "anonymous": false, + "eventSelector": "92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028", + "id": 2, + "name": "E", + "nameLocation": "19:1:1", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "20:2:1" + }, + "src": "13:10:1" + } + ], + "scope": 4, + "src": "0:25:1", + "usedErrors": [] + } + ], + "src": "0:26:1" +} diff --git a/ethers-solc/test-data/ast/fallback.json b/ethers-solc/test-data/ast/fallback.json new file mode 100644 index 00000000..25a9b858 --- /dev/null +++ b/ethers-solc/test-data/ast/fallback.json @@ -0,0 +1,73 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "43:5:1", + "statements": [] + }, + "id": 4, + "implemented": true, + "kind": "fallback", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "43:0:1" + }, + "scope": 5, + "src": "15:33:1", + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 6, + "src": "0:50:1", + "usedErrors": [] + } + ], + "src": "0:51:1" +} diff --git a/ethers-solc/test-data/ast/fallback_and_reveice_ether.json b/ethers-solc/test-data/ast/fallback_and_reveice_ether.json new file mode 100644 index 00000000..26b4ada7 --- /dev/null +++ b/ethers-solc/test-data/ast/fallback_and_reveice_ether.json @@ -0,0 +1,108 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 9 + ] + }, + "id": 10, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 9, + "linearizedBaseContracts": + [ + 9 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "42:5:1", + "statements": [] + }, + "id": 4, + "implemented": true, + "kind": "receive", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "22:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 9, + "src": "15:32:1", + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + }, + { + "body": + { + "id": 7, + "nodeType": "Block", + "src": "78:5:1", + "statements": [] + }, + "id": 8, + "implemented": true, + "kind": "fallback", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 5, + "nodeType": "ParameterList", + "parameters": [], + "src": "58:2:1" + }, + "returnParameters": + { + "id": 6, + "nodeType": "ParameterList", + "parameters": [], + "src": "78:0:1" + }, + "scope": 9, + "src": "50:33:1", + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 10, + "src": "0:85:1", + "usedErrors": [] + } + ], + "src": "0:86:1" +} diff --git a/ethers-solc/test-data/ast/fallback_payable.json b/ethers-solc/test-data/ast/fallback_payable.json new file mode 100644 index 00000000..4331b5ed --- /dev/null +++ b/ethers-solc/test-data/ast/fallback_payable.json @@ -0,0 +1,73 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "34:2:1", + "statements": [] + }, + "id": 4, + "implemented": true, + "kind": "fallback", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "22:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "34:0:1" + }, + "scope": 5, + "src": "14:22:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 6, + "src": "0:38:1", + "usedErrors": [] + } + ], + "src": "0:39:1" +} diff --git a/ethers-solc/test-data/ast/function.json b/ethers-solc/test-data/ast/function.json new file mode 100644 index 00000000..04a2ac55 --- /dev/null +++ b/ethers-solc/test-data/ast/function.json @@ -0,0 +1,158 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "42:68:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "61:43:1", + "statements": + [ + { + "body": + { + "nodeType": "YulBlock", + "src": "76:22:1", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "92:2:1", + "type": "", + "value": "20" + } + ], + "functionName": + { + "name": "blockhash", + "nodeType": "YulIdentifier", + "src": "82:9:1" + }, + "nodeType": "YulFunctionCall", + "src": "82:13:1" + } + ], + "functionName": + { + "name": "pop", + "nodeType": "YulIdentifier", + "src": "78:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "78:18:1" + }, + "nodeType": "YulExpressionStatement", + "src": "78:18:1" + } + ] + }, + "name": "g", + "nodeType": "YulFunctionDefinition", + "src": "63:35:1" + }, + { + "expression": + { + "arguments": [], + "functionName": + { + "name": "g", + "nodeType": "YulIdentifier", + "src": "99:1:1" + }, + "nodeType": "YulFunctionCall", + "src": "99:3:1" + }, + "nodeType": "YulExpressionStatement", + "src": "99:3:1" + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "52:52:1" + } + ] + }, + "functionSelector": "b8c9d365", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "h", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 6, + "src": "17:93:1", + "stateMutability": "view", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:112:1", + "usedErrors": [] + } + ], + "src": "0:113:1" +} diff --git a/ethers-solc/test-data/ast/function_type.json b/ethers-solc/test-data/ast/function_type.json new file mode 100644 index 00000000..924f9cdb --- /dev/null +++ b/ethers-solc/test-data/ast/function_type.json @@ -0,0 +1,232 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 17 + ] + }, + "id": 18, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 17, + "linearizedBaseContracts": + [ + 17 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 15, + "nodeType": "Block", + "src": "127:2:1", + "statements": [] + }, + "functionSelector": "d6cd4974", + "id": 16, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "x", + "nameLocation": "67:1:1", + "nodeType": "VariableDeclaration", + "scope": 16, + "src": "24:44:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_payable$__$returns$_t_uint256_$", + "typeString": "function () payable external returns (uint256)" + }, + "typeName": + { + "id": 5, + "nodeType": "FunctionTypeName", + "parameterTypes": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "32:2:1" + }, + "returnParameterTypes": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 5, + "src": "61:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "61:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "60:6:1" + }, + "src": "24:44:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_payable$__$returns$_t_uint256_$", + "typeString": "function () payable external returns (uint256)" + }, + "visibility": "external" + }, + "visibility": "internal" + } + ], + "src": "23:46:1" + }, + "returnParameters": + { + "id": 14, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 13, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 16, + "src": "86:40:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + }, + "typeName": + { + "id": 12, + "nodeType": "FunctionTypeName", + "parameterTypes": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "94:2:1" + }, + "returnParameterTypes": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 10, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 12, + "src": "120:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 9, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "120:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "119:6:1" + }, + "src": "86:40:1", + "stateMutability": "view", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + }, + "visibility": "external" + }, + "visibility": "internal" + } + ], + "src": "85:41:1" + }, + "scope": 17, + "src": "13:116:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 18, + "src": "0:131:1", + "usedErrors": [] + } + ], + "src": "0:132:1" +} diff --git a/ethers-solc/test-data/ast/global_enum.json b/ethers-solc/test-data/ast/global_enum.json new file mode 100644 index 00000000..0b673cff --- /dev/null +++ b/ethers-solc/test-data/ast/global_enum.json @@ -0,0 +1,34 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "E": + [ + 2 + ] + }, + "id": 3, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "E", + "id": 2, + "members": + [ + { + "id": 1, + "name": "A", + "nameLocation": "9:1:1", + "nodeType": "EnumValue", + "src": "9:1:1" + } + ], + "name": "E", + "nameLocation": "5:1:1", + "nodeType": "EnumDefinition", + "src": "0:12:1" + } + ], + "src": "0:13:1" +} diff --git a/ethers-solc/test-data/ast/global_struct.json b/ethers-solc/test-data/ast/global_struct.json new file mode 100644 index 00000000..2c14a5e4 --- /dev/null +++ b/ethers-solc/test-data/ast/global_struct.json @@ -0,0 +1,59 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "S": + [ + 3 + ] + }, + "id": 4, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "S", + "id": 3, + "members": + [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "a", + "nameLocation": "19:1:1", + "nodeType": "VariableDeclaration", + "scope": 3, + "src": "11:9:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "name": "S", + "nameLocation": "7:1:1", + "nodeType": "StructDefinition", + "scope": 4, + "src": "0:23:1", + "visibility": "public" + } + ], + "src": "0:24:1" +} diff --git a/ethers-solc/test-data/ast/inheritance_specifier.json b/ethers-solc/test-data/ast/inheritance_specifier.json new file mode 100644 index 00000000..8959d5b5 --- /dev/null +++ b/ethers-solc/test-data/ast/inheritance_specifier.json @@ -0,0 +1,80 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C1": + [ + 1 + ], + "C2": + [ + 4 + ] + }, + "id": 5, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C1", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C1", + "nameLocation": "9:2:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 5, + "src": "0:14:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 2, + "name": "C1", + "nameLocations": + [ + "30:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1, + "src": "30:2:1" + }, + "id": 3, + "nodeType": "InheritanceSpecifier", + "src": "30:2:1" + } + ], + "canonicalName": "C2", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4, + 1 + ], + "name": "C2", + "nameLocation": "24:2:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 5, + "src": "15:20:1", + "usedErrors": [] + } + ], + "src": "0:36:1" +} diff --git a/ethers-solc/test-data/ast/leave.json b/ethers-solc/test-data/ast/leave.json new file mode 100644 index 00000000..7be1136f --- /dev/null +++ b/ethers-solc/test-data/ast/leave.json @@ -0,0 +1,108 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "37:51:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "56:26:1", + "statements": + [ + { + "body": + { + "nodeType": "YulBlock", + "src": "71:9:1", + "statements": + [ + { + "nodeType": "YulLeave", + "src": "73:5:1" + } + ] + }, + "name": "f", + "nodeType": "YulFunctionDefinition", + "src": "58:22:1" + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "47:35:1" + } + ] + }, + "functionSelector": "ece866b9", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "l", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "37:0:1" + }, + "scope": 6, + "src": "17:71:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:90:1", + "usedErrors": [] + } + ], + "src": "0:91:1" +} diff --git a/ethers-solc/test-data/ast/license.json b/ethers-solc/test-data/ast/license.json new file mode 100644 index 00000000..9f996e05 --- /dev/null +++ b/ethers-solc/test-data/ast/license.json @@ -0,0 +1,37 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 1 + ] + }, + "id": 2, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C", + "nameLocation": "45:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 2, + "src": "36:13:1", + "usedErrors": [] + } + ], + "src": "36:14:1" +} diff --git a/ethers-solc/test-data/ast/long_type_name_binary_operation.json b/ethers-solc/test-data/ast/long_type_name_binary_operation.json new file mode 100644 index 00000000..8340eaf4 --- /dev/null +++ b/ethers-solc/test-data/ast/long_type_name_binary_operation.json @@ -0,0 +1,175 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 11 + ] + }, + "id": 12, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "c", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": + [ + 11 + ], + "name": "c", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 9, + "nodeType": "Block", + "src": "33:19:1", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "mutability": "mutable", + "name": "a", + "nameLocation": "40:1:1", + "nodeType": "VariableDeclaration", + "scope": 9, + "src": "35:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "35:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 8, + "initialValue": + { + "commonType": + { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + }, + "id": 7, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "hexValue": "32", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "44:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "hexValue": "33", + "id": 6, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "48:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "src": "44:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35:14:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 11, + "src": "13:39:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 12, + "src": "0:54:1", + "usedErrors": [] + } + ], + "src": "0:55:1" +} diff --git a/ethers-solc/test-data/ast/long_type_name_identifier.json b/ethers-solc/test-data/ast/long_type_name_identifier.json new file mode 100644 index 00000000..c810283d --- /dev/null +++ b/ethers-solc/test-data/ast/long_type_name_identifier.json @@ -0,0 +1,184 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 15 + ] + }, + "id": 16, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "c", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 15, + "linearizedBaseContracts": + [ + 15 + ], + "name": "c", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "a", + "nameLocation": "20:1:1", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "13:8:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "13:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2, + "nodeType": "ArrayTypeName", + "src": "13:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "visibility": "internal" + }, + { + "body": + { + "id": 13, + "nodeType": "Block", + "src": "43:25:1", + "statements": + [ + { + "assignments": + [ + 10 + ], + "declarations": + [ + { + "constant": false, + "id": 10, + "mutability": "mutable", + "name": "b", + "nameLocation": "60:1:1", + "nodeType": "VariableDeclaration", + "scope": 13, + "src": "45:16:1", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 8, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "45:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9, + "nodeType": "ArrayTypeName", + "src": "45:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "visibility": "internal" + } + ], + "id": 12, + "initialValue": + { + "id": 11, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "64:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage", + "typeString": "uint256[] storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "45:20:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 14, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "32:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:2:1" + }, + "returnParameters": + { + "id": 5, + "nodeType": "ParameterList", + "parameters": [], + "src": "43:0:1" + }, + "scope": 15, + "src": "23:45:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 16, + "src": "0:70:1", + "usedErrors": [] + } + ], + "src": "0:71:1" +} diff --git a/ethers-solc/test-data/ast/loop.json b/ethers-solc/test-data/ast/loop.json new file mode 100644 index 00000000..2b634e4c --- /dev/null +++ b/ethers-solc/test-data/ast/loop.json @@ -0,0 +1,171 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "42:74:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "61:49:1", + "statements": + [ + { + "body": + { + "nodeType": "YulBlock", + "src": "90:18:1", + "statements": + [ + { + "nodeType": "YulBreak", + "src": "92:5:1" + }, + { + "nodeType": "YulContinue", + "src": "98:8:1" + } + ] + }, + "condition": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "70:1:1", + "type": "", + "value": "1" + }, + "nodeType": "YulForLoop", + "post": + { + "nodeType": "YulBlock", + "src": "72:17:1", + "statements": + [ + { + "expression": + { + "arguments": + [ + { + "arguments": + [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "84:1:1", + "type": "", + "value": "0" + } + ], + "functionName": + { + "name": "sload", + "nodeType": "YulIdentifier", + "src": "78:5:1" + }, + "nodeType": "YulFunctionCall", + "src": "78:8:1" + } + ], + "functionName": + { + "name": "pop", + "nodeType": "YulIdentifier", + "src": "74:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "74:13:1" + }, + "nodeType": "YulExpressionStatement", + "src": "74:13:1" + } + ] + }, + "pre": + { + "nodeType": "YulBlock", + "src": "67:2:1", + "statements": [] + }, + "src": "63:45:1" + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "52:58:1" + } + ] + }, + "functionSelector": "e2179b8e", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "g", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 6, + "src": "17:99:1", + "stateMutability": "view", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:118:1", + "usedErrors": [] + } + ], + "src": "0:119:1" +} diff --git a/ethers-solc/test-data/ast/mappings.json b/ethers-solc/test-data/ast/mappings.json new file mode 100644 index 00000000..e414b56f --- /dev/null +++ b/ethers-solc/test-data/ast/mappings.json @@ -0,0 +1,253 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 19 + ] + }, + "id": 20, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 19, + "linearizedBaseContracts": + [ + 19 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "canonicalName": "C.E", + "id": 4, + "members": + [ + { + "id": 1, + "name": "A", + "nameLocation": "26:1:1", + "nodeType": "EnumValue", + "src": "26:1:1" + }, + { + "id": 2, + "name": "B", + "nameLocation": "29:1:1", + "nodeType": "EnumValue", + "src": "29:1:1" + }, + { + "id": 3, + "name": "C", + "nameLocation": "32:1:1", + "nodeType": "EnumValue", + "src": "32:1:1" + } + ], + "name": "E", + "nameLocation": "22:1:1", + "nodeType": "EnumDefinition", + "src": "17:18:1" + }, + { + "constant": false, + "id": 9, + "mutability": "mutable", + "name": "a", + "nameLocation": "59:1:1", + "nodeType": "VariableDeclaration", + "scope": 19, + "src": "40:20:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_contract$_C_$19_$_t_bool_$", + "typeString": "mapping(contract C => bool)" + }, + "typeName": + { + "id": 8, + "keyType": + { + "id": 6, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 5, + "name": "C", + "nameLocations": + [ + "48:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 19, + "src": "48:1:1" + }, + "referencedDeclaration": 19, + "src": "48:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C_$19", + "typeString": "contract C" + } + }, + "nodeType": "Mapping", + "src": "40:18:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_contract$_C_$19_$_t_bool_$", + "typeString": "mapping(contract C => bool)" + }, + "valueType": + { + "id": 7, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "53:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 13, + "mutability": "mutable", + "name": "b", + "nameLocation": "91:1:1", + "nodeType": "VariableDeclaration", + "scope": 19, + "src": "66:26:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + }, + "typeName": + { + "id": 12, + "keyType": + { + "id": 10, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "74:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "66:24:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_bool_$", + "typeString": "mapping(address => bool)" + }, + "valueType": + { + "id": 11, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "85:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 18, + "mutability": "mutable", + "name": "c", + "nameLocation": "117:1:1", + "nodeType": "VariableDeclaration", + "scope": 19, + "src": "98:20:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$", + "typeString": "mapping(enum C.E => bool)" + }, + "typeName": + { + "id": 17, + "keyType": + { + "id": 15, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 14, + "name": "E", + "nameLocations": + [ + "106:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 4, + "src": "106:1:1" + }, + "referencedDeclaration": 4, + "src": "106:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_enum$_E_$4", + "typeString": "enum C.E" + } + }, + "nodeType": "Mapping", + "src": "98:18:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$", + "typeString": "mapping(enum C.E => bool)" + }, + "valueType": + { + "id": 16, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "111:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + } + }, + "visibility": "internal" + } + ], + "scope": 20, + "src": "0:121:1", + "usedErrors": [] + } + ], + "src": "0:122:1" +} diff --git a/ethers-solc/test-data/ast/modifier_definition.json b/ethers-solc/test-data/ast/modifier_definition.json new file mode 100644 index 00000000..aa448568 --- /dev/null +++ b/ethers-solc/test-data/ast/modifier_definition.json @@ -0,0 +1,176 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 14 + ] + }, + "id": 15, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 14, + "linearizedBaseContracts": + [ + 14 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 5, + "nodeType": "Block", + "src": "32:6:1", + "statements": + [ + { + "id": 4, + "nodeType": "PlaceholderStatement", + "src": "34:1:1" + } + ] + }, + "id": 6, + "name": "M", + "nameLocation": "22:1:1", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "i", + "nameLocation": "29:1:1", + "nodeType": "VariableDeclaration", + "scope": 6, + "src": "24:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "24:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "23:8:1" + }, + "src": "13:25:1", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 12, + "nodeType": "Block", + "src": "64:2:1", + "statements": [] + }, + "functionSelector": "28811f59", + "id": 13, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "arguments": + [ + { + "hexValue": "31", + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "54:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "id": 10, + "kind": "modifierInvocation", + "modifierName": + { + "id": 8, + "name": "M", + "nameLocations": + [ + "52:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 6, + "src": "52:1:1" + }, + "nodeType": "ModifierInvocation", + "src": "52:4:1" + } + ], + "name": "F", + "nameLocation": "48:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "49:2:1" + }, + "returnParameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "64:0:1" + }, + "scope": 14, + "src": "39:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 15, + "src": "0:68:1", + "usedErrors": [] + } + ], + "src": "0:69:1" +} diff --git a/ethers-solc/test-data/ast/modifier_invocation.json b/ethers-solc/test-data/ast/modifier_invocation.json new file mode 100644 index 00000000..aa448568 --- /dev/null +++ b/ethers-solc/test-data/ast/modifier_invocation.json @@ -0,0 +1,176 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 14 + ] + }, + "id": 15, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 14, + "linearizedBaseContracts": + [ + 14 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 5, + "nodeType": "Block", + "src": "32:6:1", + "statements": + [ + { + "id": 4, + "nodeType": "PlaceholderStatement", + "src": "34:1:1" + } + ] + }, + "id": 6, + "name": "M", + "nameLocation": "22:1:1", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "i", + "nameLocation": "29:1:1", + "nodeType": "VariableDeclaration", + "scope": 6, + "src": "24:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "24:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "23:8:1" + }, + "src": "13:25:1", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 12, + "nodeType": "Block", + "src": "64:2:1", + "statements": [] + }, + "functionSelector": "28811f59", + "id": 13, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "arguments": + [ + { + "hexValue": "31", + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "54:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "id": 10, + "kind": "modifierInvocation", + "modifierName": + { + "id": 8, + "name": "M", + "nameLocations": + [ + "52:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 6, + "src": "52:1:1" + }, + "nodeType": "ModifierInvocation", + "src": "52:4:1" + } + ], + "name": "F", + "nameLocation": "48:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "49:2:1" + }, + "returnParameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "64:0:1" + }, + "scope": 14, + "src": "39:27:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 15, + "src": "0:68:1", + "usedErrors": [] + } + ], + "src": "0:69:1" +} diff --git a/ethers-solc/test-data/ast/mutability.json b/ethers-solc/test-data/ast/mutability.json new file mode 100644 index 00000000..90bbf05d --- /dev/null +++ b/ethers-solc/test-data/ast/mutability.json @@ -0,0 +1,185 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 10 + ] + }, + "id": 11, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 10, + "linearizedBaseContracts": + [ + 10 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "functionSelector": "0dbe671f", + "id": 3, + "mutability": "immutable", + "name": "a", + "nameLocation": "39:1:1", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "17:27:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "17:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "hexValue": "34", + "id": 2, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "43:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "visibility": "public" + }, + { + "constant": true, + "functionSelector": "4df7e3d0", + "id": 6, + "mutability": "constant", + "name": "b", + "nameLocation": "71:1:1", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "50:26:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "50:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "hexValue": "32", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "75:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "visibility": "public" + }, + { + "constant": false, + "functionSelector": "c3da42b8", + "id": 9, + "mutability": "mutable", + "name": "c", + "nameLocation": "94:1:1", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "82:17:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 7, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "82:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": + { + "hexValue": "33", + "id": 8, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "98:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "visibility": "public" + } + ], + "scope": 11, + "src": "0:102:1", + "usedErrors": [] + } + ], + "src": "0:103:1" +} diff --git a/ethers-solc/test-data/ast/nested_functions.json b/ethers-solc/test-data/ast/nested_functions.json new file mode 100644 index 00000000..2ba3bd03 --- /dev/null +++ b/ethers-solc/test-data/ast/nested_functions.json @@ -0,0 +1,176 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 8 + ] + }, + "id": 9, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 8, + "linearizedBaseContracts": + [ + 8 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 6, + "nodeType": "Block", + "src": "57:95:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "72:76:1", + "statements": + [ + { + "body": + { + "nodeType": "YulBlock", + "src": "94:35:1", + "statements": + [ + { + "body": + { + "nodeType": "YulBlock", + "src": "118:3:1", + "statements": [] + }, + "name": "f2", + "nodeType": "YulFunctionDefinition", + "src": "104:17:1" + } + ] + }, + "name": "f1", + "nodeType": "YulFunctionDefinition", + "src": "80:49:1" + }, + { + "nodeType": "YulAssignment", + "src": "136:6:1", + "value": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "141:1:1", + "type": "", + "value": "2" + }, + "variableNames": + [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "136:1:1" + } + ] + } + ] + }, + "evmVersion": "london", + "externalReferences": + [ + { + "declaration": 3, + "isOffset": false, + "isSlot": false, + "src": "136:1:1", + "valueSize": 1 + } + ], + "id": 5, + "nodeType": "InlineAssembly", + "src": "63:85:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 7, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "24:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "25:2:1" + }, + "returnParameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "x", + "nameLocation": "54:1:1", + "nodeType": "VariableDeclaration", + "scope": 7, + "src": "49:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "49:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "48:8:1" + }, + "scope": 8, + "src": "15:137:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 9, + "src": "0:154:1", + "usedErrors": [] + } + ], + "src": "0:155:1" +} diff --git a/ethers-solc/test-data/ast/non_utf8.json b/ethers-solc/test-data/ast/non_utf8.json new file mode 100644 index 00000000..926f858b --- /dev/null +++ b/ethers-solc/test-data/ast/non_utf8.json @@ -0,0 +1,237 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 15 + ] + }, + "id": 16, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 15, + "linearizedBaseContracts": + [ + 15 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 13, + "nodeType": "Block", + "src": "33:45:1", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "mutability": "mutable", + "name": "x", + "nameLocation": "49:1:1", + "nodeType": "VariableDeclaration", + "scope": 13, + "src": "35:15:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": + { + "id": 3, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "35:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "id": 12, + "initialValue": + { + "arguments": + [ + { + "arguments": + [ + { + "hexValue": "ff", + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "hexString", + "lValueRequested": false, + "nodeType": "Literal", + "src": "66:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9", + "typeString": "literal_string hex\"ff\"" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9", + "typeString": "literal_string hex\"ff\"" + } + ], + "id": 8, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "60:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_bytes_storage_ptr_$", + "typeString": "type(bytes storage pointer)" + }, + "typeName": + { + "id": 7, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "60:5:1", + "typeDescriptions": {} + } + }, + "id": 10, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "60:14:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 6, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "53:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_string_storage_ptr_$", + "typeString": "type(string storage pointer)" + }, + "typeName": + { + "id": 5, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "53:6:1", + "typeDescriptions": {} + } + }, + "id": 11, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "53:22:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35:40:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 14, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 15, + "src": "13:65:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 16, + "src": "0:80:1", + "usedErrors": [] + } + ], + "src": "0:81:1" +} diff --git a/ethers-solc/test-data/ast/override.json b/ethers-solc/test-data/ast/override.json new file mode 100644 index 00000000..a7c43767 --- /dev/null +++ b/ethers-solc/test-data/ast/override.json @@ -0,0 +1,337 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 5 + ], + "B": + [ + 16 + ], + "C": + [ + 29 + ] + }, + "id": 30, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "A", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "A", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "44:2:1", + "statements": [] + }, + "functionSelector": "a399b6a2", + "id": 4, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "faa", + "nameLocation": "23:3:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "26:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "44:0:1" + }, + "scope": 5, + "src": "14:32:1", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + } + ], + "scope": 30, + "src": "0:48:1", + "usedErrors": [] + }, + { + "abstract": true, + "baseContracts": + [ + { + "baseName": + { + "id": 6, + "name": "A", + "nameLocations": + [ + "72:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 5, + "src": "72:1:1" + }, + "id": 7, + "nodeType": "InheritanceSpecifier", + "src": "72:1:1" + } + ], + "canonicalName": "B", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": false, + "id": 16, + "linearizedBaseContracts": + [ + 16, + 5 + ], + "name": "B", + "nameLocation": "67:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "functionSelector": "c2985578", + "id": 10, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "foo", + "nameLocation": "86:3:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "89:2:1" + }, + "returnParameters": + { + "id": 9, + "nodeType": "ParameterList", + "parameters": [], + "src": "106:0:1" + }, + "scope": 16, + "src": "77:30:1", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + }, + { + "baseFunctions": + [ + 4 + ], + "body": + { + "id": 14, + "nodeType": "Block", + "src": "148:2:1", + "statements": [] + }, + "functionSelector": "a399b6a2", + "id": 15, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "faa", + "nameLocation": "118:3:1", + "nodeType": "FunctionDefinition", + "overrides": + { + "id": 12, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "139:8:1" + }, + "parameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "121:2:1" + }, + "returnParameters": + { + "id": 13, + "nodeType": "ParameterList", + "parameters": [], + "src": "148:0:1" + }, + "scope": 16, + "src": "109:41:1", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + } + ], + "scope": 30, + "src": "49:103:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 17, + "name": "B", + "nameLocations": + [ + "167:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 16, + "src": "167:1:1" + }, + "id": 18, + "nodeType": "InheritanceSpecifier", + "src": "167:1:1" + } + ], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 29, + "linearizedBaseContracts": + [ + 29, + 16, + 5 + ], + "name": "C", + "nameLocation": "162:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "baseFunctions": + [ + 10 + ], + "body": + { + "id": 22, + "nodeType": "Block", + "src": "203:3:1", + "statements": [] + }, + "functionSelector": "c2985578", + "id": 23, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "foo", + "nameLocation": "181:3:1", + "nodeType": "FunctionDefinition", + "overrides": + { + "id": 20, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "194:8:1" + }, + "parameters": + { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "184:2:1" + }, + "returnParameters": + { + "id": 21, + "nodeType": "ParameterList", + "parameters": [], + "src": "203:0:1" + }, + "scope": 29, + "src": "172:34:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "baseFunctions": + [ + 15 + ], + "body": + { + "id": 27, + "nodeType": "Block", + "src": "239:3:1", + "statements": [] + }, + "functionSelector": "a399b6a2", + "id": 28, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "faa", + "nameLocation": "217:3:1", + "nodeType": "FunctionDefinition", + "overrides": + { + "id": 25, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "230:8:1" + }, + "parameters": + { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "220:2:1" + }, + "returnParameters": + { + "id": 26, + "nodeType": "ParameterList", + "parameters": [], + "src": "239:0:1" + }, + "scope": 29, + "src": "208:34:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 30, + "src": "153:91:1", + "usedErrors": [] + } + ], + "src": "0:245:1" +} diff --git a/ethers-solc/test-data/ast/placeholder_statement.json b/ethers-solc/test-data/ast/placeholder_statement.json new file mode 100644 index 00000000..5a6d51b2 --- /dev/null +++ b/ethers-solc/test-data/ast/placeholder_statement.json @@ -0,0 +1,68 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "24:6:1", + "statements": + [ + { + "id": 2, + "nodeType": "PlaceholderStatement", + "src": "26:1:1" + } + ] + }, + "id": 4, + "name": "M", + "nameLocation": "22:1:1", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "24:0:1" + }, + "src": "13:17:1", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 6, + "src": "0:32:1", + "usedErrors": [] + } + ], + "src": "0:33:1" +} diff --git a/ethers-solc/test-data/ast/receive_ether.json b/ethers-solc/test-data/ast/receive_ether.json new file mode 100644 index 00000000..bfcb33f6 --- /dev/null +++ b/ethers-solc/test-data/ast/receive_ether.json @@ -0,0 +1,73 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "42:5:1", + "statements": [] + }, + "id": 4, + "implemented": true, + "kind": "receive", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "22:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 5, + "src": "15:32:1", + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 6, + "src": "0:49:1", + "usedErrors": [] + } + ], + "src": "0:50:1" +} diff --git a/ethers-solc/test-data/ast/short_type_name.json b/ethers-solc/test-data/ast/short_type_name.json new file mode 100644 index 00000000..b7409fbb --- /dev/null +++ b/ethers-solc/test-data/ast/short_type_name.json @@ -0,0 +1,129 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 11 + ] + }, + "id": 12, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "c", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": + [ + 11 + ], + "name": "c", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 9, + "nodeType": "Block", + "src": "33:20:1", + "statements": + [ + { + "assignments": + [ + 7 + ], + "declarations": + [ + { + "constant": false, + "id": 7, + "mutability": "mutable", + "name": "x", + "nameLocation": "49:1:1", + "nodeType": "VariableDeclaration", + "scope": 9, + "src": "35:15:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 5, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "35:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 6, + "nodeType": "ArrayTypeName", + "src": "35:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "visibility": "internal" + } + ], + "id": 8, + "nodeType": "VariableDeclarationStatement", + "src": "35:15:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 11, + "src": "13:40:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 12, + "src": "0:55:1", + "usedErrors": [] + } + ], + "src": "0:56:1" +} diff --git a/ethers-solc/test-data/ast/short_type_name_ref.json b/ethers-solc/test-data/ast/short_type_name_ref.json new file mode 100644 index 00000000..6a0f249f --- /dev/null +++ b/ethers-solc/test-data/ast/short_type_name_ref.json @@ -0,0 +1,140 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 12 + ] + }, + "id": 13, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "c", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 12, + "linearizedBaseContracts": + [ + 12 + ], + "name": "c", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 10, + "nodeType": "Block", + "src": "33:25:1", + "statements": + [ + { + "assignments": + [ + 8 + ], + "declarations": + [ + { + "constant": false, + "id": 8, + "mutability": "mutable", + "name": "rows", + "nameLocation": "51:4:1", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "35:20:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr", + "typeString": "uint256[][]" + }, + "typeName": + { + "baseType": + { + "baseType": + { + "id": 5, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "35:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 6, + "nodeType": "ArrayTypeName", + "src": "35:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "id": 7, + "nodeType": "ArrayTypeName", + "src": "35:8:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_storage_$dyn_storage_ptr", + "typeString": "uint256[][]" + } + }, + "visibility": "internal" + } + ], + "id": 9, + "nodeType": "VariableDeclarationStatement", + "src": "35:20:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 11, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 12, + "src": "13:45:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 13, + "src": "0:60:1", + "usedErrors": [] + } + ], + "src": "0:61:1" +} diff --git a/ethers-solc/test-data/ast/slot_offset.json b/ethers-solc/test-data/ast/slot_offset.json new file mode 100644 index 00000000..a77d3e5d --- /dev/null +++ b/ethers-solc/test-data/ast/slot_offset.json @@ -0,0 +1,252 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 12 + ] + }, + "id": 13, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 12, + "linearizedBaseContracts": + [ + 12 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "canonicalName": "C.S", + "id": 3, + "members": + [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "x", + "nameLocation": "33:1:1", + "nodeType": "VariableDeclaration", + "scope": 3, + "src": "28:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "28:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "name": "S", + "nameLocation": "24:1:1", + "nodeType": "StructDefinition", + "scope": 12, + "src": "17:20:1", + "visibility": "public" + }, + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "s", + "nameLocation": "44:1:1", + "nodeType": "VariableDeclaration", + "scope": 12, + "src": "42:3:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_S_$3_storage", + "typeString": "struct C.S" + }, + "typeName": + { + "id": 5, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 4, + "name": "S", + "nameLocations": + [ + "42:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 3, + "src": "42:1:1" + }, + "referencedDeclaration": 3, + "src": "42:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_struct$_S_$3_storage_ptr", + "typeString": "struct C.S" + } + }, + "visibility": "internal" + }, + { + "body": + { + "id": 10, + "nodeType": "Block", + "src": "76:70:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "95:45:1", + "statements": + [ + { + "nodeType": "YulVariableDeclaration", + "src": "97:17:1", + "value": + { + "name": "s.offset", + "nodeType": "YulIdentifier", + "src": "106:8:1" + }, + "variables": + [ + { + "name": "x", + "nodeType": "YulTypedName", + "src": "101:1:1", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "115:23:1", + "value": + { + "arguments": + [ + { + "name": "s.slot", + "nodeType": "YulIdentifier", + "src": "128:6:1" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "136:1:1", + "type": "", + "value": "2" + } + ], + "functionName": + { + "name": "mul", + "nodeType": "YulIdentifier", + "src": "124:3:1" + }, + "nodeType": "YulFunctionCall", + "src": "124:14:1" + }, + "variables": + [ + { + "name": "y", + "nodeType": "YulTypedName", + "src": "119:1:1", + "type": "" + } + ] + } + ] + }, + "evmVersion": "london", + "externalReferences": + [ + { + "declaration": 6, + "isOffset": true, + "isSlot": false, + "src": "106:8:1", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 6, + "isOffset": false, + "isSlot": true, + "src": "128:6:1", + "suffix": "slot", + "valueSize": 1 + } + ], + "id": 9, + "nodeType": "InlineAssembly", + "src": "86:54:1" + } + ] + }, + "functionSelector": "ffae15ba", + "id": 11, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "e", + "nameLocation": "60:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "61:2:1" + }, + "returnParameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "76:0:1" + }, + "scope": 12, + "src": "51:95:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 13, + "src": "0:148:1", + "usedErrors": [] + } + ], + "src": "0:149:1" +} diff --git a/ethers-solc/test-data/ast/smoke.json b/ethers-solc/test-data/ast/smoke.json new file mode 100644 index 00000000..4d4a02e2 --- /dev/null +++ b/ethers-solc/test-data/ast/smoke.json @@ -0,0 +1,36 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 1 + ] + }, + "id": 2, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 2, + "src": "0:13:1", + "usedErrors": [] + } + ], + "src": "0:14:1" +} diff --git a/ethers-solc/test-data/ast/source_location.json b/ethers-solc/test-data/ast/source_location.json new file mode 100644 index 00000000..df51e49c --- /dev/null +++ b/ethers-solc/test-data/ast/source_location.json @@ -0,0 +1,172 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 12 + ] + }, + "id": 13, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 12, + "linearizedBaseContracts": + [ + 12 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 10, + "nodeType": "Block", + "src": "33:20:1", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "mutability": "mutable", + "name": "x", + "nameLocation": "40:1:1", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "35:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "35:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 6, + "initialValue": + { + "hexValue": "32", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "44:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "VariableDeclarationStatement", + "src": "35:10:1" + }, + { + "expression": + { + "id": 8, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "47:3:1", + "subExpression": + { + "id": 7, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "47:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9, + "nodeType": "ExpressionStatement", + "src": "47:3:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 11, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 12, + "src": "13:40:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 13, + "src": "0:55:1", + "usedErrors": [] + } + ], + "src": "0:56:1" +} diff --git a/ethers-solc/test-data/ast/string.json b/ethers-solc/test-data/ast/string.json new file mode 100644 index 00000000..438f760c --- /dev/null +++ b/ethers-solc/test-data/ast/string.json @@ -0,0 +1,136 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 9 + ] + }, + "id": 10, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 9, + "linearizedBaseContracts": + [ + 9 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 7, + "nodeType": "Block", + "src": "33:36:1", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "mutability": "mutable", + "name": "x", + "nameLocation": "49:1:1", + "nodeType": "VariableDeclaration", + "scope": 7, + "src": "35:15:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": + { + "id": 3, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "35:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "id": 6, + "initialValue": + { + "hexValue": "48656c6c6f20576f726c64", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "53:13:1", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_592fa743889fc7f92ac2a37bb1f5ba1daf2a5c84741ca0e0061d243a2e6707ba", + "typeString": "literal_string \"Hello World\"" + }, + "value": "Hello World" + }, + "nodeType": "VariableDeclarationStatement", + "src": "35:31:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 8, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 9, + "src": "13:56:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 10, + "src": "0:71:1", + "usedErrors": [] + } + ], + "src": "0:72:1" +} diff --git a/ethers-solc/test-data/ast/stringlit.json b/ethers-solc/test-data/ast/stringlit.json new file mode 100644 index 00000000..6edf9146 --- /dev/null +++ b/ethers-solc/test-data/ast/stringlit.json @@ -0,0 +1,113 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "37:43:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "56:18:1", + "statements": + [ + { + "nodeType": "YulVariableDeclaration", + "src": "58:14:1", + "value": + { + "hexValue": "616263", + "kind": "string", + "nodeType": "YulLiteral", + "src": "67:5:1", + "type": "", + "value": "abc" + }, + "variables": + [ + { + "name": "x", + "nodeType": "YulTypedName", + "src": "62:1:1", + "type": "" + } + ] + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "47:27:1" + } + ] + }, + "functionSelector": "5a2ee019", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "m", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "37:0:1" + }, + "scope": 6, + "src": "17:63:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:82:1", + "usedErrors": [] + } + ], + "src": "0:83:1" +} diff --git a/ethers-solc/test-data/ast/switch.json b/ethers-solc/test-data/ast/switch.json new file mode 100644 index 00000000..c4116b64 --- /dev/null +++ b/ethers-solc/test-data/ast/switch.json @@ -0,0 +1,204 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "42:154:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "61:129:1", + "statements": + [ + { + "nodeType": "YulVariableDeclaration", + "src": "75:10:1", + "value": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "84:1:1", + "type": "", + "value": "0" + }, + "variables": + [ + { + "name": "v", + "nodeType": "YulTypedName", + "src": "79:1:1", + "type": "" + } + ] + }, + { + "cases": + [ + { + "body": + { + "nodeType": "YulBlock", + "src": "139:10:1", + "statements": + [ + { + "nodeType": "YulAssignment", + "src": "141:6:1", + "value": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "146:1:1", + "type": "", + "value": "1" + }, + "variableNames": + [ + { + "name": "v", + "nodeType": "YulIdentifier", + "src": "141:1:1" + } + ] + } + ] + }, + "nodeType": "YulCase", + "src": "132:17:1", + "value": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "137:1:1", + "type": "", + "value": "0" + } + }, + { + "body": + { + "nodeType": "YulBlock", + "src": "170:10:1", + "statements": + [ + { + "nodeType": "YulAssignment", + "src": "172:6:1", + "value": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "177:1:1", + "type": "", + "value": "2" + }, + "variableNames": + [ + { + "name": "v", + "nodeType": "YulIdentifier", + "src": "172:1:1" + } + ] + } + ] + }, + "nodeType": "YulCase", + "src": "162:18:1", + "value": "default" + } + ], + "expression": + { + "arguments": [], + "functionName": + { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "105:12:1" + }, + "nodeType": "YulFunctionCall", + "src": "105:14:1" + }, + "nodeType": "YulSwitch", + "src": "98:82:1" + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "52:138:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 6, + "src": "17:179:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:198:1", + "usedErrors": [] + } + ], + "src": "0:199:1" +} diff --git a/ethers-solc/test-data/ast/switch_default.json b/ethers-solc/test-data/ast/switch_default.json new file mode 100644 index 00000000..476f20b2 --- /dev/null +++ b/ethers-solc/test-data/ast/switch_default.json @@ -0,0 +1,135 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "42:58:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "61:33:1", + "statements": + [ + { + "cases": + [ + { + "body": + { + "nodeType": "YulBlock", + "src": "79:2:1", + "statements": [] + }, + "nodeType": "YulCase", + "src": "72:9:1", + "value": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "77:1:1", + "type": "", + "value": "0" + } + }, + { + "body": + { + "nodeType": "YulBlock", + "src": "90:2:1", + "statements": [] + }, + "nodeType": "YulCase", + "src": "82:10:1", + "value": "default" + } + ], + "expression": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "70:1:1", + "type": "", + "value": "0" + }, + "nodeType": "YulSwitch", + "src": "63:29:1" + } + ] + }, + "evmVersion": "london", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "52:42:1" + } + ] + }, + "functionSelector": "e2179b8e", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "g", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 6, + "src": "17:83:1", + "stateMutability": "view", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:102:1", + "usedErrors": [] + } + ], + "src": "0:103:1" +} diff --git a/ethers-solc/test-data/ast/two_base_functions.json b/ethers-solc/test-data/ast/two_base_functions.json new file mode 100644 index 00000000..23bdf6ef --- /dev/null +++ b/ethers-solc/test-data/ast/two_base_functions.json @@ -0,0 +1,272 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 5 + ], + "B": + [ + 10 + ], + "C": + [ + 22 + ] + }, + "id": 23, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "A", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "A", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "45:2:1", + "statements": [] + }, + "functionSelector": "26121ff0", + "id": 4, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "45:0:1" + }, + "scope": 5, + "src": "17:30:1", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + } + ], + "scope": 23, + "src": "0:49:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "B", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 10, + "linearizedBaseContracts": + [ + 10 + ], + "name": "B", + "nameLocation": "59:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 8, + "nodeType": "Block", + "src": "95:2:1", + "statements": [] + }, + "functionSelector": "26121ff0", + "id": 9, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "76:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 6, + "nodeType": "ParameterList", + "parameters": [], + "src": "77:2:1" + }, + "returnParameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "95:0:1" + }, + "scope": 10, + "src": "67:30:1", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + } + ], + "scope": 23, + "src": "50:49:1", + "usedErrors": [] + }, + { + "abstract": false, + "baseContracts": + [ + { + "baseName": + { + "id": 11, + "name": "A", + "nameLocations": + [ + "114:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 5, + "src": "114:1:1" + }, + "id": 12, + "nodeType": "InheritanceSpecifier", + "src": "114:1:1" + }, + { + "baseName": + { + "id": 13, + "name": "B", + "nameLocations": + [ + "117:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 10, + "src": "117:1:1" + }, + "id": 14, + "nodeType": "InheritanceSpecifier", + "src": "117:1:1" + } + ], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 22, + "linearizedBaseContracts": + [ + 22, + 10, + 5 + ], + "name": "C", + "nameLocation": "109:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "baseFunctions": + [ + 4, + 9 + ], + "body": + { + "id": 20, + "nodeType": "Block", + "src": "160:2:1", + "statements": [] + }, + "functionSelector": "26121ff0", + "id": 21, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "134:1:1", + "nodeType": "FunctionDefinition", + "overrides": + { + "id": 18, + "nodeType": "OverrideSpecifier", + "overrides": + [ + { + "id": 16, + "name": "A", + "nameLocations": + [ + "154:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 5, + "src": "154:1:1" + }, + { + "id": 17, + "name": "B", + "nameLocations": + [ + "157:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 10, + "src": "157:1:1" + } + ], + "src": "145:14:1" + }, + "parameters": + { + "id": 15, + "nodeType": "ParameterList", + "parameters": [], + "src": "135:2:1" + }, + "returnParameters": + { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "160:0:1" + }, + "scope": 22, + "src": "125:37:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 23, + "src": "100:64:1", + "usedErrors": [] + } + ], + "src": "0:165:1" +} diff --git a/ethers-solc/test-data/ast/unicode.json b/ethers-solc/test-data/ast/unicode.json new file mode 100644 index 00000000..dcb267b3 --- /dev/null +++ b/ethers-solc/test-data/ast/unicode.json @@ -0,0 +1,136 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 9 + ] + }, + "id": 10, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 9, + "linearizedBaseContracts": + [ + 9 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 7, + "nodeType": "Block", + "src": "33:42:1", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "mutability": "mutable", + "name": "x", + "nameLocation": "49:1:1", + "nodeType": "VariableDeclaration", + "scope": 7, + "src": "35:15:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": + { + "id": 3, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "35:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "id": 6, + "initialValue": + { + "hexValue": "48656c6c6f20f09f9883", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "unicodeString", + "lValueRequested": false, + "nodeType": "Literal", + "src": "53:19:1", + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_cd7a99177cebb3d14b8cc54e313dbf76867c71cd6fbb9a33ce3870dc80e9992b", + "typeString": "literal_string hex\"48656c6c6f20f09f9883\"" + }, + "value": "Hello \ud83d\ude03" + }, + "nodeType": "VariableDeclarationStatement", + "src": "35:37:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 8, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "22:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 9, + "src": "13:62:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 10, + "src": "0:77:1", + "usedErrors": [] + } + ], + "src": "0:78:1" +} diff --git a/ethers-solc/test-data/ast/used_errors.json b/ethers-solc/test-data/ast/used_errors.json new file mode 100644 index 00000000..c59b4f53 --- /dev/null +++ b/ethers-solc/test-data/ast/used_errors.json @@ -0,0 +1,235 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 19 + ], + "X": + [ + 2 + ], + "f": + [ + 9 + ] + }, + "id": 20, + "nodeType": "SourceUnit", + "nodes": + [ + { + "errorSelector": "c1599bd9", + "id": 2, + "name": "X", + "nameLocation": "6:1:1", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "7:2:1" + }, + "src": "0:10:1" + }, + { + "body": + { + "id": 8, + "nodeType": "Block", + "src": "29:15:1", + "statements": + [ + { + "errorCall": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 5, + "name": "X", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2, + "src": "38:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 6, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "38:3:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 7, + "nodeType": "RevertStatement", + "src": "31:10:1" + } + ] + }, + "id": 9, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "f", + "nameLocation": "20:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": [], + "src": "21:2:1" + }, + "returnParameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "29:0:1" + }, + "scope": 20, + "src": "11:33:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 19, + "linearizedBaseContracts": + [ + 19 + ], + "name": "C", + "nameLocation": "54:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "errorSelector": "2bc80f3a", + "id": 11, + "name": "T", + "nameLocation": "68:1:1", + "nodeType": "ErrorDefinition", + "parameters": + { + "id": 10, + "nodeType": "ParameterList", + "parameters": [], + "src": "69:2:1" + }, + "src": "62:10:1" + }, + { + "body": + { + "id": 17, + "nodeType": "Block", + "src": "97:8:1", + "statements": + [ + { + "expression": + { + "arguments": [], + "expression": + { + "argumentTypes": [], + "id": 14, + "name": "f", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9, + "src": "99:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_function_internal_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 15, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "99:3:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 16, + "nodeType": "ExpressionStatement", + "src": "99:3:1" + } + ] + }, + "functionSelector": "b8c9d365", + "id": 18, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "h", + "nameLocation": "86:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 12, + "nodeType": "ParameterList", + "parameters": [], + "src": "87:2:1" + }, + "returnParameters": + { + "id": 13, + "nodeType": "ParameterList", + "parameters": [], + "src": "97:0:1" + }, + "scope": 19, + "src": "77:28:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + } + ], + "scope": 20, + "src": "45:62:1", + "usedErrors": + [ + 2, + 11 + ] + } + ], + "src": "0:108:1" +} diff --git a/ethers-solc/test-data/ast/userDefinedValueType.json b/ethers-solc/test-data/ast/userDefinedValueType.json new file mode 100644 index 00000000..17bb19ef --- /dev/null +++ b/ethers-solc/test-data/ast/userDefinedValueType.json @@ -0,0 +1,355 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 27 + ], + "MyAddress": + [ + 2 + ], + "MyUInt": + [ + 4 + ], + "f": + [ + 16 + ] + }, + "id": 28, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "MyAddress", + "id": 2, + "name": "MyAddress", + "nameLocation": "5:9:1", + "nodeType": "UserDefinedValueTypeDefinition", + "src": "0:26:1", + "underlyingType": + { + "id": 1, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "18:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + }, + { + "canonicalName": "MyUInt", + "id": 4, + "name": "MyUInt", + "nameLocation": "32:6:1", + "nodeType": "UserDefinedValueTypeDefinition", + "src": "27:20:1", + "underlyingType": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "42:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "body": + { + "id": 15, + "nodeType": "Block", + "src": "61:34:1", + "statements": + [ + { + "assignments": + [ + 9 + ], + "declarations": + [ + { + "constant": false, + "id": 9, + "mutability": "mutable", + "name": "a", + "nameLocation": "77:1:1", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "67:11:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_MyAddress_$2", + "typeString": "MyAddress" + }, + "typeName": + { + "id": 8, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 7, + "name": "MyAddress", + "nameLocations": + [ + "67:9:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "67:9:1" + }, + "referencedDeclaration": 2, + "src": "67:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_MyAddress_$2", + "typeString": "MyAddress" + } + }, + "visibility": "internal" + } + ], + "id": 10, + "nodeType": "VariableDeclarationStatement", + "src": "67:11:1" + }, + { + "assignments": + [ + 13 + ], + "declarations": + [ + { + "constant": false, + "id": 13, + "mutability": "mutable", + "name": "b", + "nameLocation": "91:1:1", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "84:8:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_MyUInt_$4", + "typeString": "MyUInt" + }, + "typeName": + { + "id": 12, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 11, + "name": "MyUInt", + "nameLocations": + [ + "84:6:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 4, + "src": "84:6:1" + }, + "referencedDeclaration": 4, + "src": "84:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_MyUInt_$4", + "typeString": "MyUInt" + } + }, + "visibility": "internal" + } + ], + "id": 14, + "nodeType": "VariableDeclarationStatement", + "src": "84:8:1" + } + ] + }, + "id": 16, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "f", + "nameLocation": "57:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 5, + "nodeType": "ParameterList", + "parameters": [], + "src": "58:2:1" + }, + "returnParameters": + { + "id": 6, + "nodeType": "ParameterList", + "parameters": [], + "src": "61:0:1" + }, + "scope": 28, + "src": "48:47:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 27, + "linearizedBaseContracts": + [ + 27 + ], + "name": "C", + "nameLocation": "105:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "canonicalName": "C.MyAddress", + "id": 18, + "name": "MyAddress", + "nameLocation": "118:9:1", + "nodeType": "UserDefinedValueTypeDefinition", + "src": "113:26:1", + "underlyingType": + { + "id": 17, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "131:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + }, + { + "canonicalName": "C.MyUInt", + "id": 20, + "name": "MyUInt", + "nameLocation": "149:6:1", + "nodeType": "UserDefinedValueTypeDefinition", + "src": "144:20:1", + "underlyingType": + { + "id": 19, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "159:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "constant": false, + "functionSelector": "97682884", + "id": 26, + "mutability": "mutable", + "name": "m", + "nameLocation": "205:1:1", + "nodeType": "VariableDeclaration", + "scope": 27, + "src": "169:37:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$", + "typeString": "mapping(C.MyAddress => C.MyUInt)" + }, + "typeName": + { + "id": 25, + "keyType": + { + "id": 22, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 21, + "name": "MyAddress", + "nameLocations": + [ + "177:9:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 18, + "src": "177:9:1" + }, + "referencedDeclaration": 18, + "src": "177:9:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_MyAddress_$18", + "typeString": "C.MyAddress" + } + }, + "nodeType": "Mapping", + "src": "169:28:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_userDefinedValueType$_MyAddress_$18_$_t_userDefinedValueType$_MyUInt_$20_$", + "typeString": "mapping(C.MyAddress => C.MyUInt)" + }, + "valueType": + { + "id": 24, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 23, + "name": "MyUInt", + "nameLocations": + [ + "190:6:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 20, + "src": "190:6:1" + }, + "referencedDeclaration": 20, + "src": "190:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_MyUInt_$20", + "typeString": "C.MyUInt" + } + } + }, + "visibility": "public" + } + ], + "scope": 28, + "src": "96:113:1", + "usedErrors": [] + } + ], + "src": "0:210:1" +} diff --git a/ethers-solc/test-data/ast/using_for_directive.json b/ethers-solc/test-data/ast/using_for_directive.json new file mode 100644 index 00000000..57658134 --- /dev/null +++ b/ethers-solc/test-data/ast/using_for_directive.json @@ -0,0 +1,186 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 13 + ], + "L": + [ + 4 + ], + "f": + [ + 10 + ] + }, + "id": 14, + "nodeType": "SourceUnit", + "nodes": + [ + { + "functionList": + [ + { + "function": + { + "id": 1, + "name": "f", + "nameLocations": + [ + "7:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 10, + "src": "7:1:1" + } + } + ], + "global": false, + "id": 3, + "nodeType": "UsingForDirective", + "src": "0:19:1", + "typeName": + { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "14:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "L", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4 + ], + "name": "L", + "nameLocation": "28:1:1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "20:12:1", + "usedErrors": [] + }, + { + "body": + { + "id": 9, + "nodeType": "Block", + "src": "50:2:1", + "statements": [] + }, + "id": 10, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "f", + "nameLocation": "42:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "44:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 5, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "44:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "43:6:1" + }, + "returnParameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "50:0:1" + }, + "scope": 14, + "src": "33:19:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 13, + "linearizedBaseContracts": + [ + 13 + ], + "name": "C", + "nameLocation": "62:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "global": false, + "id": 12, + "libraryName": + { + "id": 11, + "name": "L", + "nameLocations": + [ + "72:1:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 4, + "src": "72:1:1" + }, + "nodeType": "UsingForDirective", + "src": "66:14:1" + } + ], + "scope": 14, + "src": "53:29:1", + "usedErrors": [] + } + ], + "src": "0:83:1" +} diff --git a/ethers-solc/test-data/ast/var_access.json b/ethers-solc/test-data/ast/var_access.json new file mode 100644 index 00000000..bff9d9e8 --- /dev/null +++ b/ethers-solc/test-data/ast/var_access.json @@ -0,0 +1,162 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 9 + ] + }, + "id": 10, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 9, + "linearizedBaseContracts": + [ + 9 + ], + "name": "C", + "nameLocation": "9:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 7, + "nodeType": "Block", + "src": "42:51:1", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "mutability": "mutable", + "name": "x", + "nameLocation": "57:1:1", + "nodeType": "VariableDeclaration", + "scope": 7, + "src": "52:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "52:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 5, + "nodeType": "VariableDeclarationStatement", + "src": "52:6:1" + }, + { + "AST": + { + "nodeType": "YulBlock", + "src": "77:10:1", + "statements": + [ + { + "nodeType": "YulAssignment", + "src": "79:6:1", + "value": + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "84:1:1", + "type": "", + "value": "7" + }, + "variableNames": + [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "79:1:1" + } + ] + } + ] + }, + "evmVersion": "london", + "externalReferences": + [ + { + "declaration": 4, + "isOffset": false, + "isSlot": false, + "src": "79:1:1", + "valueSize": 1 + } + ], + "id": 6, + "nodeType": "InlineAssembly", + "src": "68:19:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 8, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "26:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "27:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "42:0:1" + }, + "scope": 9, + "src": "17:76:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 10, + "src": "0:95:1", + "usedErrors": [] + } + ], + "src": "0:96:1" +} diff --git a/ethers-solc/test-data/ast/yul_hex_literal.json b/ethers-solc/test-data/ast/yul_hex_literal.json new file mode 100644 index 00000000..832a95d8 --- /dev/null +++ b/ethers-solc/test-data/ast/yul_hex_literal.json @@ -0,0 +1,155 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "Sample": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "Sample", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "Sample", + "nameLocation": "9:6:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "47:167:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "66:142:1", + "statements": + [ + { + "nodeType": "YulVariableDeclaration", + "src": "80:15:1", + "value": + { + "hexValue": "74657374", + "kind": "string", + "nodeType": "YulLiteral", + "src": "89:6:1", + "type": "", + "value": "test" + }, + "variables": + [ + { + "name": "a", + "nodeType": "YulTypedName", + "src": "84:1:1", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "108:54:1", + "value": + { + "hexValue": "112233445566778899aabbccddeeff6677889900", + "kind": "string", + "nodeType": "YulLiteral", + "src": "117:45:1", + "type": "" + }, + "variables": + [ + { + "name": "b", + "nodeType": "YulTypedName", + "src": "112:1:1", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "175:23:1", + "value": + { + "hexValue": "1234abcd", + "kind": "string", + "nodeType": "YulLiteral", + "src": "184:14:1", + "type": "" + }, + "variables": + [ + { + "name": "c", + "nodeType": "YulTypedName", + "src": "179:1:1", + "type": "" + } + ] + } + ] + }, + "evmVersion": "loop", + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "57:151:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "31:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "32:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "47:0:1" + }, + "scope": 6, + "src": "22:192:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:216:1", + "usedErrors": [] + } + ], + "src": "0:217:1" +} diff --git a/ethers-solc/test-data/bytes.sol b/ethers-solc/test-data/bytes.sol new file mode 100644 index 00000000..e69de29b From 04e0092adf7fcfd9226f9601549d0a085733e6de Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 22 Dec 2022 17:22:11 +0100 Subject: [PATCH 10/40] revert: Ast Artifact (#1966) --- .../src/artifact_output/configurable.rs | 8 +- ethers-solc/src/artifacts/ast/lowfidelity.rs | 217 + ethers-solc/src/artifacts/ast/mod.rs | 4 + ethers-solc/src/artifacts/mod.rs | 12 +- ethers-solc/test-data/ast/ast-erc4626.json | 6612 +++++++++++++++++ 5 files changed, 6843 insertions(+), 10 deletions(-) create mode 100644 ethers-solc/src/artifacts/ast/lowfidelity.rs create mode 100644 ethers-solc/test-data/ast/ast-erc4626.json diff --git a/ethers-solc/src/artifact_output/configurable.rs b/ethers-solc/src/artifact_output/configurable.rs index 3d3d0bae..7d4fb06c 100644 --- a/ethers-solc/src/artifact_output/configurable.rs +++ b/ethers-solc/src/artifact_output/configurable.rs @@ -16,9 +16,9 @@ use crate::{ BytecodeOutputSelection, ContractOutputSelection, EvmOutputSelection, EwasmOutputSelection, }, - CompactContractBytecodeCow, DevDoc, Evm, Ewasm, FunctionDebugData, GasEstimates, - GeneratedSource, LosslessAbi, LosslessMetadata, Metadata, Offsets, Settings, SourceUnit, - StorageLayout, UserDoc, + Ast, CompactContractBytecodeCow, DevDoc, Evm, Ewasm, FunctionDebugData, GasEstimates, + GeneratedSource, LosslessAbi, LosslessMetadata, Metadata, Offsets, Settings, StorageLayout, + UserDoc, }, sources::VersionedSourceFile, ArtifactOutput, SolcConfig, SolcError, SourceFile, @@ -68,7 +68,7 @@ pub struct ConfigurableContractArtifact { #[serde(default, skip_serializing_if = "Option::is_none")] pub ewasm: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub ast: Option, + pub ast: Option, /// The identifier of the source file #[serde(default, skip_serializing_if = "Option::is_none")] pub id: Option, diff --git a/ethers-solc/src/artifacts/ast/lowfidelity.rs b/ethers-solc/src/artifacts/ast/lowfidelity.rs new file mode 100644 index 00000000..738f4301 --- /dev/null +++ b/ethers-solc/src/artifacts/ast/lowfidelity.rs @@ -0,0 +1,217 @@ +//! Bindings for solc's `ast` output field + +use crate::artifacts::serde_helpers; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::{collections::BTreeMap, fmt, fmt::Write, str::FromStr}; + +/// Represents the AST field in the solc output +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Ast { + #[serde(rename = "absolutePath")] + pub absolute_path: String, + pub id: usize, + #[serde(default, rename = "exportedSymbols")] + pub exported_symbols: BTreeMap>, + #[serde(rename = "nodeType")] + pub node_type: NodeType, + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + #[serde(default)] + pub nodes: Vec, + + /// Node attributes that were not deserialized. + #[serde(flatten)] + pub other: BTreeMap, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Node { + /// The node ID. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub id: Option, + + /// The node type. + #[serde(rename = "nodeType")] + pub node_type: NodeType, + + /// The location of the node in the source file. + #[serde(with = "serde_helpers::display_from_str")] + pub src: SourceLocation, + + /// Child nodes for some node types. + #[serde(default)] + pub nodes: Vec, + + /// Body node for some node types. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub body: Option>, + + /// Node attributes that were not deserialized. + #[serde(flatten)] + pub other: BTreeMap, +} + +impl Node { + /// Deserialize a serialized node attribute. + pub fn attribute(&self, key: impl AsRef) -> Option { + // TODO: Can we avoid this clone? + self.other.get(key.as_ref()).and_then(|v| serde_json::from_value(v.clone()).ok()) + } +} + +/// Represents the source location of a node: `::`. +/// +/// The `length` and `index` can be -1 which is represented as `None` +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct SourceLocation { + pub start: usize, + pub length: Option, + pub index: Option, +} + +impl FromStr for SourceLocation { + type Err = String; + + fn from_str(s: &str) -> Result { + let invalid_location = move || format!("{s} invalid source location"); + + let mut split = s.split(':'); + let start = split + .next() + .ok_or_else(invalid_location)? + .parse::() + .map_err(|_| invalid_location())?; + let length = split + .next() + .ok_or_else(invalid_location)? + .parse::() + .map_err(|_| invalid_location())?; + let index = split + .next() + .ok_or_else(invalid_location)? + .parse::() + .map_err(|_| invalid_location())?; + + let length = if length < 0 { None } else { Some(length as usize) }; + let index = if index < 0 { None } else { Some(index as usize) }; + + Ok(Self { start, length, index }) + } +} + +impl fmt::Display for SourceLocation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.start.fmt(f)?; + f.write_char(':')?; + if let Some(length) = self.length { + length.fmt(f)?; + } else { + f.write_str("-1")?; + } + f.write_char(':')?; + if let Some(index) = self.index { + index.fmt(f)?; + } else { + f.write_str("-1")?; + } + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum NodeType { + // Expressions + Assignment, + BinaryOperation, + Conditional, + ElementaryTypeNameExpression, + FunctionCall, + FunctionCallOptions, + Identifier, + IndexAccess, + IndexRangeAccess, + Literal, + MemberAccess, + NewExpression, + TupleExpression, + UnaryOperation, + + // Statements + Block, + Break, + Continue, + DoWhileStatement, + EmitStatement, + ExpressionStatement, + ForStatement, + IfStatement, + InlineAssembly, + PlaceholderStatement, + Return, + RevertStatement, + TryStatement, + UncheckedBlock, + VariableDeclarationStatement, + VariableDeclaration, + WhileStatement, + + // Yul statements + YulAssignment, + YulBlock, + YulBreak, + YulContinue, + YulExpressionStatement, + YulLeave, + YulForLoop, + YulFunctionDefinition, + YulIf, + YulSwitch, + YulVariableDeclaration, + + // Yul expressions + YulFunctionCall, + YulIdentifier, + YulLiteral, + + // Yul literals + YulLiteralValue, + YulHexValue, + + // Definitions + ContractDefinition, + FunctionDefinition, + EventDefinition, + ErrorDefinition, + ModifierDefinition, + StructDefinition, + EnumDefinition, + UserDefinedValueTypeDefinition, + + // Directives + PragmaDirective, + ImportDirective, + UsingForDirective, + + // Misc + SourceUnit, + InheritanceSpecifier, + ElementaryTypeName, + FunctionTypeName, + ParameterList, + TryCatchClause, + ModifierInvocation, + + /// An unknown AST node type. + Other(String), +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_parse_ast() { + let ast = include_str!("../../../test-data/ast/ast-erc4626.json"); + let _ast: Ast = serde_json::from_str(ast).unwrap(); + } +} diff --git a/ethers-solc/src/artifacts/ast/mod.rs b/ethers-solc/src/artifacts/ast/mod.rs index 31f3a496..928bd002 100644 --- a/ethers-solc/src/artifacts/ast/mod.rs +++ b/ethers-solc/src/artifacts/ast/mod.rs @@ -17,6 +17,10 @@ pub use misc::*; pub mod util; pub mod visitor; +/// A low fidelity representation of the AST. +pub(crate) mod lowfidelity; +pub use lowfidelity::Ast; + /// Types for the Yul AST. /// /// The Yul AST is embedded into the Solidity AST for inline assembly blocks. diff --git a/ethers-solc/src/artifacts/mod.rs b/ethers-solc/src/artifacts/mod.rs index 7de6b01b..7b7985be 100644 --- a/ethers-solc/src/artifacts/mod.rs +++ b/ethers-solc/src/artifacts/mod.rs @@ -22,7 +22,10 @@ pub mod contract; pub mod output_selection; pub mod serde_helpers; use crate::{ - artifacts::output_selection::{ContractOutputSelection, OutputSelection}, + artifacts::{ + lowfidelity::NodeType, + output_selection::{ContractOutputSelection, OutputSelection}, + }, filter::FilteredSources, }; pub use bytecode::*; @@ -1835,7 +1838,7 @@ pub struct SecondarySourceLocation { pub struct SourceFile { pub id: u32, #[serde(default, with = "serde_helpers::empty_json_object_opt")] - pub ast: Option, + pub ast: Option, } // === impl SourceFile === @@ -1846,10 +1849,7 @@ impl SourceFile { pub fn contains_contract_definition(&self) -> bool { if let Some(ref ast) = self.ast { // contract definitions are only allowed at the source-unit level - return ast - .nodes - .iter() - .any(|node| matches!(node, SourceUnitPart::ContractDefinition(_))) + return ast.nodes.iter().any(|node| node.node_type == NodeType::ContractDefinition) // abstract contract, interfaces: ContractDefinition } diff --git a/ethers-solc/test-data/ast/ast-erc4626.json b/ethers-solc/test-data/ast/ast-erc4626.json new file mode 100644 index 00000000..7f677053 --- /dev/null +++ b/ethers-solc/test-data/ast/ast-erc4626.json @@ -0,0 +1,6612 @@ +{ + "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/mixins/ERC4626.sol", + "id": 2954, + "exportedSymbols": { + "ERC20": [ + 31408 + ], + "ERC4626": [ + 2953 + ], + "FixedPointMathLib": [ + 32321 + ], + "SafeTransferLib": [ + 32785 + ] + }, + "nodeType": "SourceUnit", + "src": "42:6474:4", + "nodes": [ + { + "id": 2434, + "nodeType": "PragmaDirective", + "src": "42:24:4", + "literals": [ + "solidity", + ">=", + "0.8", + ".0" + ] + }, + { + "id": 2436, + "nodeType": "ImportDirective", + "src": "68:42:4", + "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/tokens/ERC20.sol", + "file": "../tokens/ERC20.sol", + "nameLocation": "-1:-1:-1", + "scope": 2954, + "sourceUnit": 31409, + "symbolAliases": [ + { + "foreign": { + "id": 2435, + "name": "ERC20", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "src": "76:5:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 2438, + "nodeType": "ImportDirective", + "src": "111:61:4", + "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/utils/SafeTransferLib.sol", + "file": "../utils/SafeTransferLib.sol", + "nameLocation": "-1:-1:-1", + "scope": 2954, + "sourceUnit": 32786, + "symbolAliases": [ + { + "foreign": { + "id": 2437, + "name": "SafeTransferLib", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "src": "119:15:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 2440, + "nodeType": "ImportDirective", + "src": "173:65:4", + "absolutePath": "/home/oliver/Projects/github/rari-capital/solmate/src/utils/FixedPointMathLib.sol", + "file": "../utils/FixedPointMathLib.sol", + "nameLocation": "-1:-1:-1", + "scope": 2954, + "sourceUnit": 32322, + "symbolAliases": [ + { + "foreign": { + "id": 2439, + "name": "FixedPointMathLib", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "src": "181:17:4", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 2953, + "nodeType": "ContractDefinition", + "src": "395:6120:4", + "nodes": [ + { + "id": 2447, + "nodeType": "UsingForDirective", + "src": "436:32:4", + "libraryName": { + "id": 2444, + "name": "SafeTransferLib", + "nodeType": "IdentifierPath", + "referencedDeclaration": 32785, + "src": "442:15:4" + }, + "typeName": { + "id": 2446, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 2445, + "name": "ERC20", + "nodeType": "IdentifierPath", + "referencedDeclaration": 31408, + "src": "462:5:4" + }, + "referencedDeclaration": 31408, + "src": "462:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + } + }, + { + "id": 2450, + "nodeType": "UsingForDirective", + "src": "473:36:4", + "libraryName": { + "id": 2448, + "name": "FixedPointMathLib", + "nodeType": "IdentifierPath", + "referencedDeclaration": 32321, + "src": "479:17:4" + }, + "typeName": { + "id": 2449, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "501:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + }, + { + "id": 2460, + "nodeType": "EventDefinition", + "src": "694:93:4", + "anonymous": false, + "name": "Deposit", + "nameLocation": "700:7:4", + "parameters": { + "id": 2459, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2452, + "indexed": true, + "mutability": "mutable", + "name": "caller", + "nameLocation": "724:6:4", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "708:22:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2451, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "708:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2454, + "indexed": true, + "mutability": "mutable", + "name": "owner", + "nameLocation": "748:5:4", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "732:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2453, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "732:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2456, + "indexed": false, + "mutability": "mutable", + "name": "assets", + "nameLocation": "763:6:4", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "755:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2455, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "755:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2458, + "indexed": false, + "mutability": "mutable", + "name": "shares", + "nameLocation": "779:6:4", + "nodeType": "VariableDeclaration", + "scope": 2460, + "src": "771:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2457, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "771:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "707:79:4" + } + }, + { + "id": 2472, + "nodeType": "EventDefinition", + "src": "793:166:4", + "anonymous": false, + "name": "Withdraw", + "nameLocation": "799:8:4", + "parameters": { + "id": 2471, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2462, + "indexed": true, + "mutability": "mutable", + "name": "caller", + "nameLocation": "833:6:4", + "nodeType": "VariableDeclaration", + "scope": 2472, + "src": "817:22:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2461, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "817:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2464, + "indexed": true, + "mutability": "mutable", + "name": "receiver", + "nameLocation": "865:8:4", + "nodeType": "VariableDeclaration", + "scope": 2472, + "src": "849:24:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2463, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "849:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2466, + "indexed": true, + "mutability": "mutable", + "name": "owner", + "nameLocation": "899:5:4", + "nodeType": "VariableDeclaration", + "scope": 2472, + "src": "883:21:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2465, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "883:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2468, + "indexed": false, + "mutability": "mutable", + "name": "assets", + "nameLocation": "922:6:4", + "nodeType": "VariableDeclaration", + "scope": 2472, + "src": "914:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2467, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "914:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2470, + "indexed": false, + "mutability": "mutable", + "name": "shares", + "nameLocation": "946:6:4", + "nodeType": "VariableDeclaration", + "scope": 2472, + "src": "938:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2469, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "938:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "807:151:4" + } + }, + { + "id": 2475, + "nodeType": "VariableDeclaration", + "src": "1146:28:4", + "constant": false, + "functionSelector": "38d52e0f", + "mutability": "immutable", + "name": "asset", + "nameLocation": "1169:5:4", + "scope": 2953, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + }, + "typeName": { + "id": 2474, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 2473, + "name": "ERC20", + "nodeType": "IdentifierPath", + "referencedDeclaration": 31408, + "src": "1146:5:4" + }, + "referencedDeclaration": 31408, + "src": "1146:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "visibility": "public" + }, + { + "id": 2497, + "nodeType": "FunctionDefinition", + "src": "1181:172:4", + "body": { + "id": 2496, + "nodeType": "Block", + "src": "1322:31:4", + "statements": [ + { + "expression": { + "id": 2494, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2492, + "name": "asset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2475, + "src": "1332:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 2493, + "name": "_asset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2478, + "src": "1340:6:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "src": "1332:14:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "id": 2495, + "nodeType": "ExpressionStatement", + "src": "1332:14:4" + } + ] + }, + "implemented": true, + "kind": "constructor", + "modifiers": [ + { + "arguments": [ + { + "id": 2485, + "name": "_name", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2480, + "src": "1287:5:4", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "id": 2486, + "name": "_symbol", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2482, + "src": "1294:7:4", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string memory" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "id": 2487, + "name": "_asset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2478, + "src": "1303:6:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "id": 2488, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "decimals", + "nodeType": "MemberAccess", + "referencedDeclaration": 31045, + "src": "1303:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint8_$", + "typeString": "function () view external returns (uint8)" + } + }, + "id": 2489, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1303:17:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "id": 2490, + "kind": "baseConstructorSpecifier", + "modifierName": { + "id": 2484, + "name": "ERC20", + "nodeType": "IdentifierPath", + "referencedDeclaration": 31408, + "src": "1281:5:4" + }, + "nodeType": "ModifierInvocation", + "src": "1281:40:4" + } + ], + "name": "", + "nameLocation": "-1:-1:-1", + "parameters": { + "id": 2483, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2478, + "mutability": "mutable", + "name": "_asset", + "nameLocation": "1208:6:4", + "nodeType": "VariableDeclaration", + "scope": 2497, + "src": "1202:12:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + }, + "typeName": { + "id": 2477, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 2476, + "name": "ERC20", + "nodeType": "IdentifierPath", + "referencedDeclaration": 31408, + "src": "1202:5:4" + }, + "referencedDeclaration": 31408, + "src": "1202:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2480, + "mutability": "mutable", + "name": "_name", + "nameLocation": "1238:5:4", + "nodeType": "VariableDeclaration", + "scope": 2497, + "src": "1224:19:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 2479, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1224:6:4", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2482, + "mutability": "mutable", + "name": "_symbol", + "nameLocation": "1267:7:4", + "nodeType": "VariableDeclaration", + "scope": 2497, + "src": "1253:21:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 2481, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "1253:6:4", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "src": "1192:88:4" + }, + "returnParameters": { + "id": 2491, + "nodeType": "ParameterList", + "parameters": [], + "src": "1322:0:4" + }, + "scope": 2953, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "id": 2549, + "nodeType": "FunctionDefinition", + "src": "1547:516:4", + "body": { + "id": 2548, + "nodeType": "Block", + "src": "1638:425:4", + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2514, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "components": [ + { + "id": 2511, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2507, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2504, + "src": "1732:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2509, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2499, + "src": "1756:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2508, + "name": "previewDeposit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2822, + "src": "1741:14:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 2510, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1741:22:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1732:31:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2512, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "1731:33:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "hexValue": "30", + "id": 2513, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1768:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "1731:38:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5a45524f5f534841524553", + "id": 2515, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1771:13:4", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_2119bd5d92259e418533f96b824fbd100e3dea453e6ac4c5f7315e6344368f2f", + "typeString": "literal_string \"ZERO_SHARES\"" + }, + "value": "ZERO_SHARES" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_2119bd5d92259e418533f96b824fbd100e3dea453e6ac4c5f7315e6344368f2f", + "typeString": "literal_string \"ZERO_SHARES\"" + } + ], + "id": 2506, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "1723:7:4", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 2516, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1723:62:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2517, + "nodeType": "ExpressionStatement", + "src": "1723:62:4" + }, + { + "expression": { + "arguments": [ + { + "expression": { + "id": 2521, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "1888:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2522, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "1888:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "id": 2525, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "1908:4:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC4626_$2953", + "typeString": "contract ERC4626" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_ERC4626_$2953", + "typeString": "contract ERC4626" + } + ], + "id": 2524, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1900:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 2523, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1900:7:4", + "typeDescriptions": {} + } + }, + "id": 2526, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1900:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2527, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2499, + "src": "1915:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2518, + "name": "asset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2475, + "src": "1865:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "id": 2520, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "safeTransferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 32744, + "src": "1865:22:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", + "typeString": "function (contract ERC20,address,address,uint256)" + } + }, + "id": 2528, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1865:57:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2529, + "nodeType": "ExpressionStatement", + "src": "1865:57:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2531, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2501, + "src": "1939:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2532, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2504, + "src": "1949:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2530, + "name": "_mint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31379, + "src": "1933:5:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 2533, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1933:23:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2534, + "nodeType": "ExpressionStatement", + "src": "1933:23:4" + }, + { + "eventCall": { + "arguments": [ + { + "expression": { + "id": 2536, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "1980:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2537, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "1980:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2538, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2501, + "src": "1992:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2539, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2499, + "src": "2002:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2540, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2504, + "src": "2010:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2535, + "name": "Deposit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2460, + "src": "1972:7:4", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256,uint256)" + } + }, + "id": 2541, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "1972:45:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2542, + "nodeType": "EmitStatement", + "src": "1967:50:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2544, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2499, + "src": "2041:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2545, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2504, + "src": "2049:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2543, + "name": "afterDeposit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2952, + "src": "2028:12:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 2546, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2028:28:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2547, + "nodeType": "ExpressionStatement", + "src": "2028:28:4" + } + ] + }, + "functionSelector": "6e553f65", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "deposit", + "nameLocation": "1556:7:4", + "parameters": { + "id": 2502, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2499, + "mutability": "mutable", + "name": "assets", + "nameLocation": "1572:6:4", + "nodeType": "VariableDeclaration", + "scope": 2549, + "src": "1564:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2498, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1564:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2501, + "mutability": "mutable", + "name": "receiver", + "nameLocation": "1588:8:4", + "nodeType": "VariableDeclaration", + "scope": 2549, + "src": "1580:16:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2500, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1580:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "1563:34:4" + }, + "returnParameters": { + "id": 2505, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2504, + "mutability": "mutable", + "name": "shares", + "nameLocation": "1630:6:4", + "nodeType": "VariableDeclaration", + "scope": 2549, + "src": "1622:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2503, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1622:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1621:16:4" + }, + "scope": 2953, + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + }, + { + "id": 2595, + "nodeType": "FunctionDefinition", + "src": "2069:467:4", + "body": { + "id": 2594, + "nodeType": "Block", + "src": "2157:379:4", + "statements": [ + { + "expression": { + "id": 2562, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2558, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2556, + "src": "2167:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2560, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2551, + "src": "2188:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2559, + "name": "previewMint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2846, + "src": "2176:11:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 2561, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2176:19:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2167:28:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2563, + "nodeType": "ExpressionStatement", + "src": "2167:28:4" + }, + { + "expression": { + "arguments": [ + { + "expression": { + "id": 2567, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "2361:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2568, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "2361:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "id": 2571, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "2381:4:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC4626_$2953", + "typeString": "contract ERC4626" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_ERC4626_$2953", + "typeString": "contract ERC4626" + } + ], + "id": 2570, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2373:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 2569, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2373:7:4", + "typeDescriptions": {} + } + }, + "id": 2572, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2373:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2573, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2556, + "src": "2388:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2564, + "name": "asset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2475, + "src": "2338:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "id": 2566, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "safeTransferFrom", + "nodeType": "MemberAccess", + "referencedDeclaration": 32744, + "src": "2338:22:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", + "typeString": "function (contract ERC20,address,address,uint256)" + } + }, + "id": 2574, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2338:57:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2575, + "nodeType": "ExpressionStatement", + "src": "2338:57:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2577, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2553, + "src": "2412:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2578, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2551, + "src": "2422:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2576, + "name": "_mint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31379, + "src": "2406:5:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 2579, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2406:23:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2580, + "nodeType": "ExpressionStatement", + "src": "2406:23:4" + }, + { + "eventCall": { + "arguments": [ + { + "expression": { + "id": 2582, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "2453:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2583, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "2453:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2584, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2553, + "src": "2465:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2585, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2556, + "src": "2475:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2586, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2551, + "src": "2483:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2581, + "name": "Deposit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2460, + "src": "2445:7:4", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (address,address,uint256,uint256)" + } + }, + "id": 2587, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2445:45:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2588, + "nodeType": "EmitStatement", + "src": "2440:50:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2590, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2556, + "src": "2514:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2591, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2551, + "src": "2522:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2589, + "name": "afterDeposit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2952, + "src": "2501:12:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 2592, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2501:28:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2593, + "nodeType": "ExpressionStatement", + "src": "2501:28:4" + } + ] + }, + "functionSelector": "94bf804d", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "mint", + "nameLocation": "2078:4:4", + "parameters": { + "id": 2554, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2551, + "mutability": "mutable", + "name": "shares", + "nameLocation": "2091:6:4", + "nodeType": "VariableDeclaration", + "scope": 2595, + "src": "2083:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2550, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2083:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2553, + "mutability": "mutable", + "name": "receiver", + "nameLocation": "2107:8:4", + "nodeType": "VariableDeclaration", + "scope": 2595, + "src": "2099:16:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2552, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2099:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "2082:34:4" + }, + "returnParameters": { + "id": 2557, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2556, + "mutability": "mutable", + "name": "assets", + "nameLocation": "2149:6:4", + "nodeType": "VariableDeclaration", + "scope": 2595, + "src": "2141:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2555, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2141:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2140:16:4" + }, + "scope": 2953, + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + }, + { + "id": 2673, + "nodeType": "FunctionDefinition", + "src": "2542:679:4", + "body": { + "id": 2672, + "nodeType": "Block", + "src": "2679:542:4", + "statements": [ + { + "expression": { + "id": 2610, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2606, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2604, + "src": "2689:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2608, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2597, + "src": "2714:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2607, + "name": "previewWithdraw", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2870, + "src": "2698:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 2609, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2698:23:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2689:32:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2611, + "nodeType": "ExpressionStatement", + "src": "2689:32:4" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 2615, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 2612, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "2803:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2613, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "2803:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "id": 2614, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2601, + "src": "2817:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "2803:19:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2645, + "nodeType": "IfStatement", + "src": "2799:228:4", + "trueBody": { + "id": 2644, + "nodeType": "Block", + "src": "2824:203:4", + "statements": [ + { + "assignments": [ + 2617 + ], + "declarations": [ + { + "constant": false, + "id": 2617, + "mutability": "mutable", + "name": "allowed", + "nameLocation": "2846:7:4", + "nodeType": "VariableDeclaration", + "scope": 2644, + "src": "2838:15:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2616, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2838:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2624, + "initialValue": { + "baseExpression": { + "baseExpression": { + "id": 2618, + "name": "allowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31057, + "src": "2856:9:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 2620, + "indexExpression": { + "id": 2619, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2601, + "src": "2866:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "2856:16:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 2623, + "indexExpression": { + "expression": { + "id": 2621, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "2873:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2622, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "2873:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "2856:28:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2838:46:4" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2631, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2625, + "name": "allowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2617, + "src": "2939:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "expression": { + "arguments": [ + { + "id": 2628, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2955:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2627, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2955:7:4", + "typeDescriptions": {} + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + } + ], + "id": 2626, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -27, + "src": "2950:4:4", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2629, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "2950:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_uint256", + "typeString": "type(uint256)" + } + }, + "id": 2630, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "max", + "nodeType": "MemberAccess", + "src": "2950:17:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2939:28:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2643, + "nodeType": "IfStatement", + "src": "2935:81:4", + "trueBody": { + "expression": { + "id": 2641, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "baseExpression": { + "baseExpression": { + "id": 2632, + "name": "allowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31057, + "src": "2969:9:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 2636, + "indexExpression": { + "id": 2633, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2601, + "src": "2979:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "2969:16:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 2637, + "indexExpression": { + "expression": { + "id": 2634, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "2986:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2635, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "2986:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "2969:28:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2640, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2638, + "name": "allowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2617, + "src": "3000:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "id": 2639, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2604, + "src": "3010:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3000:16:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2969:47:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2642, + "nodeType": "ExpressionStatement", + "src": "2969:47:4" + } + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "id": 2647, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2597, + "src": "3052:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2648, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2604, + "src": "3060:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2646, + "name": "beforeWithdraw", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2944, + "src": "3037:14:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 2649, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3037:30:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2650, + "nodeType": "ExpressionStatement", + "src": "3037:30:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2652, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2601, + "src": "3084:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2653, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2604, + "src": "3091:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2651, + "name": "_burn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31407, + "src": "3078:5:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 2654, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3078:20:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2655, + "nodeType": "ExpressionStatement", + "src": "3078:20:4" + }, + { + "eventCall": { + "arguments": [ + { + "expression": { + "id": 2657, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "3123:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2658, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "3123:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2659, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2599, + "src": "3135:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2660, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2601, + "src": "3145:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2661, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2597, + "src": "3152:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2662, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2604, + "src": "3160:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2656, + "name": "Withdraw", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2472, + "src": "3114:8:4", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (address,address,address,uint256,uint256)" + } + }, + "id": 2663, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3114:53:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2664, + "nodeType": "EmitStatement", + "src": "3109:58:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2668, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2599, + "src": "3197:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2669, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2597, + "src": "3207:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2665, + "name": "asset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2475, + "src": "3178:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "id": 2667, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "safeTransfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 32764, + "src": "3178:18:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", + "typeString": "function (contract ERC20,address,uint256)" + } + }, + "id": 2670, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3178:36:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2671, + "nodeType": "ExpressionStatement", + "src": "3178:36:4" + } + ] + }, + "functionSelector": "b460af94", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "withdraw", + "nameLocation": "2551:8:4", + "parameters": { + "id": 2602, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2597, + "mutability": "mutable", + "name": "assets", + "nameLocation": "2577:6:4", + "nodeType": "VariableDeclaration", + "scope": 2673, + "src": "2569:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2596, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2569:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2599, + "mutability": "mutable", + "name": "receiver", + "nameLocation": "2601:8:4", + "nodeType": "VariableDeclaration", + "scope": 2673, + "src": "2593:16:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2598, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2593:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2601, + "mutability": "mutable", + "name": "owner", + "nameLocation": "2627:5:4", + "nodeType": "VariableDeclaration", + "scope": 2673, + "src": "2619:13:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2600, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2619:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "2559:79:4" + }, + "returnParameters": { + "id": 2605, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2604, + "mutability": "mutable", + "name": "shares", + "nameLocation": "2671:6:4", + "nodeType": "VariableDeclaration", + "scope": 2673, + "src": "2663:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2603, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2663:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2662:16:4" + }, + "scope": 2953, + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + }, + { + "id": 2757, + "nodeType": "FunctionDefinition", + "src": "3227:713:4", + "body": { + "id": 2756, + "nodeType": "Block", + "src": "3362:578:4", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 2687, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 2684, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "3376:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2685, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "3376:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "id": 2686, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2679, + "src": "3390:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3376:19:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2717, + "nodeType": "IfStatement", + "src": "3372:228:4", + "trueBody": { + "id": 2716, + "nodeType": "Block", + "src": "3397:203:4", + "statements": [ + { + "assignments": [ + 2689 + ], + "declarations": [ + { + "constant": false, + "id": 2689, + "mutability": "mutable", + "name": "allowed", + "nameLocation": "3419:7:4", + "nodeType": "VariableDeclaration", + "scope": 2716, + "src": "3411:15:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2688, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3411:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2696, + "initialValue": { + "baseExpression": { + "baseExpression": { + "id": 2690, + "name": "allowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31057, + "src": "3429:9:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 2692, + "indexExpression": { + "id": 2691, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2679, + "src": "3439:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3429:16:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 2695, + "indexExpression": { + "expression": { + "id": 2693, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "3446:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2694, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "3446:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3429:28:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "3411:46:4" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2703, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2697, + "name": "allowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2689, + "src": "3512:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "expression": { + "arguments": [ + { + "id": 2700, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3528:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2699, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3528:7:4", + "typeDescriptions": {} + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + } + ], + "id": 2698, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -27, + "src": "3523:4:4", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2701, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3523:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_uint256", + "typeString": "type(uint256)" + } + }, + "id": 2702, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "max", + "nodeType": "MemberAccess", + "src": "3523:17:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3512:28:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2715, + "nodeType": "IfStatement", + "src": "3508:81:4", + "trueBody": { + "expression": { + "id": 2713, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "baseExpression": { + "baseExpression": { + "id": 2704, + "name": "allowance", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31057, + "src": "3542:9:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_mapping$_t_address_$_t_uint256_$_$", + "typeString": "mapping(address => mapping(address => uint256))" + } + }, + "id": 2708, + "indexExpression": { + "id": 2705, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2679, + "src": "3552:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "3542:16:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 2709, + "indexExpression": { + "expression": { + "id": 2706, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "3559:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2707, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "3559:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "3542:28:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2712, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2710, + "name": "allowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2689, + "src": "3573:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "id": 2711, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2675, + "src": "3583:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3573:16:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3542:47:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2714, + "nodeType": "ExpressionStatement", + "src": "3542:47:4" + } + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2726, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "components": [ + { + "id": 2723, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2719, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2682, + "src": "3693:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2721, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2675, + "src": "3716:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2720, + "name": "previewRedeem", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2882, + "src": "3702:13:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 2722, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3702:21:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3693:30:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2724, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "3692:32:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "hexValue": "30", + "id": 2725, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3728:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "3692:37:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "hexValue": "5a45524f5f415353455453", + "id": 2727, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3731:13:4", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_bf169ab2ef12d57708bb5afe72ea54ba3ad2eccb91dd95f37571afa377c52483", + "typeString": "literal_string \"ZERO_ASSETS\"" + }, + "value": "ZERO_ASSETS" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_bf169ab2ef12d57708bb5afe72ea54ba3ad2eccb91dd95f37571afa377c52483", + "typeString": "literal_string \"ZERO_ASSETS\"" + } + ], + "id": 2718, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + -18, + -18 + ], + "referencedDeclaration": -18, + "src": "3684:7:4", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 2728, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3684:61:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2729, + "nodeType": "ExpressionStatement", + "src": "3684:61:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2731, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2682, + "src": "3771:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2732, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2675, + "src": "3779:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2730, + "name": "beforeWithdraw", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2944, + "src": "3756:14:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 2733, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3756:30:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2734, + "nodeType": "ExpressionStatement", + "src": "3756:30:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2736, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2679, + "src": "3803:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2737, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2675, + "src": "3810:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2735, + "name": "_burn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31407, + "src": "3797:5:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$", + "typeString": "function (address,uint256)" + } + }, + "id": 2738, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3797:20:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2739, + "nodeType": "ExpressionStatement", + "src": "3797:20:4" + }, + { + "eventCall": { + "arguments": [ + { + "expression": { + "id": 2741, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "3842:3:4", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 2742, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "3842:10:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2743, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2677, + "src": "3854:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2744, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2679, + "src": "3864:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2745, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2682, + "src": "3871:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2746, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2675, + "src": "3879:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2740, + "name": "Withdraw", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2472, + "src": "3833:8:4", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (address,address,address,uint256,uint256)" + } + }, + "id": 2747, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3833:53:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2748, + "nodeType": "EmitStatement", + "src": "3828:58:4" + }, + { + "expression": { + "arguments": [ + { + "id": 2752, + "name": "receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2677, + "src": "3916:8:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2753, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2682, + "src": "3926:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2749, + "name": "asset", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2475, + "src": "3897:5:4", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ERC20_$31408", + "typeString": "contract ERC20" + } + }, + "id": 2751, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "safeTransfer", + "nodeType": "MemberAccess", + "referencedDeclaration": 32764, + "src": "3897:18:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_contract$_ERC20_$31408_$_t_address_$_t_uint256_$returns$__$bound_to$_t_contract$_ERC20_$31408_$", + "typeString": "function (contract ERC20,address,uint256)" + } + }, + "id": 2754, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "3897:36:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2755, + "nodeType": "ExpressionStatement", + "src": "3897:36:4" + } + ] + }, + "functionSelector": "ba087652", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "redeem", + "nameLocation": "3236:6:4", + "parameters": { + "id": 2680, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2675, + "mutability": "mutable", + "name": "shares", + "nameLocation": "3260:6:4", + "nodeType": "VariableDeclaration", + "scope": 2757, + "src": "3252:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2674, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3252:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2677, + "mutability": "mutable", + "name": "receiver", + "nameLocation": "3284:8:4", + "nodeType": "VariableDeclaration", + "scope": 2757, + "src": "3276:16:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2676, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3276:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2679, + "mutability": "mutable", + "name": "owner", + "nameLocation": "3310:5:4", + "nodeType": "VariableDeclaration", + "scope": 2757, + "src": "3302:13:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2678, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "3302:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "3242:79:4" + }, + "returnParameters": { + "id": 2683, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2682, + "mutability": "mutable", + "name": "assets", + "nameLocation": "3354:6:4", + "nodeType": "VariableDeclaration", + "scope": 2757, + "src": "3346:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2681, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3346:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3345:16:4" + }, + "scope": 2953, + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "public" + }, + { + "id": 2762, + "nodeType": "FunctionDefinition", + "src": "4130:61:4", + "functionSelector": "01e1d114", + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "totalAssets", + "nameLocation": "4139:11:4", + "parameters": { + "id": 2758, + "nodeType": "ParameterList", + "parameters": [], + "src": "4150:2:4" + }, + "returnParameters": { + "id": 2761, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2760, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2762, + "src": "4182:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2759, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4182:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4181:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2786, + "nodeType": "FunctionDefinition", + "src": "4197:257:4", + "body": { + "id": 2785, + "nodeType": "Block", + "src": "4276:178:4", + "statements": [ + { + "assignments": [ + 2770 + ], + "declarations": [ + { + "constant": false, + "id": 2770, + "mutability": "mutable", + "name": "supply", + "nameLocation": "4294:6:4", + "nodeType": "VariableDeclaration", + "scope": 2785, + "src": "4286:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2769, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4286:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2772, + "initialValue": { + "id": 2771, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31047, + "src": "4303:11:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4286:28:4" + }, + { + "expression": { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2775, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2773, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2770, + "src": "4384:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 2774, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4394:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4384:11:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "arguments": [ + { + "id": 2779, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2770, + "src": "4425:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 2780, + "name": "totalAssets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2762, + "src": "4433:11:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 2781, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4433:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2777, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2764, + "src": "4407:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2778, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "mulDivDown", + "nodeType": "MemberAccess", + "referencedDeclaration": 32285, + "src": "4407:17:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" + } + }, + "id": 2782, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4407:40:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2783, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "4384:63:4", + "trueExpression": { + "id": 2776, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2764, + "src": "4398:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2768, + "id": 2784, + "nodeType": "Return", + "src": "4377:70:4" + } + ] + }, + "functionSelector": "c6e6f592", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "convertToShares", + "nameLocation": "4206:15:4", + "parameters": { + "id": 2765, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2764, + "mutability": "mutable", + "name": "assets", + "nameLocation": "4230:6:4", + "nodeType": "VariableDeclaration", + "scope": 2786, + "src": "4222:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2763, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4222:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4221:16:4" + }, + "returnParameters": { + "id": 2768, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2767, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2786, + "src": "4267:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2766, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4267:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4266:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2810, + "nodeType": "FunctionDefinition", + "src": "4460:257:4", + "body": { + "id": 2809, + "nodeType": "Block", + "src": "4539:178:4", + "statements": [ + { + "assignments": [ + 2794 + ], + "declarations": [ + { + "constant": false, + "id": 2794, + "mutability": "mutable", + "name": "supply", + "nameLocation": "4557:6:4", + "nodeType": "VariableDeclaration", + "scope": 2809, + "src": "4549:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2793, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4549:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2796, + "initialValue": { + "id": 2795, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31047, + "src": "4566:11:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4549:28:4" + }, + { + "expression": { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2799, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2797, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2794, + "src": "4647:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 2798, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4657:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4647:11:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "arguments": [ + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 2803, + "name": "totalAssets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2762, + "src": "4688:11:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 2804, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4688:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2805, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2794, + "src": "4703:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2801, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2788, + "src": "4670:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2802, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "mulDivDown", + "nodeType": "MemberAccess", + "referencedDeclaration": 32285, + "src": "4670:17:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" + } + }, + "id": 2806, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4670:40:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2807, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "4647:63:4", + "trueExpression": { + "id": 2800, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2788, + "src": "4661:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2792, + "id": 2808, + "nodeType": "Return", + "src": "4640:70:4" + } + ] + }, + "functionSelector": "07a2d13a", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "convertToAssets", + "nameLocation": "4469:15:4", + "parameters": { + "id": 2789, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2788, + "mutability": "mutable", + "name": "shares", + "nameLocation": "4493:6:4", + "nodeType": "VariableDeclaration", + "scope": 2810, + "src": "4485:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2787, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4485:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4484:16:4" + }, + "returnParameters": { + "id": 2792, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2791, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2810, + "src": "4530:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2790, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4530:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4529:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2822, + "nodeType": "FunctionDefinition", + "src": "4723:125:4", + "body": { + "id": 2821, + "nodeType": "Block", + "src": "4801:47:4", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 2818, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2812, + "src": "4834:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2817, + "name": "convertToShares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2786, + "src": "4818:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 2819, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "4818:23:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2816, + "id": 2820, + "nodeType": "Return", + "src": "4811:30:4" + } + ] + }, + "functionSelector": "ef8b30f7", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "previewDeposit", + "nameLocation": "4732:14:4", + "parameters": { + "id": 2813, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2812, + "mutability": "mutable", + "name": "assets", + "nameLocation": "4755:6:4", + "nodeType": "VariableDeclaration", + "scope": 2822, + "src": "4747:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2811, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4747:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4746:16:4" + }, + "returnParameters": { + "id": 2816, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2815, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2822, + "src": "4792:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2814, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4792:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4791:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2846, + "nodeType": "FunctionDefinition", + "src": "4854:251:4", + "body": { + "id": 2845, + "nodeType": "Block", + "src": "4929:176:4", + "statements": [ + { + "assignments": [ + 2830 + ], + "declarations": [ + { + "constant": false, + "id": 2830, + "mutability": "mutable", + "name": "supply", + "nameLocation": "4947:6:4", + "nodeType": "VariableDeclaration", + "scope": 2845, + "src": "4939:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2829, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4939:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2832, + "initialValue": { + "id": 2831, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31047, + "src": "4956:11:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4939:28:4" + }, + { + "expression": { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2835, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2833, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2830, + "src": "5037:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 2834, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5047:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5037:11:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "arguments": [ + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 2839, + "name": "totalAssets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2762, + "src": "5076:11:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 2840, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5076:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2841, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2830, + "src": "5091:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2837, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2824, + "src": "5060:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2838, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "mulDivUp", + "nodeType": "MemberAccess", + "referencedDeclaration": 32298, + "src": "5060:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" + } + }, + "id": 2842, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5060:38:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2843, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "5037:61:4", + "trueExpression": { + "id": 2836, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2824, + "src": "5051:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2828, + "id": 2844, + "nodeType": "Return", + "src": "5030:68:4" + } + ] + }, + "functionSelector": "b3d7f6b9", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "previewMint", + "nameLocation": "4863:11:4", + "parameters": { + "id": 2825, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2824, + "mutability": "mutable", + "name": "shares", + "nameLocation": "4883:6:4", + "nodeType": "VariableDeclaration", + "scope": 2846, + "src": "4875:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2823, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4875:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4874:16:4" + }, + "returnParameters": { + "id": 2828, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2827, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2846, + "src": "4920:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2826, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4920:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4919:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2870, + "nodeType": "FunctionDefinition", + "src": "5111:255:4", + "body": { + "id": 2869, + "nodeType": "Block", + "src": "5190:176:4", + "statements": [ + { + "assignments": [ + 2854 + ], + "declarations": [ + { + "constant": false, + "id": 2854, + "mutability": "mutable", + "name": "supply", + "nameLocation": "5208:6:4", + "nodeType": "VariableDeclaration", + "scope": 2869, + "src": "5200:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2853, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5200:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2856, + "initialValue": { + "id": 2855, + "name": "totalSupply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31047, + "src": "5217:11:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5200:28:4" + }, + { + "expression": { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2859, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2857, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2854, + "src": "5298:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 2858, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5308:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "5298:11:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "arguments": [ + { + "id": 2863, + "name": "supply", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2854, + "src": "5337:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 2864, + "name": "totalAssets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2762, + "src": "5345:11:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 2865, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5345:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2861, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2848, + "src": "5321:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "mulDivUp", + "nodeType": "MemberAccess", + "referencedDeclaration": 32298, + "src": "5321:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$bound_to$_t_uint256_$", + "typeString": "function (uint256,uint256,uint256) pure returns (uint256)" + } + }, + "id": 2866, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5321:38:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2867, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "5298:61:4", + "trueExpression": { + "id": 2860, + "name": "assets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2848, + "src": "5312:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2852, + "id": 2868, + "nodeType": "Return", + "src": "5291:68:4" + } + ] + }, + "functionSelector": "0a28a477", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "previewWithdraw", + "nameLocation": "5120:15:4", + "parameters": { + "id": 2849, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2848, + "mutability": "mutable", + "name": "assets", + "nameLocation": "5144:6:4", + "nodeType": "VariableDeclaration", + "scope": 2870, + "src": "5136:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2847, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5136:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5135:16:4" + }, + "returnParameters": { + "id": 2852, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2851, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2870, + "src": "5181:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2850, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5181:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5180:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2882, + "nodeType": "FunctionDefinition", + "src": "5372:124:4", + "body": { + "id": 2881, + "nodeType": "Block", + "src": "5449:47:4", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 2878, + "name": "shares", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2872, + "src": "5482:6:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2877, + "name": "convertToAssets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2810, + "src": "5466:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 2879, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5466:23:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2876, + "id": 2880, + "nodeType": "Return", + "src": "5459:30:4" + } + ] + }, + "functionSelector": "4cdad506", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "previewRedeem", + "nameLocation": "5381:13:4", + "parameters": { + "id": 2873, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2872, + "mutability": "mutable", + "name": "shares", + "nameLocation": "5403:6:4", + "nodeType": "VariableDeclaration", + "scope": 2882, + "src": "5395:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2871, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5395:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5394:16:4" + }, + "returnParameters": { + "id": 2876, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2875, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2882, + "src": "5440:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2874, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5440:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5439:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2896, + "nodeType": "FunctionDefinition", + "src": "5693:108:4", + "body": { + "id": 2895, + "nodeType": "Block", + "src": "5760:41:4", + "statements": [ + { + "expression": { + "expression": { + "arguments": [ + { + "id": 2891, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5782:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2890, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5782:7:4", + "typeDescriptions": {} + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + } + ], + "id": 2889, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -27, + "src": "5777:4:4", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2892, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5777:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_uint256", + "typeString": "type(uint256)" + } + }, + "id": 2893, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "max", + "nodeType": "MemberAccess", + "src": "5777:17:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2888, + "id": 2894, + "nodeType": "Return", + "src": "5770:24:4" + } + ] + }, + "functionSelector": "402d267d", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "maxDeposit", + "nameLocation": "5702:10:4", + "parameters": { + "id": 2885, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2884, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2896, + "src": "5713:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2883, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5713:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "5712:9:4" + }, + "returnParameters": { + "id": 2888, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2887, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2896, + "src": "5751:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2886, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5751:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5750:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2910, + "nodeType": "FunctionDefinition", + "src": "5807:105:4", + "body": { + "id": 2909, + "nodeType": "Block", + "src": "5871:41:4", + "statements": [ + { + "expression": { + "expression": { + "arguments": [ + { + "id": 2905, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5893:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2904, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5893:7:4", + "typeDescriptions": {} + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + } + ], + "id": 2903, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -27, + "src": "5888:4:4", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2906, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "5888:13:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_uint256", + "typeString": "type(uint256)" + } + }, + "id": 2907, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberName": "max", + "nodeType": "MemberAccess", + "src": "5888:17:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2902, + "id": 2908, + "nodeType": "Return", + "src": "5881:24:4" + } + ] + }, + "functionSelector": "c63d75b6", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "maxMint", + "nameLocation": "5816:7:4", + "parameters": { + "id": 2899, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2898, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2910, + "src": "5824:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2897, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5824:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "5823:9:4" + }, + "returnParameters": { + "id": 2902, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2901, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2910, + "src": "5862:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2900, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5862:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5861:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2924, + "nodeType": "FunctionDefinition", + "src": "5918:131:4", + "body": { + "id": 2923, + "nodeType": "Block", + "src": "5992:57:4", + "statements": [ + { + "expression": { + "arguments": [ + { + "baseExpression": { + "id": 2918, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31051, + "src": "6025:9:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 2920, + "indexExpression": { + "id": 2919, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2912, + "src": "6035:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "6025:16:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2917, + "name": "convertToAssets", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2810, + "src": "6009:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 2921, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "6009:33:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2916, + "id": 2922, + "nodeType": "Return", + "src": "6002:40:4" + } + ] + }, + "functionSelector": "ce96cb77", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "maxWithdraw", + "nameLocation": "5927:11:4", + "parameters": { + "id": 2913, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2912, + "mutability": "mutable", + "name": "owner", + "nameLocation": "5947:5:4", + "nodeType": "VariableDeclaration", + "scope": 2924, + "src": "5939:13:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2911, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5939:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "5938:15:4" + }, + "returnParameters": { + "id": 2916, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2915, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2924, + "src": "5983:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2914, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5983:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5982:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2936, + "nodeType": "FunctionDefinition", + "src": "6055:112:4", + "body": { + "id": 2935, + "nodeType": "Block", + "src": "6127:40:4", + "statements": [ + { + "expression": { + "baseExpression": { + "id": 2931, + "name": "balanceOf", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31051, + "src": "6144:9:4", + "typeDescriptions": { + "typeIdentifier": "t_mapping$_t_address_$_t_uint256_$", + "typeString": "mapping(address => uint256)" + } + }, + "id": 2933, + "indexExpression": { + "id": 2932, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2926, + "src": "6154:5:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "6144:16:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 2930, + "id": 2934, + "nodeType": "Return", + "src": "6137:23:4" + } + ] + }, + "functionSelector": "d905777e", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "maxRedeem", + "nameLocation": "6064:9:4", + "parameters": { + "id": 2927, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2926, + "mutability": "mutable", + "name": "owner", + "nameLocation": "6082:5:4", + "nodeType": "VariableDeclaration", + "scope": 2936, + "src": "6074:13:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2925, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "6074:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "6073:15:4" + }, + "returnParameters": { + "id": 2930, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2929, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2936, + "src": "6118:7:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2928, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6118:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "6117:9:4" + }, + "scope": 2953, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 2944, + "nodeType": "FunctionDefinition", + "src": "6359:75:4", + "body": { + "id": 2943, + "nodeType": "Block", + "src": "6432:2:4", + "statements": [] + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "beforeWithdraw", + "nameLocation": "6368:14:4", + "parameters": { + "id": 2941, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2938, + "mutability": "mutable", + "name": "assets", + "nameLocation": "6391:6:4", + "nodeType": "VariableDeclaration", + "scope": 2944, + "src": "6383:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2937, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6383:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2940, + "mutability": "mutable", + "name": "shares", + "nameLocation": "6407:6:4", + "nodeType": "VariableDeclaration", + "scope": 2944, + "src": "6399:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2939, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6399:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "6382:32:4" + }, + "returnParameters": { + "id": 2942, + "nodeType": "ParameterList", + "parameters": [], + "src": "6432:0:4" + }, + "scope": 2953, + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "internal" + }, + { + "id": 2952, + "nodeType": "FunctionDefinition", + "src": "6440:73:4", + "body": { + "id": 2951, + "nodeType": "Block", + "src": "6511:2:4", + "statements": [] + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "afterDeposit", + "nameLocation": "6449:12:4", + "parameters": { + "id": 2949, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2946, + "mutability": "mutable", + "name": "assets", + "nameLocation": "6470:6:4", + "nodeType": "VariableDeclaration", + "scope": 2952, + "src": "6462:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2945, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6462:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2948, + "mutability": "mutable", + "name": "shares", + "nameLocation": "6486:6:4", + "nodeType": "VariableDeclaration", + "scope": 2952, + "src": "6478:14:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2947, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6478:7:4", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "6461:32:4" + }, + "returnParameters": { + "id": 2950, + "nodeType": "ParameterList", + "parameters": [], + "src": "6511:0:4" + }, + "scope": 2953, + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "internal" + } + ], + "abstract": true, + "baseContracts": [ + { + "baseName": { + "id": 2442, + "name": "ERC20", + "nodeType": "IdentifierPath", + "referencedDeclaration": 31408, + "src": "424:5:4" + }, + "id": 2443, + "nodeType": "InheritanceSpecifier", + "src": "424:5:4" + } + ], + "canonicalName": "ERC4626", + "contractDependencies": [], + "contractKind": "contract", + "documentation": { + "id": 2441, + "nodeType": "StructuredDocumentation", + "src": "240:155:4", + "text": "@notice Minimal ERC4626 tokenized Vault implementation.\n @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)" + }, + "fullyImplemented": false, + "linearizedBaseContracts": [ + 2953, + 31408 + ], + "name": "ERC4626", + "nameLocation": "413:7:4", + "scope": 2954, + "usedErrors": [] + } + ], + "license": "AGPL-3.0-only" +} \ No newline at end of file From 8673704955106d39baa1e78c56ba20b0a3d2e69e Mon Sep 17 00:00:00 2001 From: Andrey Kuznetsov Date: Thu, 22 Dec 2022 20:25:09 +0400 Subject: [PATCH 11/40] Init devenv, gitignore .nlsp-settings (#1942) --- .gitattributes | 2 + .gitignore | 4 + .pre-commit-config.yaml | 1 + flake.lock | 271 ++++++++++++++++++++++++++++++++++++++++ flake.nix | 58 +++++++++ 5 files changed, 336 insertions(+) create mode 100644 .gitattributes create mode 120000 .pre-commit-config.yaml create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..ef6885e0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +Cargo.lock linguist-generated=true +flake.lock linguist-generated=true diff --git a/.gitignore b/.gitignore index 026535e5..02d1224d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ .vscode /.envrc .idea +.nlsp-settings +.devenv* +devenv.local.nix +.direnv diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 120000 index 00000000..70e2baf8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1 @@ +/nix/store/x0ajmrm01wvglrj88lvy0j1lvivy32g9-pre-commit-config.json \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..c438805c --- /dev/null +++ b/flake.lock @@ -0,0 +1,271 @@ +{ + "nodes": { + "devenv": { + "inputs": { + "flake-compat": "flake-compat", + "nix": "nix", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1671704144, + "narHash": "sha256-k+jPOOTeRFt1zzgb8gU+lnedbZs8dzscnlA0c29VFcQ=", + "owner": "cachix", + "repo": "devenv", + "rev": "01fd16d1fd24ec2ace19ce1f3f3ce90038d9d042", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1671690212, + "narHash": "sha256-iLWnd/lyCIULpsJcFcrpA5JilMff7vzoniEcWLggp7o=", + "owner": "nix-community", + "repo": "fenix", + "rev": "645713f090f2e40ff6b072a10b1d890e5ee6ea23", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1668681692, + "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "009399224d5e398d03b22badca40a37ac85412a1", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1671638174, + "narHash": "sha256-FeEmVix8l/HglWtRgeHOfjqEm2etvp+MLYd1C/raq3Y=", + "owner": "domenkozar", + "repo": "nix", + "rev": "51b770e985f9e1b84fb5e03a983ef1e19f18c3e9", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "relaxed-flakes", + "repo": "nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1671458120, + "narHash": "sha256-2+k/OONN4OF21TeoNjKB5sXVZv6Zvm/uEyQIW9OYCg8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e37ef84b478fa8da0ced96522adfd956fde9047a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1671271954, + "narHash": "sha256-cSvu+bnvN08sOlTBWbBrKaBHQZq8mvk8bgpt0ZJ2Snc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d513b448cc2a6da2c8803e3c197c9fc7e67b19e3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1671458120, + "narHash": "sha256-2+k/OONN4OF21TeoNjKB5sXVZv6Zvm/uEyQIW9OYCg8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e37ef84b478fa8da0ced96522adfd956fde9047a", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1671452357, + "narHash": "sha256-HqzXiQEegpRQ4VEl9pEPgHSIxhJrNJ27HfN1wOc7w2E=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "200790e9c77064c53eaf95805b013d96615ecc27", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "fenix": "fenix", + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs_2" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1671659018, + "narHash": "sha256-y3btK8GxfZG599y0Y6yfMjPs4jz72Eej9FuWUMPrB7A=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "271f7b44d3d71db2ec2d0cd1a8a59aa16f902d49", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..64a21c7b --- /dev/null +++ b/flake.nix @@ -0,0 +1,58 @@ +{ + inputs = { + devenv.url = "github:cachix/devenv"; + flake-utils.url = "github:numtide/flake-utils"; + fenix = { + url = "github:nix-community/fenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { self + , nixpkgs + , flake-utils + , fenix + , devenv + } @ inputs: + flake-utils.lib.eachDefaultSystem (system: + let pkgs = import nixpkgs { + inherit system; + }; + in + { + devShell = devenv.lib.mkShell { + inherit inputs pkgs; + + modules = [ + { + packages = with pkgs; [ + solc + ] ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk; [ + libiconv + frameworks.Security + ]); + + # https://devenv.sh/languages/ + languages.nix.enable = true; + languages.rust = { + enable = true; + version = "stable"; + packages = { + rustfmt = inputs.fenix.packages.${pkgs.system}.latest.rustfmt; + clippy = inputs.fenix.packages.${pkgs.system}.latest.clippy; + }; + }; + + # https://devenv.sh/pre-commit-hooks/ + pre-commit.hooks = { + shellcheck.enable = true; + + clippy.enable = true; + rustfmt.enable = true; + }; + } + ]; + }; + }); +} From 42dacbb9b31525264319a840d6ee2b72a57cfb6e Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 22 Dec 2022 12:56:33 -0600 Subject: [PATCH 12/40] (docs): add clippy command (#1967) --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2d925088..7c0c387f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,6 +121,7 @@ cargo check --all-features cargo +nightly fmt --all cargo build --all-features cargo test --all-features +cargo +nightly clippy --all-features ``` ### Tests From 5008006767413cb7ac5e7dcd5672a739600872b8 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 22 Dec 2022 19:57:00 +0100 Subject: [PATCH 13/40] fix: ethers-etherscan solc feature (#1965) --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index d0ec85e9..f4c2adf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,6 +86,7 @@ abigen = ["ethers-contract/abigen"] ### abigen without reqwest abigen-offline = ["ethers-contract/abigen-offline"] ## solc +ethers-solc = ["dep:ethers-solc", "ethers-etherscan/ethers-solc"] solc-full = ["ethers-solc", "ethers-solc/full"] solc-tests = ["ethers-solc", "ethers-solc/tests"] solc-sha2-asm = ["ethers-solc", "ethers-solc/asm"] From 1baf88138f60248a5ec59c178d2a74fb1d0596f6 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 22 Dec 2022 19:58:35 +0100 Subject: [PATCH 14/40] fix(etherscan): source code serde (#1962) --- ethers-etherscan/src/contract.rs | 10 +++++-- ethers-etherscan/src/utils.rs | 51 ++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/ethers-etherscan/src/contract.rs b/ethers-etherscan/src/contract.rs index ae19abf6..2b5adb23 100644 --- a/ethers-etherscan/src/contract.rs +++ b/ethers-etherscan/src/contract.rs @@ -1,6 +1,6 @@ use crate::{ source_tree::{SourceTree, SourceTreeEntry}, - utils::{deserialize_address_opt, deserialize_stringified_source_code}, + utils::{deserialize_address_opt, deserialize_source_code}, Client, EtherscanError, Response, Result, }; use ethers_core::{ @@ -107,7 +107,7 @@ impl SourceCodeMetadata { #[serde(rename_all = "PascalCase")] pub struct Metadata { /// Includes metadata for compiler settings and language. - #[serde(deserialize_with = "deserialize_stringified_source_code")] + #[serde(deserialize_with = "deserialize_source_code")] pub source_code: SourceCodeMetadata, /// The ABI of the contract. @@ -148,7 +148,11 @@ pub struct Metadata { pub proxy: u64, /// If this contract is a proxy, the address of its implementation. - #[serde(deserialize_with = "deserialize_address_opt")] + #[serde( + default, + skip_serializing_if = "Option::is_none", + deserialize_with = "deserialize_address_opt" + )] pub implementation: Option
, /// The swarm source of the contract. diff --git a/ethers-etherscan/src/utils.rs b/ethers-etherscan/src/utils.rs index b76745eb..3107492a 100644 --- a/ethers-etherscan/src/utils.rs +++ b/ethers-etherscan/src/utils.rs @@ -36,20 +36,35 @@ pub fn deserialize_address_opt<'de, D: Deserializer<'de>>( /// Deserializes as JSON: /// -/// `{ "SourceCode": "{{ .. }}", ..}` +/// Object: `{ "SourceCode": { language: "Solidity", .. }, ..}` /// /// or /// -/// `{ "SourceCode": "..", .. }` -pub fn deserialize_stringified_source_code<'de, D: Deserializer<'de>>( +/// Stringified JSON: `{ "SourceCode": "{{\r\n \"language\": \"Solidity\", ..}}", ..}` +/// +/// or +/// +/// Normal source code: `{ "SourceCode": "// SPDX-License-Identifier: ...", .. }` +pub fn deserialize_source_code<'de, D: Deserializer<'de>>( deserializer: D, ) -> std::result::Result { - let s = String::deserialize(deserializer)?; - if s.starts_with("{{") && s.ends_with("}}") { - let s = &s[1..s.len() - 1]; - serde_json::from_str(s).map_err(serde::de::Error::custom) - } else { - Ok(SourceCodeMetadata::SourceCode(s)) + #[derive(Deserialize)] + #[serde(untagged)] + enum SourceCode { + String(String), // this must come first + Obj(SourceCodeMetadata), + } + let s = SourceCode::deserialize(deserializer)?; + match s { + SourceCode::String(s) => { + if s.starts_with("{{") && s.ends_with("}}") { + let s = &s[1..s.len() - 1]; + serde_json::from_str(s).map_err(serde::de::Error::custom) + } else { + Ok(SourceCodeMetadata::SourceCode(s)) + } + } + SourceCode::Obj(obj) => Ok(obj), } } @@ -108,17 +123,29 @@ mod tests { } #[test] - fn can_deserialize_stringified_source_code() { + fn can_deserialize_source_code() { #[derive(Deserialize)] struct Test { - #[serde(deserialize_with = "deserialize_stringified_source_code")] + #[serde(deserialize_with = "deserialize_source_code")] source_code: SourceCodeMetadata, } let src = "source code text"; + // Normal JSON let json = r#"{ - "source_code": "{{ \"language\": \"Solidity\", \"sources\": {\"Contract\": { \"content\": \"source code text\" } } }}" + "source_code": { "language": "Solidity", "sources": { "Contract": { "content": "source code text" } } } + }"#; + let de: Test = serde_json::from_str(json).unwrap(); + assert!(matches!(de.source_code.language().unwrap(), SourceCodeLanguage::Solidity)); + assert_eq!(de.source_code.sources().len(), 1); + assert_eq!(de.source_code.sources().get("Contract").unwrap().content, src); + #[cfg(feature = "ethers-solc")] + assert!(matches!(de.source_code.settings().unwrap(), None)); + + // Stringified JSON + let json = r#"{ + "source_code": "{{ \"language\": \"Solidity\", \"sources\": { \"Contract\": { \"content\": \"source code text\" } } }}" }"#; let de: Test = serde_json::from_str(json).unwrap(); assert!(matches!(de.source_code.language().unwrap(), SourceCodeLanguage::Solidity)); From 73039ba264ef8de753dbd430dc8950371c58c7b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 20:58:52 +0200 Subject: [PATCH 15/40] chore(deps): bump num_cpus from 1.14.0 to 1.15.0 (#1959) --- Cargo.lock | 6 +++--- ethers-solc/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcb49656..ce4dd11a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2570,11 +2570,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi 0.2.6", "libc", ] diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index 32b0f99d..c535222a 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -31,7 +31,7 @@ hex = "0.4.3" yansi = "0.5.1" glob = "0.3.0" tracing = "0.1.37" -num_cpus = "1.14.0" +num_cpus = "1.15.0" tiny-keccak = { version = "2.0.2", default-features = false } tempfile = { version = "3.3.0", optional = true } fs_extra = { version = "1.2.0", optional = true } From 253202f96a534fbe7859b6b76d6350f64e6bc37a Mon Sep 17 00:00:00 2001 From: Sebastiano Faiella Date: Thu, 22 Dec 2022 14:59:20 -0400 Subject: [PATCH 16/40] docs(ethers-providers): fixed typos in rw client docs (#1957) --- CHANGELOG.md | 2 ++ ethers-providers/src/transports/rw.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba768abc..61aaa329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ ## ethers-core ### Unreleased + - +- Fix typo in `RwClient` docs for `write_client` method. - Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815) - `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers. - An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract. diff --git a/ethers-providers/src/transports/rw.rs b/ethers-providers/src/transports/rw.rs index f54a96eb..58499d20 100644 --- a/ethers-providers/src/transports/rw.rs +++ b/ethers-providers/src/transports/rw.rs @@ -9,7 +9,7 @@ use serde::{de::DeserializeOwned, Serialize}; use thiserror::Error; -/// A client contains two clients. +/// A client containing two clients. /// /// One is used for _read_ operations /// One is used for _write_ operations that consume gas `["eth_sendTransaction", @@ -48,7 +48,7 @@ impl RwClient { &self.r } - /// Returns the client used for read operations + /// Returns the client used for write operations pub fn write_client(&self) -> &Write { &self.w } From bfb919a5bf7061c2bf6ae241ff7e1ef414b7ce98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 20:59:44 +0200 Subject: [PATCH 17/40] chore(deps): bump serial_test from 0.9.0 to 0.10.0 (#1954) --- Cargo.lock | 9 ++++----- ethers-etherscan/Cargo.toml | 2 +- ethers-middleware/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce4dd11a..35a81ccd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3772,9 +3772,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92761393ee4dc3ff8f4af487bd58f4307c9329bbedea02cac0089ad9c411e153" +checksum = "1c789ec87f4687d022a2405cf46e0cd6284889f1839de292cadeb6c6019506f2" dependencies = [ "dashmap", "futures", @@ -3786,11 +3786,10 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6f5d1c3087fb119617cff2966fe3808a80e5eb59a8c1601d5994d66f4346a5" +checksum = "b64f9e531ce97c88b4778aad0ceee079216071cffec6ac9b904277f8f92e7fe3" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", "syn", diff --git a/ethers-etherscan/Cargo.toml b/ethers-etherscan/Cargo.toml index a6f71c6b..e9ff87d8 100644 --- a/ethers-etherscan/Cargo.toml +++ b/ethers-etherscan/Cargo.toml @@ -35,7 +35,7 @@ getrandom = { version = "0.2", features = ["js"] } [dev-dependencies] tempfile = "3.3.0" tokio = { version = "1.18", features = ["macros", "rt-multi-thread", "time"] } -serial_test = "0.9.0" +serial_test = "0.10.0" tracing-subscriber = { version = "0.3", default-features = false, features = ["env-filter", "fmt"] } ethers-solc = { version = "^1.0.0", path = "../ethers-solc", default-features = false } diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml index 0dc3e9d9..87d9b62a 100644 --- a/ethers-middleware/Cargo.toml +++ b/ethers-middleware/Cargo.toml @@ -49,7 +49,7 @@ ethers-providers = { version = "^1.0.0", path = "../ethers-providers", default-f ] } once_cell = "1.16.0" ethers-solc = { version = "^1.0.0", path = "../ethers-solc" } -serial_test = "0.9.0" +serial_test = "0.10.0" reqwest = { version = "0.11.13", default-features = false, features = ["json", "rustls"] } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] From 6bb5abb2fd4f6208cea8b1823e09ec1bd94b7d21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 21:00:10 +0200 Subject: [PATCH 18/40] chore(deps): bump syn from 1.0.105 to 1.0.107 (#1953) --- Cargo.lock | 4 ++-- ethers-core/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35a81ccd..c9015d65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4065,9 +4065,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml index f2c67a0e..4f32c3cd 100644 --- a/ethers-core/Cargo.toml +++ b/ethers-core/Cargo.toml @@ -40,7 +40,7 @@ cargo_metadata = { version = "0.15.2", optional = true } # eip712 feature enabled dependencies convert_case = { version = "0.6.0", optional = true } -syn = { version = "1.0.105", optional = true } +syn = { version = "1.0.107", optional = true } proc-macro2 = { version = "1.0.47", optional = true } num_enum = "0.5.7" From 3e685aaedeb8218ada619ca5f761f5564f9482f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 21:00:18 +0200 Subject: [PATCH 19/40] chore(deps): bump semver from 1.0.14 to 1.0.16 (#1952) --- Cargo.lock | 4 ++-- ethers-etherscan/Cargo.toml | 2 +- ethers-signers/Cargo.toml | 2 +- ethers-solc/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9015d65..6a4444a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3674,9 +3674,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" dependencies = [ "serde", ] diff --git a/ethers-etherscan/Cargo.toml b/ethers-etherscan/Cargo.toml index e9ff87d8..abea9a1e 100644 --- a/ethers-etherscan/Cargo.toml +++ b/ethers-etherscan/Cargo.toml @@ -26,7 +26,7 @@ serde_json = { version = "1.0.64", default-features = false } serde-aux = { version = "4.1.2", default-features = false } thiserror = "1.0" tracing = "0.1.37" -semver = "1.0.14" +semver = "1.0.16" [target.'cfg(target_arch = "wasm32")'.dependencies] # NOTE: this enables wasm compatibility for getrandom indirectly diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml index 96915bf4..21563063 100644 --- a/ethers-signers/Cargo.toml +++ b/ethers-signers/Cargo.toml @@ -28,7 +28,7 @@ rand = { version = "0.8.5", default-features = false } yubihsm = { version = "0.41.0", features = ["secp256k1", "http", "usb"], optional = true } futures-util = { version = "^0.3", optional = true } futures-executor = { version = "^0.3", optional = true } -semver = { version = "1.0.14", optional = true } +semver = { version = "1.0.16", optional = true } trezor-client = { version = "0.0.7", optional = true, default-features = false, features = [ "f_ethereum", ] } diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index c535222a..52a85ed0 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -19,7 +19,7 @@ keywords = ["ethereum", "web3", "solc", "solidity", "ethers"] ethers-core = { version = "^1.0.0", path = "../ethers-core", default-features = false } serde_json = "1.0.68" serde = { version = "1.0.130", features = ["derive"] } -semver = { version = "1.0.14", features = ["serde"] } +semver = { version = "1.0.16", features = ["serde"] } walkdir = "2.3.2" tokio = { version = "1.18", default-features = false, features = ["rt"] } futures-util = { version = "^0.3", optional = true } From 0cc6be4f5c8d3301e891824a0ef98c5e7624352e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 21:00:36 +0200 Subject: [PATCH 20/40] chore(deps): bump thiserror from 1.0.37 to 1.0.38 (#1950) --- Cargo.lock | 8 ++++---- ethers-signers/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a4444a0..db539211 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4153,18 +4153,18 @@ checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml index 21563063..02c2bab1 100644 --- a/ethers-signers/Cargo.toml +++ b/ethers-signers/Cargo.toml @@ -16,7 +16,7 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] ethers-core = { version = "^1.0.0", path = "../ethers-core", features = ["eip712"] } -thiserror = { version = "1.0.37", default-features = false } +thiserror = { version = "1.0.38", default-features = false } coins-bip32 = "0.7.0" coins-bip39 = "0.7.0" coins-ledger = { version = "0.7.0", default-features = false, optional = true } From d8d4eac3ad3b867c0e9923b8a6f0dd63379396e7 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 22 Dec 2022 20:05:00 +0100 Subject: [PATCH 21/40] fix(contract): add setter for MultiBindings' rustfmt (#1948) --- .../ethers-contract-abigen/src/multi.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ethers-contract/ethers-contract-abigen/src/multi.rs b/ethers-contract/ethers-contract-abigen/src/multi.rs index f4bd7837..a0c4a21d 100644 --- a/ethers-contract/ethers-contract-abigen/src/multi.rs +++ b/ethers-contract/ethers-contract-abigen/src/multi.rs @@ -31,6 +31,12 @@ impl std::ops::Deref for MultiAbigen { } } +impl std::ops::DerefMut for MultiAbigen { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.abigens + } +} + impl From> for MultiAbigen { fn from(abigens: Vec) -> Self { Self { abigens } @@ -372,6 +378,16 @@ impl MultiBindings { self.expansion.contracts.is_empty() } + /// Specify whether or not to format the code using a locally installed copy + /// of `rustfmt`. + /// + /// Note that in case `rustfmt` does not exist or produces an error, the + /// unformatted code will be used. + pub fn rustfmt(mut self, rustfmt: bool) -> Self { + self.rustfmt = rustfmt; + self + } + fn into_inner(self, single_file: bool) -> MultiBindingsInner { self.expansion.into_bindings(single_file, self.rustfmt) } From 612cce016cb90de049495bb3c23c360787beb4b1 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 23 Dec 2022 11:37:23 +0100 Subject: [PATCH 22/40] fix: reexport some ast types again (#1968) --- ethers-solc/src/artifacts/ast/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethers-solc/src/artifacts/ast/mod.rs b/ethers-solc/src/artifacts/ast/mod.rs index 928bd002..e2f7382f 100644 --- a/ethers-solc/src/artifacts/ast/mod.rs +++ b/ethers-solc/src/artifacts/ast/mod.rs @@ -19,7 +19,7 @@ pub mod visitor; /// A low fidelity representation of the AST. pub(crate) mod lowfidelity; -pub use lowfidelity::Ast; +pub use lowfidelity::{Ast, Node, NodeType}; /// Types for the Yul AST. /// From 5bbc7524c01098b0e9728dd3ce8a38e910bac12a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 23 Dec 2022 12:56:51 +0100 Subject: [PATCH 23/40] chore: rm broken pre commit yaml (#1972) --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) delete mode 120000 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 120000 index 70e2baf8..00000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1 +0,0 @@ -/nix/store/x0ajmrm01wvglrj88lvy0j1lvivy32g9-pre-commit-config.json \ No newline at end of file From 8a5b3cc6c95eb31fa7530117b9860e3fa52e5e0f Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 23 Dec 2022 13:58:02 +0100 Subject: [PATCH 24/40] fix: reexport SourceLocation (#1971) --- ethers-solc/src/artifacts/ast/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethers-solc/src/artifacts/ast/mod.rs b/ethers-solc/src/artifacts/ast/mod.rs index e2f7382f..82e01a2b 100644 --- a/ethers-solc/src/artifacts/ast/mod.rs +++ b/ethers-solc/src/artifacts/ast/mod.rs @@ -19,7 +19,7 @@ pub mod visitor; /// A low fidelity representation of the AST. pub(crate) mod lowfidelity; -pub use lowfidelity::{Ast, Node, NodeType}; +pub use lowfidelity::{Ast, Node, NodeType, SourceLocation as LowFidelitySourceLocation}; /// Types for the Yul AST. /// From 2e3252829285eb59c4eafd21a08d705705dbdfa2 Mon Sep 17 00:00:00 2001 From: Andrey Kuznetsov Date: Sun, 25 Dec 2022 14:20:42 +0400 Subject: [PATCH 25/40] chore: gitignore .pre-commit-config.yaml (#1973) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 02d1224d..30620b95 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ .devenv* devenv.local.nix .direnv +.pre-commit-config.yaml From b27c7b0773d7ba329e0e1eebb37db652ac8fa601 Mon Sep 17 00:00:00 2001 From: Vid Kersic <38610409+Vid201@users.noreply.github.com> Date: Sun, 25 Dec 2022 12:33:05 +0100 Subject: [PATCH 26/40] feat: debug_traceCall (#1949) * feat: debug_traceCall * chore: update changelog * fix: rebase to master and change tracer from string to enum --- CHANGELOG.md | 2 +- ethers-core/src/types/trace/geth.rs | 31 ++++++++++++++++++++++++++--- ethers-middleware/Cargo.toml | 2 +- ethers-providers/src/lib.rs | 11 ++++++++++ ethers-providers/src/provider.rs | 21 ++++++++++++++++--- examples/geth_trace_call.rs | 26 ++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 examples/geth_trace_call.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 61aaa329..2a623363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ ### Unreleased -- - Fix typo in `RwClient` docs for `write_client` method. +- Add support for Geth `debug_traceCall` [#1949](https://github.com/gakonst/ethers-rs/pull/1949) - Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815) - `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers. - An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract. diff --git a/ethers-core/src/types/trace/geth.rs b/ethers-core/src/types/trace/geth.rs index d18632c9..c346a299 100644 --- a/ethers-core/src/types/trace/geth.rs +++ b/ethers-core/src/types/trace/geth.rs @@ -1,4 +1,7 @@ -use crate::types::{Bytes, H256, U256}; +use crate::{ + types::{Bytes, H256, U256}, + utils::from_int_or_hex, +}; use serde::{Deserialize, Serialize, Serializer}; use std::collections::BTreeMap; @@ -6,7 +9,8 @@ use std::collections::BTreeMap; #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct GethTrace { pub failed: bool, - pub gas: u64, + #[serde(deserialize_with = "from_int_or_hex")] + pub gas: U256, #[serde(serialize_with = "serialize_bytes", rename = "returnValue")] pub return_value: Bytes, #[serde(rename = "structLogs")] @@ -35,6 +39,16 @@ pub struct StructLog { pub storage: Option>, } +#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] +/// Available built-in tracers +/// +/// See +pub enum GethDebugTracerType { + /// callTracer (native) + #[serde(rename = "callTracer")] + CallTracer, +} + /// Bindings for additional `debug_traceTransaction` options /// /// See @@ -50,11 +64,22 @@ pub struct GethDebugTracingOptions { #[serde(default, skip_serializing_if = "Option::is_none")] pub enable_return_data: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub tracer: Option, + pub tracer: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub timeout: Option, } +/// Bindings for additional `debug_traceCall` options +/// +/// See +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct GethDebugTracingCallOptions { + #[serde(flatten)] + pub tracing_options: GethDebugTracingOptions, + // TODO: Add stateoverrides and blockoverrides options +} + fn serialize_bytes(x: T, s: S) -> Result where S: Serializer, diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml index 87d9b62a..2518a21d 100644 --- a/ethers-middleware/Cargo.toml +++ b/ethers-middleware/Cargo.toml @@ -31,7 +31,7 @@ tracing = { version = "0.1.37", default-features = false } tracing-futures = { version = "0.2.5", default-features = false } # for gas oracles -reqwest = { version = "0.11.13", default-features = false, features = ["json"] } +reqwest = { version = "0.11.13", default-features = false, features = ["json", "rustls-tls"] } url = { version = "2.3.1", default-features = false } serde_json = { version = "1.0.64", default-features = false } diff --git a/ethers-providers/src/lib.rs b/ethers-providers/src/lib.rs index 2c0ba7f6..b7825682 100644 --- a/ethers-providers/src/lib.rs +++ b/ethers-providers/src/lib.rs @@ -540,6 +540,7 @@ pub trait Middleware: Sync + Send + Debug { } // Geth `trace` support + /// After replaying any previous transactions in the same block, /// Replays a transaction, returning the traces configured with passed options async fn debug_trace_transaction( @@ -550,6 +551,16 @@ pub trait Middleware: Sync + Send + Debug { self.inner().debug_trace_transaction(tx_hash, trace_options).await.map_err(FromErr::from) } + /// Executes the given call and returns a number of possible traces for it + async fn debug_trace_call + Send + Sync>( + &self, + req: T, + block: Option, + trace_options: GethDebugTracingCallOptions, + ) -> Result { + self.inner().debug_trace_call(req, block, trace_options).await.map_err(FromErr::from) + } + // Parity `trace` support /// Executes the given call and returns a number of possible traces for it diff --git a/ethers-providers/src/provider.rs b/ethers-providers/src/provider.rs index 71cf41ce..cde771cc 100644 --- a/ethers-providers/src/provider.rs +++ b/ethers-providers/src/provider.rs @@ -22,9 +22,10 @@ use ethers_core::{ types::{ transaction::{eip2718::TypedTransaction, eip2930::AccessListWithGasUsed}, Address, Block, BlockId, BlockNumber, BlockTrace, Bytes, EIP1186ProofResponse, FeeHistory, - Filter, FilterBlockOption, GethDebugTracingOptions, GethTrace, Log, NameOrAddress, - Selector, Signature, Trace, TraceFilter, TraceType, Transaction, TransactionReceipt, - TransactionRequest, TxHash, TxpoolContent, TxpoolInspect, TxpoolStatus, H256, U256, U64, + Filter, FilterBlockOption, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, + Log, NameOrAddress, Selector, Signature, Trace, TraceFilter, TraceType, Transaction, + TransactionReceipt, TransactionRequest, TxHash, TxpoolContent, TxpoolInspect, TxpoolStatus, + H256, U256, U64, }, utils, }; @@ -1048,6 +1049,20 @@ impl Middleware for Provider

{ self.request("debug_traceTransaction", [tx_hash, trace_options]).await } + /// Executes the given call and returns a number of possible traces for it + async fn debug_trace_call + Send + Sync>( + &self, + req: T, + block: Option, + trace_options: GethDebugTracingCallOptions, + ) -> Result { + let req = req.into(); + let req = utils::serialize(&req); + let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into())); + let trace_options = utils::serialize(&trace_options); + self.request("debug_traceCall", [req, block, trace_options]).await + } + /// Executes the given call and returns a number of possible traces for it async fn trace_call + Send + Sync>( &self, diff --git a/examples/geth_trace_call.rs b/examples/geth_trace_call.rs new file mode 100644 index 00000000..00851951 --- /dev/null +++ b/examples/geth_trace_call.rs @@ -0,0 +1,26 @@ +use ethers::prelude::*; +use eyre::Result; +use std::str::FromStr; + +/// use `debug_traceCall` to fetch traces +/// requires, a valid endpoint in `RPC_URL` env var that supports `debug_traceCall` +#[tokio::main] +async fn main() -> Result<()> { + if let Ok(url) = std::env::var("RPC_URL") { + let client = Provider::::try_from(url)?; + let tx = TransactionRequest::new().from(Address::from_str("0xdeadbeef29292929192939494959594933929292").unwrap()).to(Address::from_str("0xde929f939d939d393f939393f93939f393929023").unwrap()).gas("0x7a120").data(Bytes::from_str("0xf00d4b5d00000000000000000000000001291230982139282304923482304912923823920000000000000000000000001293123098123928310239129839291010293810").unwrap()); + let block = BlockId::from(16213100); + let options: GethDebugTracingCallOptions = GethDebugTracingCallOptions { + tracing_options: GethDebugTracingOptions { + disable_storage: Some(true), + enable_memory: Some(false), + tracer: Some(GethDebugTracerType::CallTracer), + ..Default::default() + }, + }; + let traces = client.debug_trace_call(tx, Some(block), options).await?; + println!("{traces:?}"); + } + + Ok(()) +} From ea6d058bbcccd1cbcab3e162f625cf7185d930f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 25 Dec 2022 13:53:32 +0200 Subject: [PATCH 27/40] chore(deps): bump proc-macro2 from 1.0.47 to 1.0.49 (#1951) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.47 to 1.0.49. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.47...1.0.49) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- ethers-core/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db539211..3d785d16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3109,9 +3109,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml index 4f32c3cd..fbf0e92d 100644 --- a/ethers-core/Cargo.toml +++ b/ethers-core/Cargo.toml @@ -41,7 +41,7 @@ cargo_metadata = { version = "0.15.2", optional = true } # eip712 feature enabled dependencies convert_case = { version = "0.6.0", optional = true } syn = { version = "1.0.107", optional = true } -proc-macro2 = { version = "1.0.47", optional = true } +proc-macro2 = { version = "1.0.49", optional = true } num_enum = "0.5.7" [dev-dependencies] From 799f752e55e80aa8d6357321d4f5f7ebf66daa8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 25 Dec 2022 13:53:42 +0200 Subject: [PATCH 28/40] chore(deps): bump serde_path_to_error from 0.1.8 to 0.1.9 (#1969) Bumps [serde_path_to_error](https://github.com/dtolnay/path-to-error) from 0.1.8 to 0.1.9. - [Release notes](https://github.com/dtolnay/path-to-error/releases) - [Commits](https://github.com/dtolnay/path-to-error/compare/0.1.8...0.1.9) --- updated-dependencies: - dependency-name: serde_path_to_error dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- ethers-solc/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d785d16..0121253b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3751,9 +3751,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "184c643044780f7ceb59104cef98a5a6f12cb2288a7bc701ab93a362b49fd47d" +checksum = "26b04f22b563c91331a10074bda3dd5492e3cc39d56bd557e91c0af42b6c7341" dependencies = [ "serde", ] diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index 52a85ed0..66002fd5 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -62,7 +62,7 @@ rand = "0.8.5" pretty_assertions = "1.3.0" tempfile = "3.3.0" tokio = { version = "1.18", features = ["full"] } -serde_path_to_error = "0.1.8" +serde_path_to_error = "0.1.9" [[bench]] name = "compile_many" From e26ede21f1044c61e28a1b50c1e332320a0cc409 Mon Sep 17 00:00:00 2001 From: James Prestwich <10149425+prestwich@users.noreply.github.com> Date: Wed, 28 Dec 2022 20:05:08 -0500 Subject: [PATCH 29/40] fix: don't override user-set 1559 attributes (#1980) * fix: don't override user-set 1559 attributes * fix: enforce cap on prioirity fee per gas --- ethers-providers/src/provider.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ethers-providers/src/provider.rs b/ethers-providers/src/provider.rs index cde771cc..97d5a995 100644 --- a/ethers-providers/src/provider.rs +++ b/ethers-providers/src/provider.rs @@ -352,8 +352,19 @@ impl Middleware for Provider

{ if inner.max_fee_per_gas.is_none() || inner.max_priority_fee_per_gas.is_none() { let (max_fee_per_gas, max_priority_fee_per_gas) = self.estimate_eip1559_fees(None).await?; - inner.max_fee_per_gas = Some(max_fee_per_gas); - inner.max_priority_fee_per_gas = Some(max_priority_fee_per_gas); + // we want to avoid overriding the user if either of these + // are set. In order to do this, we refuse to override the + // `max_fee_per_gas` if already set. + // However, we must preserve the constraint that the tip + // cannot be higher than max fee, so we override user + // intent if that is so. We override by + // - first: if set, set to the min(current value, MFPG) + // - second, if still unset, use the RPC estimated amount + let mfpg = inner.max_fee_per_gas.get_or_insert(max_fee_per_gas); + inner + .max_priority_fee_per_gas + .map(|tip| std::cmp::min(tip, *mfpg)) + .get_or_insert(max_priority_fee_per_gas); }; } } From 10310ce3ad8562476196e9ec06f78c2a27417739 Mon Sep 17 00:00:00 2001 From: Andrea Simeoni Date: Thu, 29 Dec 2022 13:53:11 +0100 Subject: [PATCH 30/40] refactor: examples (#1940) * ToC * Big numbers section * Middleware examples: builder * Middleware examples: gas_escalator * Middleware examples: gas_oracle * Middleware examples: signer * Middleware examples: missing stubs * review: applied DaniPopes suggestions to big numbers * typo * Middleware examples: nonce_manager * cargo +nightly fmt * update roadmap * Middleware examples: policy * Middleware examples: added docs * Contracts examples: created folder; included abigen example * Contracts examples: refactor abigen docs. Fixed cargo example reference * Contracts examples: contract_events; minor docs changes * Moved each example under its own crate. Cargo builds locally TODO: Fix broken examples CI * Big numbers examples: used regular operators for math * Single examples run correctly (missing overall CI execution) Example crates dependencies Removed duplicates * review: Applied gakonst note to remove commented items in workspace manifest * review: Applied gakonst note to restore visibility on contract constructor * ci: - Run/Build examples in a single step to avoid duplicated scripts - Removed ci.yaml step "Build all examples" * cargo +nightly fmt * ci: fix WASM step error * Removed deprecated EthGasStation example * WASM example uses local copy of `contract_abi.json`. In this way we keep the WASM example auto-consistent, at the cost of a small duplication * Cargo.lock aligned to master branch * Removed useless comments in examples * review: Applied gakonst note to add panic!() on the policy middleware example * review: Applied gakonst suggestion to add a custom middleware example * typos in docs * Update examples/big-numbers/examples/bn_math_operations.rs review: Accepted commit suggested by DaniPopes Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> * review: Applied DaniPopes suggestion on assert_eq! * Update examples/big-numbers/README.md review: Accepted DaniPopes suggestion on big-numbers docs Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> * review: All imports now reference the "ethers" crate * ci: added features ["ws", "rustls"] where needed cargo +nigthly fmt * Examples with special features (e.g. ipc, trezor etc.) are built alongside them. This is expressed as a "default" requirement in their respective Cargo.toml * cargo +nightly fmt * Examples: Gas oracle API keys from env Added missing features in middleware Cargo.toml * typo: use expect() instead of unwrap() * Updated ToC Moved 2 examples under more relevant folders * Gas oracle examples raise panic on middleware errors * review: removed useless [[example]] in Cargo.toml * review: removed #[allow(unused_must_use)] from gas_escalator example * review: Removed prefixes from file names * review: removed useless [[example]] in Cargo.toml * docs: Updated description to run examples in the workspace README.md Co-authored-by: Andrea Simeoni <> Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> --- .github/workflows/ci.yml | 27 +-- Cargo.lock | 105 ++++++++++++ Cargo.toml | 62 +------ README.md | 7 +- examples/README.md | 81 +++++++++ examples/anvil/Cargo.toml | 10 ++ examples/anvil/README.md | 0 examples/{ => anvil/examples}/anvil_fork.rs | 3 +- examples/big-numbers/Cargo.toml | 10 ++ examples/big-numbers/README.md | 7 + .../examples/comparison_equivalence.rs | 32 ++++ examples/big-numbers/examples/conversion.rs | 23 +++ .../big-numbers/examples/create_instances.rs | 47 ++++++ .../big-numbers/examples/math_operations.rs | 49 ++++++ examples/big-numbers/examples/utilities.rs | 92 +++++++++++ examples/contracts/Cargo.toml | 19 +++ examples/contracts/README.md | 39 +++++ examples/contracts/examples/abi/IERC20.json | 153 +++++++++++++++++ .../examples/abi}/contract_abi.json | 0 examples/contracts/examples/abigen.rs | 77 +++++++++ .../examples/compile.rs} | 9 +- .../examples/contracts}/contract.sol | 1 + .../examples/deploy_anvil.rs} | 11 +- .../examples/deploy_from_abi_and_bytecode.rs} | 8 +- .../examples/deploy_from_solidity.rs} | 15 +- .../examples/deploy_moonbeam.rs} | 6 +- examples/contracts/examples/events.rs | 68 ++++++++ .../examples/events_with_meta.rs} | 13 +- examples/contracts/examples/instances.rs | 2 + examples/contracts/examples/methods.rs | 2 + .../examples/methods_abi_and_structs.rs} | 14 +- examples/ethers-wasm/abi/contract_abi.json | 1 + examples/ethers-wasm/src/lib.rs | 2 +- .../ethers-wasm/tests/contract_with_abi.rs | 2 +- examples/events/Cargo.toml | 13 ++ examples/events/README.md | 0 examples/events/examples/placeholder.rs | 2 + examples/middleware/Cargo.toml | 15 ++ examples/middleware/README.md | 0 examples/middleware/examples/builder.rs | 58 +++++++ .../examples/create_custom_middleware.rs | 156 ++++++++++++++++++ examples/middleware/examples/gas_escalator.rs | 59 +++++++ examples/middleware/examples/gas_oracle.rs | 88 ++++++++++ examples/middleware/examples/nonce_manager.rs | 46 ++++++ examples/middleware/examples/policy.rs | 39 +++++ examples/middleware/examples/signer.rs | 40 +++++ examples/middleware/examples/timelag.rs | 2 + examples/middleware/examples/transformer.rs | 2 + examples/providers/Cargo.toml | 17 ++ examples/providers/README.md | 0 examples/{ => providers/examples}/ipc.rs | 0 examples/{ => providers/examples}/quorum.rs | 8 +- examples/{ => providers/examples}/rw.rs | 8 +- examples/queries/Cargo.toml | 13 ++ examples/queries/README.md | 0 .../{ => queries/examples}/paginated_logs.rs | 10 +- .../examples/uniswapv2_pair.rs} | 6 +- examples/subscribe_contract_events.rs | 38 ----- examples/subscriptions/Cargo.toml | 13 ++ examples/subscriptions/README.md | 0 .../examples}/subscribe_events_by_type.rs | 11 +- .../examples}/subscribe_logs.rs | 10 +- .../examples}/watch_blocks.rs | 11 +- examples/transactions/Cargo.toml | 13 ++ examples/transactions/README.md | 0 .../examples}/call_override.rs | 15 +- .../examples/decode_input.rs} | 5 +- examples/{ => transactions/examples}/ens.rs | 6 +- .../examples}/gas_price_usd.rs | 10 +- .../examples}/remove_liquidity.rs | 11 +- .../examples/trace.rs} | 5 +- .../examples}/transfer_eth.rs | 5 +- examples/wallets/Cargo.toml | 20 +++ examples/wallets/README.md | 0 examples/{ => wallets/examples}/ledger.rs | 0 .../{ => wallets/examples}/local_signer.rs | 7 +- examples/{ => wallets/examples}/mnemonic.rs | 8 +- .../{ => wallets/examples}/permit_hash.rs | 6 +- .../examples/sign_message.rs} | 4 +- examples/{ => wallets/examples}/trezor.rs | 0 examples/{ => wallets/examples}/yubi.rs | 0 scripts/examples.sh | 53 ++++-- 82 files changed, 1623 insertions(+), 207 deletions(-) create mode 100644 examples/README.md create mode 100644 examples/anvil/Cargo.toml create mode 100644 examples/anvil/README.md rename examples/{ => anvil/examples}/anvil_fork.rs (88%) create mode 100644 examples/big-numbers/Cargo.toml create mode 100644 examples/big-numbers/README.md create mode 100644 examples/big-numbers/examples/comparison_equivalence.rs create mode 100644 examples/big-numbers/examples/conversion.rs create mode 100644 examples/big-numbers/examples/create_instances.rs create mode 100644 examples/big-numbers/examples/math_operations.rs create mode 100644 examples/big-numbers/examples/utilities.rs create mode 100644 examples/contracts/Cargo.toml create mode 100644 examples/contracts/README.md create mode 100644 examples/contracts/examples/abi/IERC20.json rename examples/{ => contracts/examples/abi}/contract_abi.json (100%) create mode 100644 examples/contracts/examples/abigen.rs rename examples/{abigen.rs => contracts/examples/compile.rs} (77%) rename examples/{ => contracts/examples/contracts}/contract.sol (93%) rename examples/{contract_human_readable.rs => contracts/examples/deploy_anvil.rs} (90%) rename examples/{contract_with_abi_and_bytecode.rs => contracts/examples/deploy_from_abi_and_bytecode.rs} (89%) rename examples/{contract_with_abi.rs => contracts/examples/deploy_from_solidity.rs} (85%) rename examples/{moonbeam_with_abi.rs => contracts/examples/deploy_moonbeam.rs} (95%) create mode 100644 examples/contracts/examples/events.rs rename examples/{subscribe_contract_events_with_meta.rs => contracts/examples/events_with_meta.rs} (80%) create mode 100644 examples/contracts/examples/instances.rs create mode 100644 examples/contracts/examples/methods.rs rename examples/{contract_with_abi_and_structs.rs => contracts/examples/methods_abi_and_structs.rs} (82%) create mode 100644 examples/ethers-wasm/abi/contract_abi.json create mode 100644 examples/events/Cargo.toml create mode 100644 examples/events/README.md create mode 100644 examples/events/examples/placeholder.rs create mode 100644 examples/middleware/Cargo.toml create mode 100644 examples/middleware/README.md create mode 100644 examples/middleware/examples/builder.rs create mode 100644 examples/middleware/examples/create_custom_middleware.rs create mode 100644 examples/middleware/examples/gas_escalator.rs create mode 100644 examples/middleware/examples/gas_oracle.rs create mode 100644 examples/middleware/examples/nonce_manager.rs create mode 100644 examples/middleware/examples/policy.rs create mode 100644 examples/middleware/examples/signer.rs create mode 100644 examples/middleware/examples/timelag.rs create mode 100644 examples/middleware/examples/transformer.rs create mode 100644 examples/providers/Cargo.toml create mode 100644 examples/providers/README.md rename examples/{ => providers/examples}/ipc.rs (100%) rename examples/{ => providers/examples}/quorum.rs (85%) rename examples/{ => providers/examples}/rw.rs (76%) create mode 100644 examples/queries/Cargo.toml create mode 100644 examples/queries/README.md rename examples/{ => queries/examples}/paginated_logs.rs (84%) rename examples/{uniswapv2.rs => queries/examples/uniswapv2_pair.rs} (91%) delete mode 100644 examples/subscribe_contract_events.rs create mode 100644 examples/subscriptions/Cargo.toml create mode 100644 examples/subscriptions/README.md rename examples/{ => subscriptions/examples}/subscribe_events_by_type.rs (82%) rename examples/{ => subscriptions/examples}/subscribe_logs.rs (82%) rename examples/{ => subscriptions/examples}/watch_blocks.rs (58%) create mode 100644 examples/transactions/Cargo.toml create mode 100644 examples/transactions/README.md rename examples/{ => transactions/examples}/call_override.rs (90%) rename examples/{decode_tx_input.rs => transactions/examples/decode_input.rs} (94%) rename examples/{ => transactions/examples}/ens.rs (87%) rename examples/{ => transactions/examples}/gas_price_usd.rs (92%) rename examples/{ => transactions/examples}/remove_liquidity.rs (92%) rename examples/{geth_trace_transaction.rs => transactions/examples/trace.rs} (85%) rename examples/{ => transactions/examples}/transfer_eth.rs (90%) create mode 100644 examples/wallets/Cargo.toml create mode 100644 examples/wallets/README.md rename examples/{ => wallets/examples}/ledger.rs (100%) rename examples/{ => wallets/examples}/local_signer.rs (84%) rename examples/{ => wallets/examples}/mnemonic.rs (87%) rename examples/{ => wallets/examples}/permit_hash.rs (89%) rename examples/{sign.rs => wallets/examples/sign_message.rs} (91%) rename examples/{ => wallets/examples}/trezor.rs (100%) rename examples/{ => wallets/examples}/yubi.rs (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bcfaa4ba..16d62793 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -232,32 +232,7 @@ jobs: - uses: Swatinem/rust-cache@v1 with: cache-on-failure: true - - name: Build all examples - run: | - export PATH=$HOME/bin:$PATH - examples=$(cargo metadata --format-version 1 | \ - jq -c '.packages[] - | select(.name == "ethers") - | .targets[] - | select(.kind[] | contains("example")) - | with_entries(select([.key] - | inside(["name", "required-features"])))' - ) - for example in $examples; do - name="$(echo "$example" | jq -r '.name')" - args=( - -p ethers - --example "$name" - ) - features="$(echo "$example" | jq -r 'try(."required-features" | join(","))')" - if [[ ! -z "$features" ]]; then - args+=(--features "$features") - fi - - echo "building $name" - cargo build "${args[@]}" - done - - name: Run all examples + - name: Build and run all examples run: | export PATH=$HOME/bin:$PATH chmod +x ./scripts/examples.sh diff --git a/Cargo.lock b/Cargo.lock index 0121253b..bbb66218 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1627,6 +1627,111 @@ dependencies = [ "wee_alloc", ] +[[package]] +name = "examples-anvil" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "tokio", +] + +[[package]] +name = "examples-big-numbers" +version = "1.0.2" +dependencies = [ + "ethers", +] + +[[package]] +name = "examples-contracts" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "examples-events" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "examples-middleware" +version = "1.0.2" +dependencies = [ + "async-trait", + "ethers", + "eyre", + "serde_json", + "thiserror", + "tokio", +] + +[[package]] +name = "examples-providers" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "examples-queries" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "examples-subscriptions" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "examples-transactions" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "examples-wallets" +version = "1.0.2" +dependencies = [ + "ethers", + "eyre", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "eyre" version = "0.6.8" diff --git a/Cargo.toml b/Cargo.toml index f4c2adf4..45c2d1d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,8 @@ members = [ "ethers-middleware", "ethers-etherscan", "ethers-solc", - "examples/ethers-wasm", + # Example crates + "examples/*", ] default-members = [ @@ -128,62 +129,3 @@ bytes = "1.3.0" # Tell `rustc` to optimize for small code size. opt-level = "s" -[[example]] -name = "abigen" -path = "examples/abigen.rs" -required-features = ["ethers-solc"] - -[[example]] -name = "contract_human_readable" -path = "examples/contract_human_readable.rs" -required-features = ["ethers-solc"] - -[[example]] -name = "contract_with_abi" -path = "examples/contract_with_abi.rs" -required-features = ["ethers-solc"] - -[[example]] -name = "contract_with_abi_and_bytecode" -path = "examples/contract_with_abi_and_bytecode.rs" -required-features = ["ethers-solc"] - -[[example]] -name = "ipc" -path = "examples/ipc.rs" -required-features = ["ipc"] - -[[example]] -name = "ledger" -path = "examples/ledger.rs" -required-features = ["ledger"] - -[[example]] -name = "moonbeam_with_abi" -path = "examples/moonbeam_with_abi.rs" -required-features = ["legacy", "ethers-solc"] - -[[example]] -name = "trezor" -path = "examples/trezor.rs" -required-features = ["trezor"] - -[[example]] -name = "yubi" -path = "examples/yubi.rs" -required-features = ["yubi"] - -[[example]] -name = "paginated_logs" -path = "examples/paginated_logs.rs" -required-features = ["rustls"] - -[[example]] -name = "subscribe_contract_events" -path = "examples/subscribe_contract_events.rs" -required-features = ["rustls", "ws"] - -[[example]] -name = "subscribe_contract_events_with_meta" -path = "examples/subscribe_contract_events_with_meta.rs" -required-features = ["rustls", "ws"] diff --git a/README.md b/README.md index 9d98bb16..c85e9f9e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,12 @@ Extensive documentation and examples are available [here](https://docs.rs/ethers Alternatively, you may clone the repository and run `cd ethers/ && cargo doc --open` -You can also run any of the examples by executing: `cargo run -p ethers --example ` +Examples are organized into individual crates under the `/examples` folder. +You can run any of the examples by executing: +```bash +# cargo run -p --example +cargo run -p examples-big-numbers --example math_operations +``` ## Add ethers-rs to your repository diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..87fbfc19 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,81 @@ +# Examples +- [ ] Address book +- [ ] Anvil + - [ ] Boot anvil + - [ ] Deploy contracts + - [x] Fork + - [ ] Testing +- [x] Big numbers + - [x] Comparison and equivalence + - [x] Conversion + - [x] Creating Instances + - [x] Math operations + - [x] Utilities +- [ ] Contracts + - [x] Abigen + - [x] Compile + - [ ] Creating Instances + - [x] Deploy Anvil + - [x] Deploy from ABI and bytecode + - [x] Deploy Moonbeam + - [x] Events + - [x] Events with meta + - [ ] Methods +- [ ] Events + - [ ] Logs and filtering + - [ ] Solidity topics +- [ ] Middleware + - [x] Builder + - [x] Create custom middleware + - [x] Gas escalator + - [x] Gas oracle + - [x] Nonce manager + - [x] Policy + - [x] Signer + - [ ] Time lag + - [ ] Transformer +- [ ] Providers + - [ ] Http + - [x] IPC + - [ ] Mock + - [x] Quorum + - [ ] Retry + - [x] RW + - [ ] WS +- [ ] Queries + - [ ] Blocks + - [x] Contracts + - [ ] Events + - [x] Paginated logs + - [x] UniswapV2 pair + - [ ] Transactions +- [x] Subscriptions + - [x] Watch blocks + - [x] Subscribe events by type + - [x] Subscribe logs +- [ ] Transactions + - [x] Call override + - [ ] Create raw transaction + - [ ] Create typed transaction + - [x] Decode input + - [ ] EIP-1559 + - [x] ENS + - [ ] Estimate gas + - [ ] Get gas price + - [x] Get gas price USD + - [x] Remove liquidity + - [ ] Set gas for a transaction + - [ ] Send raw transaction + - [ ] Send typed transaction + - [x] Trace + - [ ] Transaction receipt + - [ ] Transaction status + - [x] Transfer ETH +- [x] Wallets + - [x] Mnemonic + - [x] Ledger + - [x] Local + - [x] Permit hash + - [x] Sign message + - [x] Trezor + - [x] Yubi diff --git a/examples/anvil/Cargo.toml b/examples/anvil/Cargo.toml new file mode 100644 index 00000000..7e1fb044 --- /dev/null +++ b/examples/anvil/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "examples-anvil" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0" } +eyre = "0.6" +tokio = { version = "1.18", features = ["full"] } diff --git a/examples/anvil/README.md b/examples/anvil/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/anvil_fork.rs b/examples/anvil/examples/anvil_fork.rs similarity index 88% rename from examples/anvil_fork.rs rename to examples/anvil/examples/anvil_fork.rs index 31da8670..4fecb8e8 100644 --- a/examples/anvil_fork.rs +++ b/examples/anvil/examples/anvil_fork.rs @@ -1,9 +1,10 @@ //! Spawn an [anvil](https://github.com/foundry-rs/foundry/tree/master/anvil) instance in forking mode use ethers::utils::Anvil; +use eyre::Result; #[tokio::main] -async fn main() -> eyre::Result<()> { +async fn main() -> Result<()> { // ensure `anvil` is available in $PATH let anvil = Anvil::new().fork("https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27").spawn(); diff --git a/examples/big-numbers/Cargo.toml b/examples/big-numbers/Cargo.toml new file mode 100644 index 00000000..04505c19 --- /dev/null +++ b/examples/big-numbers/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "examples-big-numbers" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[dev-dependencies] +#ethers-core = { version = "^1.0.0", path = "../../ethers-core" } +ethers = { path = "../..", version = "1.0.0" } + diff --git a/examples/big-numbers/README.md b/examples/big-numbers/README.md new file mode 100644 index 00000000..7ac9428e --- /dev/null +++ b/examples/big-numbers/README.md @@ -0,0 +1,7 @@ +# Big numbers +Ethereum uses big numbers (also known as "bignums" or "arbitrary-precision integers") to represent certain values in its codebase and in blockchain transactions. This is necessary because [the EVM](https://ethereum.org/en/developers/docs/evm) operates on a 256-bit word size, which is different from the usual 32-bit or 64-bit of modern machines. This was chosen for the ease of use with 256-bit cryptography (such as Keccak-256 hashes or secp256k1 signatures). + +It is worth noting that Ethereum is not the only blockchain or cryptocurrency that uses big numbers. Many other blockchains and cryptocurrencies also use big numbers to represent values in their respective systems. + +## Utilities +In order to create an application, it is often necessary to convert between the representation of values that is easily understood by humans (such as ether) and the machine-readable form that is used by contracts and math functions (such as wei). This is particularly important when working with Ethereum, as certain values, such as balances and gas prices, must be expressed in wei when sending transactions, even if they are displayed to the user in a different format, such as ether or gwei. To help with this conversion, ethers-rs provides two functions, `parse_units` and `format_units`, which allow you to easily convert between human-readable and machine-readable forms of values. `parse_units` can be used to convert a string representing a value in ether, such as "1.1", into a big number in wei, which can be used in contracts and math functions. `format_units` can be used to convert a big number value into a human-readable string, which is useful for displaying values to users. diff --git a/examples/big-numbers/examples/comparison_equivalence.rs b/examples/big-numbers/examples/comparison_equivalence.rs new file mode 100644 index 00000000..214a81e7 --- /dev/null +++ b/examples/big-numbers/examples/comparison_equivalence.rs @@ -0,0 +1,32 @@ +use ethers::types::U256; + +fn main() { + // a == b + let a = U256::from(100_u32); + let b = U256::from(100_u32); + assert!(a == b); + + // a < b + let a = U256::from(1_u32); + let b = U256::from(100_u32); + assert!(a < b); + + // a <= b + let a = U256::from(100_u32); + let b = U256::from(100_u32); + assert!(a <= b); + + // a > b + let a = U256::from(100_u32); + let b = U256::from(1_u32); + assert!(a > b); + + // a >= b + let a = U256::from(100_u32); + let b = U256::from(100_u32); + assert!(a >= b); + + // a == 0 + let a = U256::zero(); + assert!(a.is_zero()); +} diff --git a/examples/big-numbers/examples/conversion.rs b/examples/big-numbers/examples/conversion.rs new file mode 100644 index 00000000..99eb6ea0 --- /dev/null +++ b/examples/big-numbers/examples/conversion.rs @@ -0,0 +1,23 @@ +use ethers::{types::U256, utils::format_units}; + +fn main() { + let num = U256::from(42_u8); + + let a: u128 = num.as_u128(); + assert_eq!(a, 42); + + let b: u64 = num.as_u64(); + assert_eq!(b, 42); + + let c: u32 = num.as_u32(); + assert_eq!(c, 42); + + let d: usize = num.as_usize(); + assert_eq!(d, 42); + + let e: String = num.to_string(); + assert_eq!(e, "42"); + + let f: String = format_units(num, 4).unwrap(); + assert_eq!(f, "0.0042"); +} diff --git a/examples/big-numbers/examples/create_instances.rs b/examples/big-numbers/examples/create_instances.rs new file mode 100644 index 00000000..35fea7f1 --- /dev/null +++ b/examples/big-numbers/examples/create_instances.rs @@ -0,0 +1,47 @@ +use ethers::{ + types::{serde_helpers::Numeric, U256}, + utils::{parse_units, ParseUnits}, +}; + +fn main() { + // From strings + let a = U256::from_dec_str("42").unwrap(); + assert_eq!(format!("{a:?}"), "42"); + + let amount = "42"; + let units = 4; + let pu: ParseUnits = parse_units(amount, units).unwrap(); + let b = U256::from(pu); + assert_eq!(format!("{b:?}"), "420000"); + + // From numbers + let c = U256::from(42_u8); + assert_eq!(format!("{c:?}"), "42"); + + let d = U256::from(42_u16); + assert_eq!(format!("{d:?}"), "42"); + + let e = U256::from(42_u32); + assert_eq!(format!("{e:?}"), "42"); + + let f = U256::from(42_u64); + assert_eq!(format!("{f:?}"), "42"); + + let g = U256::from(42_u128); + assert_eq!(format!("{g:?}"), "42"); + + let h = U256::from(0x2a); + assert_eq!(format!("{h:?}"), "42"); + + let i: U256 = 42.into(); + assert_eq!(format!("{i:?}"), "42"); + + // From `Numeric` + let num: Numeric = Numeric::U256(U256::one()); + let l = U256::from(num); + assert_eq!(format!("{l:?}"), "1"); + + let num: Numeric = Numeric::Num(42); + let m = U256::from(num); + assert_eq!(format!("{m:?}"), "42"); +} diff --git a/examples/big-numbers/examples/math_operations.rs b/examples/big-numbers/examples/math_operations.rs new file mode 100644 index 00000000..45938331 --- /dev/null +++ b/examples/big-numbers/examples/math_operations.rs @@ -0,0 +1,49 @@ +use ethers::{types::U256, utils::format_units}; +use std::ops::{Div, Mul}; + +fn main() { + let a = U256::from(10); + let b = U256::from(2); + + // addition + let sum = a + b; + assert_eq!(sum, U256::from(12)); + + // subtraction + let difference = a - b; + assert_eq!(difference, U256::from(8)); + + // multiplication + let product = a * b; + assert_eq!(product, U256::from(20)); + + // division + let quotient = a / b; + assert_eq!(quotient, U256::from(5)); + + // modulo + let remainder = a % b; + assert_eq!(remainder, U256::zero()); // equivalent to `U256::from(0)` + + // exponentiation + let power = a.pow(b); + assert_eq!(power, U256::from(100)); + // powers of 10 can also be expressed like this: + let power_of_10 = U256::exp10(2); + assert_eq!(power_of_10, U256::from(100)); + + // Multiply two 'ether' numbers: + // Big numbers are integers, that can represent fixed point numbers. + // For instance, 1 ether has 18 fixed + // decimal places (1.000000000000000000), and its big number + // representation is 10^18 = 1000000000000000000. + // When we multiply such numbers we are summing up their exponents. + // So if we multiply 10^18 * 10^18 we get 10^36, that is obviously incorrect. + // In order to get the correct result we need to divide by 10^18. + let eth1 = U256::from(10_000000000000000000_u128); // 10 ether + let eth2 = U256::from(20_000000000000000000_u128); // 20 ether + let base = U256::from(10).pow(18.into()); + let mul = eth1.mul(eth2).div(base); // We also divide by 10^18 + let s: String = format_units(mul, "ether").unwrap(); + assert_eq!(s, "200.000000000000000000"); // 200 +} diff --git a/examples/big-numbers/examples/utilities.rs b/examples/big-numbers/examples/utilities.rs new file mode 100644 index 00000000..58493584 --- /dev/null +++ b/examples/big-numbers/examples/utilities.rs @@ -0,0 +1,92 @@ +use ethers::{ + types::U256, + utils::{format_units, parse_units, ParseUnits}, +}; + +fn main() { + parse_units_example(); + format_units_example(); +} + +/// DApps business logics handles big numbers in 'wei' units (i.e. sending transactions, on-chain +/// math, etc.). We provide convenient methods to map user inputs (usually in 'ether' or 'gwei') +/// into 'wei' format. +fn parse_units_example() { + let pu: ParseUnits = parse_units("1.0", "wei").unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::one()); + + let pu: ParseUnits = parse_units("1.0", "kwei").unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::from(1000)); + + let pu: ParseUnits = parse_units("1.0", "mwei").unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::from(1000000)); + + let pu: ParseUnits = parse_units("1.0", "gwei").unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::from(1000000000)); + + let pu: ParseUnits = parse_units("1.0", "szabo").unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::from(1000000000000_u128)); + + let pu: ParseUnits = parse_units("1.0", "finney").unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::from(1000000000000000_u128)); + + let pu: ParseUnits = parse_units("1.0", "ether").unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::from(1000000000000000000_u128)); + + let pu: ParseUnits = parse_units("1.0", 18).unwrap(); + let num = U256::from(pu); + assert_eq!(num, U256::from(1000000000000000000_u128)); +} + +/// DApps business logics handles big numbers in 'wei' units (i.e. sending transactions, on-chain +/// math, etc.). On the other hand it is useful to convert big numbers into user readable formats +/// when displaying on a UI. Generally dApps display numbers in 'ether' and 'gwei' units, +/// respectively for displaying amounts and gas. The `format_units` function will format a big +/// number into a user readable string. +fn format_units_example() { + // 1 ETHER = 10^18 WEI + let one_ether = U256::from(1000000000000000000_u128); + + let num: String = format_units(one_ether, "wei").unwrap(); + assert_eq!(num, "1000000000000000000.0"); + + let num: String = format_units(one_ether, "gwei").unwrap(); + assert_eq!(num, "1000000000.000000000"); + + let num: String = format_units(one_ether, "ether").unwrap(); + assert_eq!(num, "1.000000000000000000"); + + // 1 GWEI = 10^9 WEI + let one_gwei = U256::from(1000000000_u128); + + let num: String = format_units(one_gwei, 0).unwrap(); + assert_eq!(num, "1000000000.0"); + + let num: String = format_units(one_gwei, "wei").unwrap(); + assert_eq!(num, "1000000000.0"); + + let num: String = format_units(one_gwei, "kwei").unwrap(); + assert_eq!(num, "1000000.000"); + + let num: String = format_units(one_gwei, "mwei").unwrap(); + assert_eq!(num, "1000.000000"); + + let num: String = format_units(one_gwei, "gwei").unwrap(); + assert_eq!(num, "1.000000000"); + + let num: String = format_units(one_gwei, "szabo").unwrap(); + assert_eq!(num, "0.001000000000"); + + let num: String = format_units(one_gwei, "finney").unwrap(); + assert_eq!(num, "0.000001000000000"); + + let num: String = format_units(one_gwei, "ether").unwrap(); + assert_eq!(num, "0.000000001000000000"); +} diff --git a/examples/contracts/Cargo.toml b/examples/contracts/Cargo.toml new file mode 100644 index 00000000..4f0e12bd --- /dev/null +++ b/examples/contracts/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "examples-contracts" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[features] +default = ["legacy"] +legacy = [] + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0", features = ["abigen", "ethers-solc", "legacy", "rustls", "ws"] } + +eyre = "0.6" +serde = { version = "1.0.144", features = ["derive"] } +serde_json = "1.0.64" +tokio = { version = "1.18", features = ["macros"] } + + diff --git a/examples/contracts/README.md b/examples/contracts/README.md new file mode 100644 index 00000000..472592f7 --- /dev/null +++ b/examples/contracts/README.md @@ -0,0 +1,39 @@ +# Contracts +In this guide, we will go over some examples of using ethers-rs to work with contracts, including using abigen to generate Rust bindings for a contract, listening for contract events, calling contract methods, and instantiating contracts. + +## Generating Rust bindings with abigen +To use a contract with ethers-rs, you will need to generate Rust bindings using the abigen tool. abigen is included with the ethers-rs library and can be used to generate Rust bindings for any Solidity contract. + +### Generate a Rust file +This method takes a smart contract's Application Binary Interface (ABI) file and generates a Rust file to interact with it. This is useful if the smart contract is referenced in different places in a project. File generation from ABI can also be easily included as a build step of your application. + +Running the code below will generate a file called `token.rs` containing the bindings inside, which exports an `ERC20Token` struct, along with all its events and methods. Put into a `build.rs` file this will generate the bindings during cargo build. + +```rust +Abigen::new("ERC20Token", "./abi.json")?.generate()?.write_to_file("token.rs")?; +``` + +### Generate inline Rust bindings +This method takes a smart contract's solidity definition and generates inline Rust code to interact with it. This is useful for fast prototyping and for tight scoped use-cases of your contracts. Inline Rust generation uses the `abigen!` macro to expand Rust contract bindings. + +Running the code below will generate bindings for the `ERC20Token` struct, along with all its events and methods. +```rust +abigen!( + ERC20Token, + r#"[ + function approve(address spender, uint256 amount) external returns (bool) + event Transfer(address indexed from, address indexed to, uint256 value) + event Approval(address indexed owner, address indexed spender, uint256 value) + ]"#, +); +``` + +Another way to get the same result, is to provide the ABI contract's definition as follows. +```rust +abigen!(ERC20Token, "./abi.json",); +``` + +## Contract instances +## Contract methods +## Contract events + diff --git a/examples/contracts/examples/abi/IERC20.json b/examples/contracts/examples/abi/IERC20.json new file mode 100644 index 00000000..4827e872 --- /dev/null +++ b/examples/contracts/examples/abi/IERC20.json @@ -0,0 +1,153 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "guy", "type": "address" }, + { "name": "wad", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "src", "type": "address" }, + { "name": "dst", "type": "address" }, + { "name": "wad", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "wad", "type": "uint256" }], + "name": "withdraw", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [{ "name": "", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "dst", "type": "address" }, + { "name": "wad", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "deposit", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "", "type": "address" }, + { "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "src", "type": "address" }, + { "indexed": true, "name": "guy", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "src", "type": "address" }, + { "indexed": true, "name": "dst", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "dst", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "src", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Withdrawal", + "type": "event" + } +] diff --git a/examples/contract_abi.json b/examples/contracts/examples/abi/contract_abi.json similarity index 100% rename from examples/contract_abi.json rename to examples/contracts/examples/abi/contract_abi.json diff --git a/examples/contracts/examples/abigen.rs b/examples/contracts/examples/abigen.rs new file mode 100644 index 00000000..b29fa2b2 --- /dev/null +++ b/examples/contracts/examples/abigen.rs @@ -0,0 +1,77 @@ +use ethers::{ + prelude::{abigen, Abigen}, + providers::{Http, Provider}, + types::Address, +}; +use eyre::Result; +use std::sync::Arc; + +/// Abigen is used to generate Rust code to interact with smart contracts on the blockchain. +/// It provides a way to encode and decode data that is passed to and from smart contracts. +/// The output of abigen is Rust code, that is bound to the contract's interface, allowing +/// developers to call its methods to read/write on-chain state and subscribe to realtime events. +/// +/// The abigen tool can be used in two ways, addressing different use-cases scenarios and developer +/// taste: +/// +/// 1. **Rust file generation:** takes a smart contract's Application Binary Interface (ABI) +/// file and generates a Rust file to interact with it. This is useful if the smart contract is +/// referenced in different places in a project. File generation from ABI can also be easily +/// included as a build step of your application. +/// 2. **Rust inline generation:** takes a smart contract's solidity definition and generates inline +/// Rust code to interact with it. This is useful for fast prototyping and for tight scoped +/// use-cases of your contracts. +/// 3. **Rust inline generation from ABI:** similar to the previous point but instead of Solidity +/// code takes in input a smart contract's Application Binary Interface (ABI) file. +#[tokio::main] +async fn main() -> Result<()> { + rust_file_generation()?; + rust_inline_generation().await?; + rust_inline_generation_from_abi(); + Ok(()) +} + +fn rust_file_generation() -> Result<()> { + let base_dir = "./examples/contracts/examples/abi"; + Abigen::new("IERC20", format!("{base_dir}/IERC20.json"))? + .generate()? + .write_to_file(format!("{base_dir}/ierc20.rs"))?; + Ok(()) +} + +fn rust_inline_generation_from_abi() { + abigen!(IERC20, "./examples/contracts/examples/abi/IERC20.json"); +} + +async fn rust_inline_generation() -> Result<()> { + // The abigen! macro expands the contract's code in the current scope + // so that you can interface your Rust program with the blockchain + // counterpart of the contract. + abigen!( + IERC20, + r#"[ + function totalSupply() external view returns (uint256) + function balanceOf(address account) external view returns (uint256) + function transfer(address recipient, uint256 amount) external returns (bool) + function allowance(address owner, address spender) external view returns (uint256) + function approve(address spender, uint256 amount) external returns (bool) + function transferFrom( address sender, address recipient, uint256 amount) external returns (bool) + event Transfer(address indexed from, address indexed to, uint256 value) + event Approval(address indexed owner, address indexed spender, uint256 value) + ]"#, + ); + + const RPC_URL: &str = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"; + const WETH_ADDRESS: &str = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; + + let provider = Provider::::try_from(RPC_URL)?; + let client = Arc::new(provider); + let address: Address = WETH_ADDRESS.parse()?; + let contract = IERC20::new(address, client); + + if let Ok(total_supply) = contract.total_supply().call().await { + println!("WETH total supply is {total_supply:?}"); + } + + Ok(()) +} diff --git a/examples/abigen.rs b/examples/contracts/examples/compile.rs similarity index 77% rename from examples/abigen.rs rename to examples/contracts/examples/compile.rs index e0886687..21b7586a 100644 --- a/examples/abigen.rs +++ b/examples/contracts/examples/compile.rs @@ -1,11 +1,14 @@ -use ethers::{contract::Abigen, solc::Solc}; +use ethers::{prelude::Abigen, solc::Solc}; +use eyre::Result; -fn main() -> eyre::Result<()> { +fn main() -> Result<()> { let mut args = std::env::args(); args.next().unwrap(); // skip program name let contract_name = args.next().unwrap_or_else(|| "SimpleStorage".to_owned()); - let contract: String = args.next().unwrap_or_else(|| "examples/contract.sol".to_owned()); + let contract: String = args + .next() + .unwrap_or_else(|| "examples/contracts/examples/contracts/contract.sol".to_owned()); println!("Generating bindings for {contract}\n"); diff --git a/examples/contract.sol b/examples/contracts/examples/contracts/contract.sol similarity index 93% rename from examples/contract.sol rename to examples/contracts/examples/contracts/contract.sol index 9d04f2f4..e9910f32 100644 --- a/examples/contract.sol +++ b/examples/contracts/examples/contracts/contract.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Unlicense pragma solidity >=0.4.24; contract SimpleStorage { diff --git a/examples/contract_human_readable.rs b/examples/contracts/examples/deploy_anvil.rs similarity index 90% rename from examples/contract_human_readable.rs rename to examples/contracts/examples/deploy_anvil.rs index d0ca18c7..7ef77176 100644 --- a/examples/contract_human_readable.rs +++ b/examples/contracts/examples/deploy_anvil.rs @@ -1,10 +1,13 @@ use ethers::{ - prelude::*, - solc::{Project, ProjectPathsConfig}, - utils::Anvil, + contract::{abigen, ContractFactory}, + core::utils::Anvil, + middleware::SignerMiddleware, + providers::{Http, Provider}, + signers::{LocalWallet, Signer}, + solc::{Artifact, Project, ProjectPathsConfig}, }; use eyre::Result; -use std::{convert::TryFrom, path::PathBuf, sync::Arc, time::Duration}; +use std::{path::PathBuf, sync::Arc, time::Duration}; // Generate the type-safe contract bindings by providing the ABI // definition in human readable format diff --git a/examples/contract_with_abi_and_bytecode.rs b/examples/contracts/examples/deploy_from_abi_and_bytecode.rs similarity index 89% rename from examples/contract_with_abi_and_bytecode.rs rename to examples/contracts/examples/deploy_from_abi_and_bytecode.rs index 2748e252..1dd91f37 100644 --- a/examples/contract_with_abi_and_bytecode.rs +++ b/examples/contracts/examples/deploy_from_abi_and_bytecode.rs @@ -1,4 +1,10 @@ -use ethers::{prelude::*, utils::Anvil}; +use ethers::{ + contract::abigen, + core::utils::Anvil, + middleware::SignerMiddleware, + providers::{Http, Provider}, + signers::{LocalWallet, Signer}, +}; use eyre::Result; use std::{convert::TryFrom, sync::Arc, time::Duration}; diff --git a/examples/contract_with_abi.rs b/examples/contracts/examples/deploy_from_solidity.rs similarity index 85% rename from examples/contract_with_abi.rs rename to examples/contracts/examples/deploy_from_solidity.rs index c77d094f..fa6fb365 100644 --- a/examples/contract_with_abi.rs +++ b/examples/contracts/examples/deploy_from_solidity.rs @@ -1,4 +1,11 @@ -use ethers::{prelude::*, utils::Anvil}; +use ethers::{ + contract::{abigen, ContractFactory}, + core::utils::Anvil, + middleware::SignerMiddleware, + providers::{Http, Provider}, + signers::{LocalWallet, Signer}, + solc::Solc, +}; use eyre::Result; use std::{convert::TryFrom, path::Path, sync::Arc, time::Duration}; @@ -6,7 +13,7 @@ use std::{convert::TryFrom, path::Path, sync::Arc, time::Duration}; // definition abigen!( SimpleContract, - "./examples/contract_abi.json", + "./examples/contracts/examples/abi/contract_abi.json", event_derives(serde::Deserialize, serde::Serialize) ); @@ -17,8 +24,8 @@ async fn main() -> Result<()> { let anvil = Anvil::new().spawn(); // set the path to the contract, `CARGO_MANIFEST_DIR` points to the directory containing the - // manifest of `ethers`. which will be `../` relative to this file - let source = Path::new(&env!("CARGO_MANIFEST_DIR")).join("examples/contract.sol"); + // manifest of `example/contracts`. which will be `../` relative to this file + let source = Path::new(&env!("CARGO_MANIFEST_DIR")).join("examples/contracts/contract.sol"); let compiled = Solc::default().compile_source(source).expect("Could not compile contracts"); let (abi, bytecode, _runtime_bytecode) = compiled.find("SimpleStorage").expect("could not find contract").into_parts_or_default(); diff --git a/examples/moonbeam_with_abi.rs b/examples/contracts/examples/deploy_moonbeam.rs similarity index 95% rename from examples/moonbeam_with_abi.rs rename to examples/contracts/examples/deploy_moonbeam.rs index e17500bc..a26464c8 100644 --- a/examples/moonbeam_with_abi.rs +++ b/examples/contracts/examples/deploy_moonbeam.rs @@ -1,8 +1,8 @@ -use ethers::prelude::*; +use ethers::contract::abigen; abigen!( SimpleContract, - "./examples/contract_abi.json", + "./examples/contracts/examples/abi/contract_abi.json", event_derives(serde::Deserialize, serde::Serialize) ); @@ -19,7 +19,9 @@ abigen!( #[tokio::main] #[cfg(feature = "legacy")] async fn main() -> eyre::Result<()> { + use ethers::prelude::*; use std::{convert::TryFrom, path::Path, sync::Arc, time::Duration}; + const MOONBEAM_DEV_ENDPOINT: &str = "http://localhost:9933"; // set the path to the contract, `CARGO_MANIFEST_DIR` points to the directory containing the diff --git a/examples/contracts/examples/events.rs b/examples/contracts/examples/events.rs new file mode 100644 index 00000000..4039d883 --- /dev/null +++ b/examples/contracts/examples/events.rs @@ -0,0 +1,68 @@ +use ethers::{ + contract::abigen, + core::types::Address, + providers::{Provider, StreamExt, Ws}, +}; +use eyre::Result; +use std::sync::Arc; + +abigen!( + IERC20, + r#"[ + event Transfer(address indexed from, address indexed to, uint256 value) + event Approval(address indexed owner, address indexed spender, uint256 value) + ]"#, +); + +const WSS_URL: &str = "wss://mainnet.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27"; +const WETH_ADDRESS: &str = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; + +#[tokio::main] +async fn main() -> Result<()> { + let provider = Provider::::connect(WSS_URL).await?; + let client = Arc::new(provider); + let address: Address = WETH_ADDRESS.parse()?; + let contract = IERC20::new(address, client); + + listen_all_events(&contract).await?; + listen_specific_events(&contract).await?; + + Ok(()) +} + +/// Given a contract instance, subscribe to all possible events. +/// This allows to centralize the event handling logic and dispatch +/// proper actions. +/// +/// Note that all event bindings have been generated +/// by abigen. Feel free to investigate the abigen expanded code to +/// better understand types and functionalities. +async fn listen_all_events(contract: &IERC20>) -> Result<()> { + let events = contract.events().from_block(16232696); + let mut stream = events.stream().await?.take(1); + + while let Some(Ok(evt)) = stream.next().await { + match evt { + IERC20Events::ApprovalFilter(f) => println!("{f:?}"), + IERC20Events::TransferFilter(f) => println!("{f:?}"), + } + } + + Ok(()) +} + +/// Given a contract instance subscribe to a single type of event. +/// +/// Note that all event bindings have been generated +/// by abigen. Feel free to investigate the abigen expanded code to +/// better understand types and functionalities. +async fn listen_specific_events(contract: &IERC20>) -> Result<()> { + let events = contract.event::().from_block(16232696); + let mut stream = events.stream().await?.take(1); + + while let Some(Ok(f)) = stream.next().await { + println!("ApprovalFilter event: {f:?}"); + } + + Ok(()) +} diff --git a/examples/subscribe_contract_events_with_meta.rs b/examples/contracts/examples/events_with_meta.rs similarity index 80% rename from examples/subscribe_contract_events_with_meta.rs rename to examples/contracts/examples/events_with_meta.rs index c81b4da8..ceb0c68e 100644 --- a/examples/subscribe_contract_events_with_meta.rs +++ b/examples/contracts/examples/events_with_meta.rs @@ -1,4 +1,8 @@ -use ethers::prelude::*; +use ethers::{ + contract::abigen, + core::types::Address, + providers::{Provider, StreamExt, Ws}, +}; use eyre::Result; use std::sync::Arc; @@ -11,9 +15,6 @@ abigen!( ]"#, ); -// In order to run this example you need to include Ws and TLS features -// Run this example with -// `cargo run -p ethers --example subscribe_contract_events_with_meta --features="ws","rustls"` #[tokio::main] async fn main() -> Result<()> { let client = @@ -27,8 +28,8 @@ async fn main() -> Result<()> { let weth = ERC20::new(address, Arc::clone(&client)); // Subscribe Transfer events - let events = weth.events(); - let mut stream = events.stream().await?.with_meta(); + let events = weth.events().from_block(16232698); + let mut stream = events.stream().await?.with_meta().take(1); while let Some(Ok((event, meta))) = stream.next().await { println!("src: {:?}, dst: {:?}, wad: {:?}", event.src, event.dst, event.wad); diff --git a/examples/contracts/examples/instances.rs b/examples/contracts/examples/instances.rs new file mode 100644 index 00000000..7f755fb7 --- /dev/null +++ b/examples/contracts/examples/instances.rs @@ -0,0 +1,2 @@ +#[tokio::main] +async fn main() {} diff --git a/examples/contracts/examples/methods.rs b/examples/contracts/examples/methods.rs new file mode 100644 index 00000000..7f755fb7 --- /dev/null +++ b/examples/contracts/examples/methods.rs @@ -0,0 +1,2 @@ +#[tokio::main] +async fn main() {} diff --git a/examples/contract_with_abi_and_structs.rs b/examples/contracts/examples/methods_abi_and_structs.rs similarity index 82% rename from examples/contract_with_abi_and_structs.rs rename to examples/contracts/examples/methods_abi_and_structs.rs index b74c9ea9..87b08c52 100644 --- a/examples/contract_with_abi_and_structs.rs +++ b/examples/contracts/examples/methods_abi_and_structs.rs @@ -1,7 +1,17 @@ //! Main entry point for ContractMonitor -use ethers::{prelude::*, utils::Anvil}; -use std::{convert::TryFrom, sync::Arc, time::Duration}; +use std::{sync::Arc, time::Duration}; + +use ethers::{ + contract::abigen, + core::{ + types::{Address, U256}, + utils::Anvil, + }, + middleware::SignerMiddleware, + providers::{Http, Provider}, + signers::LocalWallet, +}; abigen!(VerifierContract, "ethers-contract/tests/solidity-contracts/verifier_abi.json"); diff --git a/examples/ethers-wasm/abi/contract_abi.json b/examples/ethers-wasm/abi/contract_abi.json new file mode 100644 index 00000000..12de10c8 --- /dev/null +++ b/examples/ethers-wasm/abi/contract_abi.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"value","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"author","type":"address"},{"indexed":false,"internalType":"string","name":"oldValue","type":"string"},{"indexed":false,"internalType":"string","name":"newValue","type":"string"}],"name":"ValueChanged","type":"event"},{"inputs":[],"name":"getValue","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"value","type":"string"}],"name":"setValue","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/examples/ethers-wasm/src/lib.rs b/examples/ethers-wasm/src/lib.rs index 2e18ad03..273836ce 100644 --- a/examples/ethers-wasm/src/lib.rs +++ b/examples/ethers-wasm/src/lib.rs @@ -24,7 +24,7 @@ macro_rules! log { abigen!( SimpleContract, - "./../contract_abi.json", + "./abi/contract_abi.json", event_derives(serde::Deserialize, serde::Serialize) ); diff --git a/examples/ethers-wasm/tests/contract_with_abi.rs b/examples/ethers-wasm/tests/contract_with_abi.rs index 5530df67..df080b38 100644 --- a/examples/ethers-wasm/tests/contract_with_abi.rs +++ b/examples/ethers-wasm/tests/contract_with_abi.rs @@ -16,7 +16,7 @@ wasm_bindgen_test_configure!(run_in_browser); // definition in human readable format abigen!( SimpleContract, - "../contract_abi.json", + "./abi/contract_abi.json", event_derives(serde::Deserialize, serde::Serialize) ); diff --git a/examples/events/Cargo.toml b/examples/events/Cargo.toml new file mode 100644 index 00000000..4330bdf7 --- /dev/null +++ b/examples/events/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "examples-events" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0" } + +eyre = "0.6" +serde = { version = "1.0.144", features = ["derive"] } +serde_json = "1.0.64" +tokio = { version = "1.18", features = ["macros"] } \ No newline at end of file diff --git a/examples/events/README.md b/examples/events/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/events/examples/placeholder.rs b/examples/events/examples/placeholder.rs new file mode 100644 index 00000000..7f755fb7 --- /dev/null +++ b/examples/events/examples/placeholder.rs @@ -0,0 +1,2 @@ +#[tokio::main] +async fn main() {} diff --git a/examples/middleware/Cargo.toml b/examples/middleware/Cargo.toml new file mode 100644 index 00000000..0c6eb85d --- /dev/null +++ b/examples/middleware/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "examples-middleware" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0", features = ["rustls", "ws"] } + +async-trait = { version = "0.1.50", default-features = false } +eyre = "0.6" +serde_json = "1.0.61" +thiserror = { version = "1.0", default-features = false } +tokio = { version = "1.18", features = ["macros", "rt", "rt-multi-thread"] } + diff --git a/examples/middleware/README.md b/examples/middleware/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/middleware/examples/builder.rs b/examples/middleware/examples/builder.rs new file mode 100644 index 00000000..f8c54ad4 --- /dev/null +++ b/examples/middleware/examples/builder.rs @@ -0,0 +1,58 @@ +use ethers::{ + core::types::BlockNumber, + middleware::{gas_escalator::*, gas_oracle::*, *}, + providers::{Http, Middleware, Provider}, + signers::{LocalWallet, Signer}, +}; +use std::convert::TryFrom; + +const RPC_URL: &str = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"; +const SIGNING_KEY: &str = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169"; + +/// In ethers-rs, middleware is a way to customize the behavior of certain aspects of the library by +/// injecting custom logic into the process of sending transactions and interacting with contracts +/// on the Ethereum blockchain. The MiddlewareBuilder trait provides a way to define a chain of +/// middleware that will be called at different points in this process, allowing you to customize +/// the behavior of the Provider based on your needs. +#[tokio::main] +async fn main() { + builder_example().await; + builder_example_raw_wrap().await; +} + +async fn builder_example() { + let signer = SIGNING_KEY.parse::().unwrap(); + let address = signer.address(); + let escalator = GeometricGasPrice::new(1.125, 60_u64, None::); + let gas_oracle = EthGasStation::new(None); + + let provider = Provider::::try_from(RPC_URL) + .unwrap() + .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) + .gas_oracle(gas_oracle) + .with_signer(signer) + .nonce_manager(address); // Outermost layer + + match provider.get_block(BlockNumber::Latest).await { + Ok(Some(block)) => println!("{:?}", block.number), + _ => println!("Unable to get latest block"), + } +} + +async fn builder_example_raw_wrap() { + let signer = SIGNING_KEY.parse::().unwrap(); + let address = signer.address(); + let escalator = GeometricGasPrice::new(1.125, 60_u64, None::); + + let provider = Provider::::try_from(RPC_URL) + .unwrap() + .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) + .wrap_into(|p| SignerMiddleware::new(p, signer)) + .wrap_into(|p| GasOracleMiddleware::new(p, EthGasStation::new(None))) + .wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer + + match provider.get_block(BlockNumber::Latest).await { + Ok(Some(block)) => println!("{:?}", block.number), + _ => println!("Unable to get latest block"), + } +} diff --git a/examples/middleware/examples/create_custom_middleware.rs b/examples/middleware/examples/create_custom_middleware.rs new file mode 100644 index 00000000..7e19ee3a --- /dev/null +++ b/examples/middleware/examples/create_custom_middleware.rs @@ -0,0 +1,156 @@ +use async_trait::async_trait; +use ethers::{ + core::{ + types::{transaction::eip2718::TypedTransaction, BlockId, TransactionRequest, U256}, + utils::{parse_units, Anvil}, + }, + middleware::MiddlewareBuilder, + providers::{FromErr, Http, Middleware, PendingTransaction, Provider}, + signers::{LocalWallet, Signer}, +}; +use thiserror::Error; + +/// This example demonstrates the mechanisms for creating custom middlewares in ethers-rs. +/// The example includes explanations of the process and code snippets to illustrate the +/// concepts. It is intended for developers who want to learn how to customize the behavior of +/// ethers-rs providers by creating and using custom middlewares. +/// +/// This custom middleware increases the gas value of transactions sent through an ethers-rs +/// provider by a specified percentage and will be called for each transaction before it is sent. +/// This can be useful if you want to ensure that transactions have a higher gas value than the +/// estimated, in order to improve the chances of them not to run out of gas when landing on-chain. +#[derive(Debug)] +struct GasMiddleware { + inner: M, + /// This value is used to raise the gas value before sending transactions + contingency: U256, +} + +/// Contingency is expressed with 4 units +/// e.g. +/// 50% => 1 + 0.5 => 15000 +/// 20% => 1 + 0.2 => 12000 +/// 1% => 1 + 0.01 => 10100 +const CONTINGENCY_UNITS: usize = 4; + +impl GasMiddleware +where + M: Middleware, +{ + /// Creates an instance of GasMiddleware + /// `ìnner` the inner Middleware + /// `perc` This is an unsigned integer representing the percentage increase in the amount of gas + /// to be used for the transaction. The percentage is relative to the gas value specified in the + /// transaction. Valid contingency values are in range 1..=50. Otherwise a custom middleware + /// error is raised. + pub fn new(inner: M, perc: u32) -> Result> { + let contingency = match perc { + 0 => Err(GasMiddlewareError::TooLowContingency(perc))?, + 51.. => Err(GasMiddlewareError::TooHighContingency(perc))?, + 1..=50 => { + let decimals = 2; + let perc = U256::from(perc) * U256::exp10(decimals); // e.g. 50 => 5000 + let one = parse_units(1, CONTINGENCY_UNITS).unwrap(); + let one = U256::from(one); + one + perc // e.g. 50% => 1 + 0.5 => 10000 + 5000 => 15000 + } + }; + + Ok(Self { inner, contingency }) + } +} + +/// Let's implement the `Middleware` trait for our custom middleware. +/// All trait functions are derived automatically, so we just need to +/// override the needed functions. +#[async_trait] +impl Middleware for GasMiddleware +where + M: Middleware, +{ + type Error = GasMiddlewareError; + type Provider = M::Provider; + type Inner = M; + + fn inner(&self) -> &M { + &self.inner + } + + /// In this function we bump the transaction gas value by the specified percentage + /// This can raise a custom middleware error if a gas amount was not set for + /// the transaction. + async fn send_transaction + Send + Sync>( + &self, + tx: T, + block: Option, + ) -> Result, Self::Error> { + let mut tx: TypedTransaction = tx.into(); + + let curr_gas: U256 = match tx.gas() { + Some(gas) => gas.to_owned(), + None => Err(GasMiddlewareError::NoGasSetForTransaction)?, + }; + + println!("Original transaction gas: {curr_gas:?} wei"); + let units: U256 = U256::exp10(CONTINGENCY_UNITS.into()); + let raised_gas: U256 = (curr_gas * self.contingency) / units; + tx.set_gas(raised_gas); + println!("Raised transaction gas: {raised_gas:?} wei"); + + // Dispatch the call to the inner layer + self.inner().send_transaction(tx, block).await.map_err(FromErr::from) + } +} + +/// This example demonstrates how to handle errors in custom middlewares. It shows how to define +/// custom error types, use them in middleware implementations, and how to propagate the errors +/// through the middleware chain. This is intended for developers who want to create custom +/// middlewares that can handle and propagate errors in a consistent and robust way. +#[derive(Error, Debug)] +pub enum GasMiddlewareError { + /// Thrown when the internal middleware errors + #[error("{0}")] + MiddlewareError(M::Error), + /// Specific errors of this GasMiddleware. + /// Please refer to the `thiserror` crate for + /// further docs. + #[error("{0}")] + TooHighContingency(u32), + #[error("{0}")] + TooLowContingency(u32), + #[error("Cannot raise gas! Gas value not provided for this transaction.")] + NoGasSetForTransaction, +} + +impl FromErr for GasMiddlewareError { + fn from(src: M::Error) -> Self { + GasMiddlewareError::MiddlewareError(src) + } +} + +#[tokio::main] +async fn main() -> eyre::Result<()> { + let anvil = Anvil::new().spawn(); + + let wallet: LocalWallet = anvil.keys()[0].clone().into(); + let wallet2: LocalWallet = anvil.keys()[1].clone().into(); + let signer = wallet.with_chain_id(anvil.chain_id()); + + let gas_raise_perc = 50; // 50%; + let provider = Provider::::try_from(anvil.endpoint())? + .with_signer(signer) + .wrap_into(|s| GasMiddleware::new(s, gas_raise_perc).unwrap()); + + let gas = 15000; + let tx = TransactionRequest::new().to(wallet2.address()).value(10000).gas(gas); + + let pending_tx = provider.send_transaction(tx, None).await?; + + let receipt = pending_tx.await?.ok_or_else(|| eyre::format_err!("tx dropped from mempool"))?; + let tx = provider.get_transaction(receipt.transaction_hash).await?; + + println!("Sent tx: {}\n", serde_json::to_string(&tx)?); + println!("Tx receipt: {}", serde_json::to_string(&receipt)?); + + Ok(()) +} diff --git a/examples/middleware/examples/gas_escalator.rs b/examples/middleware/examples/gas_escalator.rs new file mode 100644 index 00000000..c60d304c --- /dev/null +++ b/examples/middleware/examples/gas_escalator.rs @@ -0,0 +1,59 @@ +use ethers::{ + core::{types::TransactionRequest, utils::Anvil}, + middleware::gas_escalator::*, + providers::{Http, Middleware, Provider}, +}; +use eyre::Result; + +/// The gas escalator middleware in ethers-rs is designed to automatically increase the gas cost of +/// transactions if they get stuck in the mempool. This can be useful if you want to +/// ensure that transactions are processed in a timely manner without having to manually adjust the +/// gas cost yourself. +#[tokio::main] +async fn main() -> Result<()> { + let every_secs: u64 = 60; + let max_price: Option = None; + + // Linearly increase gas price: + // 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. + let increase_by: i32 = 100; + let linear_escalator = LinearGasPrice::new(increase_by, every_secs, max_price); + send_escalating_transaction(linear_escalator).await?; + + // Geometrically increase gas price: + // Start with `initial_price`, then increase it every 'every_secs' seconds by a fixed + // coefficient. 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. + let coefficient: f64 = 1.125; + let geometric_escalator = GeometricGasPrice::new(coefficient, every_secs, max_price); + send_escalating_transaction(geometric_escalator).await?; + + Ok(()) +} + +async fn send_escalating_transaction(escalator: E) -> Result<()> +where + E: GasEscalator + Clone + 'static, +{ + // Spawn local node + let anvil = Anvil::new().spawn(); + let endpoint = anvil.endpoint(); + + // Connect to the node + let provider = Provider::::try_from(endpoint)?; + let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock); + + let accounts = provider.get_accounts().await?; + let from = accounts[0]; + let to = accounts[1]; + let tx = TransactionRequest::new().from(from).to(to).value(1000); + + // Bumps the gas price until transaction gets mined + let pending_tx = provider.send_transaction(tx, None).await?; + let receipt = pending_tx.await?; + + println!("{receipt:?}"); + + Ok(()) +} diff --git a/examples/middleware/examples/gas_oracle.rs b/examples/middleware/examples/gas_oracle.rs new file mode 100644 index 00000000..95105aeb --- /dev/null +++ b/examples/middleware/examples/gas_oracle.rs @@ -0,0 +1,88 @@ +use ethers::{ + core::types::Chain, + etherscan::Client, + middleware::gas_oracle::{ + BlockNative, Etherscan, GasCategory, GasNow, GasOracle, Polygon, ProviderOracle, + }, + providers::{Http, Provider}, +}; + +/// In Ethereum, the "gas" of a transaction refers to the amount of computation required to execute +/// the transaction on the blockchain. Gas is typically measured in units of "gas," and the cost of +/// a transaction is determined by the amount of gas it consumes. +/// +/// A "gas oracle" is a tool or service that provides information about the current price of gas on +/// the Ethereum network. Gas oracles are often used to help determine the appropriate amount of gas +/// to include in a transaction, in order to ensure that it will be processed in a timely manner +/// without running out of gas. +/// +/// Ethers-rs includes a feature called "gas oracle middleware" that allows you to customize the +/// behavior of the library when it comes to determining the gas cost of transactions. +#[tokio::main] +async fn main() { + blocknative().await; + etherscan().await; + gas_now().await; + polygon().await; + provider_oracle().await; + //etherchain().await; // FIXME: Etherchain URL is broken (Http 404) +} + +async fn blocknative() { + let api_key: Option = std::env::var("BLOCK_NATIVE_API_KEY").ok(); + let oracle = BlockNative::new(api_key).category(GasCategory::Fastest); + match oracle.fetch().await { + Ok(gas_price) => println!("[Blocknative]: Gas price is {gas_price:?}"), + Err(e) => panic!("[Blocknative]: Cannot estimate gas: {e:?}"), + } +} + +async fn etherscan() { + let chain = Chain::Mainnet; + let api_key: String = std::env::var("ETHERSCAN_API_KEY_ETHEREUM").expect("Provide an API key"); + if let Ok(client) = Client::new(chain, api_key) { + let oracle = Etherscan::new(client).category(GasCategory::Fast); + match oracle.fetch().await { + Ok(gas_price) => println!("[Etherscan]: Gas price is {gas_price:?}"), + Err(e) => panic!("[Etherscan]: Cannot estimate gas: {e:?}"), + } + } +} + +async fn gas_now() { + let oracle = GasNow::new().category(GasCategory::Fast); + match oracle.fetch().await { + Ok(gas_price) => println!("[GasNow]: Gas price is {gas_price:?}"), + Err(e) => panic!("[GasNow]: Cannot estimate gas: {e:?}"), + } +} + +async fn polygon() { + let chain = Chain::Polygon; + if let Ok(oracle) = Polygon::new(chain) { + match oracle.category(GasCategory::SafeLow).fetch().await { + Ok(gas_price) => println!("[Polygon]: Gas price is {gas_price:?}"), + Err(e) => panic!("[Polygon]: Cannot estimate gas: {e:?}"), + } + } +} + +async fn provider_oracle() { + const RPC_URL: &str = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"; + let provider = Provider::::try_from(RPC_URL).unwrap(); + let oracle = ProviderOracle::new(provider); + match oracle.fetch().await { + Ok(gas_price) => println!("[Provider oracle]: Gas price is {gas_price:?}"), + Err(e) => panic!("[Provider oracle]: Cannot estimate gas: {e:?}"), + } +} + +/* +// FIXME: Etherchain URL is broken (Http 404) +async fn etherchain() { + let oracle = Etherchain::new().category(GasCategory::Standard); + match oracle.fetch().await { + Ok(gas_price) => println!("[Etherchain]: Gas price is {gas_price:?}"), + Err(e) => panic!("[Etherchain]: Cannot estimate gas: {e:?}"), + } +}*/ diff --git a/examples/middleware/examples/nonce_manager.rs b/examples/middleware/examples/nonce_manager.rs new file mode 100644 index 00000000..e76bcc1c --- /dev/null +++ b/examples/middleware/examples/nonce_manager.rs @@ -0,0 +1,46 @@ +use ethers::{ + core::{ + types::{BlockNumber, TransactionRequest}, + utils::Anvil, + }, + middleware::MiddlewareBuilder, + providers::{Http, Middleware, Provider}, +}; +use eyre::Result; + +/// In Ethereum, the nonce of a transaction is a number that represents the number of transactions +/// that have been sent from a particular account. The nonce is used to ensure that transactions are +/// processed in the order they are intended, and to prevent the same transaction from being +/// processed multiple times. +/// +/// The nonce manager in ethers-rs is a middleware that helps you manage the nonce +/// of transactions by keeping track of the current nonce for a given account and automatically +/// incrementing it as needed. This can be useful if you want to ensure that transactions are sent +/// in the correct order, or if you want to avoid having to manually manage the nonce yourself. +#[tokio::main] +async fn main() -> Result<()> { + let anvil = Anvil::new().spawn(); + let endpoint = anvil.endpoint(); + + let provider = Provider::::try_from(endpoint)?; + let accounts = provider.get_accounts().await?; + let account = accounts[0]; + let to = accounts[1]; + let tx = TransactionRequest::new().from(account).to(to).value(1000); + + let nonce_manager = provider.nonce_manager(account); + + let curr_nonce = nonce_manager + .get_transaction_count(account, Some(BlockNumber::Pending.into())) + .await? + .as_u64(); + + assert_eq!(curr_nonce, 0); + + nonce_manager.send_transaction(tx, None).await?; + let next_nonce = nonce_manager.next().as_u64(); + + assert_eq!(next_nonce, 1); + + Ok(()) +} diff --git a/examples/middleware/examples/policy.rs b/examples/middleware/examples/policy.rs new file mode 100644 index 00000000..3e2e0a4b --- /dev/null +++ b/examples/middleware/examples/policy.rs @@ -0,0 +1,39 @@ +use ethers::{ + core::{types::TransactionRequest, utils::Anvil}, + middleware::{ + policy::{PolicyMiddlewareError, RejectEverything}, + MiddlewareBuilder, PolicyMiddleware, + }, + providers::{Http, Middleware, Provider}, +}; +use eyre::Result; + +/// Policy middleware is a way to inject custom logic into the process of sending transactions and +/// interacting with contracts on the Ethereum blockchain. It allows you to define rules or policies +/// that should be followed when performing these actions, and to customize the behavior of the +/// library based on these policies. +#[tokio::main] +async fn main() -> Result<()> { + let anvil = Anvil::new().spawn(); + let endpoint = anvil.endpoint(); + + let provider = Provider::::try_from(endpoint)?; + + let accounts = provider.get_accounts().await?; + let account = accounts[0]; + let to = accounts[1]; + let tx = TransactionRequest::new().from(account).to(to).value(1000); + + let policy = RejectEverything; + let policy_middleware = provider.wrap_into(|p| PolicyMiddleware::new(p, policy)); + + match policy_middleware.send_transaction(tx, None).await { + Err(e) => { + // Given the RejectEverything policy, we expect to execute this branch + assert!(matches!(e, PolicyMiddlewareError::PolicyError(()))) + } + _ => panic!("We don't expect this to happen!"), + } + + Ok(()) +} diff --git a/examples/middleware/examples/signer.rs b/examples/middleware/examples/signer.rs new file mode 100644 index 00000000..38ad057c --- /dev/null +++ b/examples/middleware/examples/signer.rs @@ -0,0 +1,40 @@ +use ethers::{ + core::{types::TransactionRequest, utils::Anvil}, + middleware::SignerMiddleware, + providers::{Http, Middleware, Provider}, + signers::{LocalWallet, Signer}, +}; +use eyre::Result; +use std::convert::TryFrom; + +/// In Ethereum, transactions must be signed with a private key before they can be broadcast to the +/// network. Ethers-rs provides a way to customize this process by allowing +/// you to define a signer, called to sign transactions before they are sent. +#[tokio::main] +async fn main() -> Result<()> { + let anvil = Anvil::new().spawn(); + + let wallet: LocalWallet = anvil.keys()[0].clone().into(); + let wallet2: LocalWallet = anvil.keys()[1].clone().into(); + + // connect to the network + let provider = Provider::::try_from(anvil.endpoint())?; + + // connect the wallet to the provider + let client = SignerMiddleware::new(provider, wallet.with_chain_id(anvil.chain_id())); + + // craft the transaction + let tx = TransactionRequest::new().to(wallet2.address()).value(10000); + + // send it! + let pending_tx = client.send_transaction(tx, None).await?; + + // get the mined tx + let receipt = pending_tx.await?.ok_or_else(|| eyre::format_err!("tx dropped from mempool"))?; + let tx = client.get_transaction(receipt.transaction_hash).await?; + + println!("Sent tx: {}\n", serde_json::to_string(&tx)?); + println!("Tx receipt: {}", serde_json::to_string(&receipt)?); + + Ok(()) +} diff --git a/examples/middleware/examples/timelag.rs b/examples/middleware/examples/timelag.rs new file mode 100644 index 00000000..7f755fb7 --- /dev/null +++ b/examples/middleware/examples/timelag.rs @@ -0,0 +1,2 @@ +#[tokio::main] +async fn main() {} diff --git a/examples/middleware/examples/transformer.rs b/examples/middleware/examples/transformer.rs new file mode 100644 index 00000000..7f755fb7 --- /dev/null +++ b/examples/middleware/examples/transformer.rs @@ -0,0 +1,2 @@ +#[tokio::main] +async fn main() {} diff --git a/examples/providers/Cargo.toml b/examples/providers/Cargo.toml new file mode 100644 index 00000000..71a92210 --- /dev/null +++ b/examples/providers/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "examples-providers" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[features] +default = ["ipc"] +ipc = [] + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0", features = ["abigen", "ipc", "rustls", "ws"] } + +eyre = "0.6" +serde = { version = "1.0.144", features = ["derive"] } +serde_json = "1.0.64" +tokio = { version = "1.18", features = ["macros"] } diff --git a/examples/providers/README.md b/examples/providers/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/ipc.rs b/examples/providers/examples/ipc.rs similarity index 100% rename from examples/ipc.rs rename to examples/providers/examples/ipc.rs diff --git a/examples/quorum.rs b/examples/providers/examples/quorum.rs similarity index 85% rename from examples/quorum.rs rename to examples/providers/examples/quorum.rs index 95f62af1..a1d50c8c 100644 --- a/examples/quorum.rs +++ b/examples/providers/examples/quorum.rs @@ -1,11 +1,15 @@ //! Example usage for the `QuorumProvider` that requests multiple backends and only returns //! a value if the configured `Quorum` was reached. -use ethers::{prelude::*, utils::Anvil}; +use ethers::{ + core::utils::Anvil, + providers::{Http, Middleware, Provider, Quorum, QuorumProvider, WeightedProvider, Ws}, +}; +use eyre::Result; use std::{str::FromStr, time::Duration}; #[tokio::main] -async fn main() -> eyre::Result<()> { +async fn main() -> Result<()> { let anvil = Anvil::new().spawn(); // create a quorum provider with some providers diff --git a/examples/rw.rs b/examples/providers/examples/rw.rs similarity index 76% rename from examples/rw.rs rename to examples/providers/examples/rw.rs index 89733a8f..89f1f439 100644 --- a/examples/rw.rs +++ b/examples/providers/examples/rw.rs @@ -1,11 +1,15 @@ //! Example usage for the `RwClient` that uses a didicated client to send transaction and nother one //! for read ops -use ethers::{prelude::*, utils::Anvil}; +use ethers::{ + core::utils::Anvil, + providers::{Http, Middleware, Provider, Ws}, +}; +use eyre::Result; use std::{str::FromStr, time::Duration}; #[tokio::main] -async fn main() -> eyre::Result<()> { +async fn main() -> Result<()> { let anvil = Anvil::new().spawn(); let http = Http::from_str(&anvil.endpoint())?; diff --git a/examples/queries/Cargo.toml b/examples/queries/Cargo.toml new file mode 100644 index 00000000..fa92ea52 --- /dev/null +++ b/examples/queries/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "examples-queries" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0", features = ["abigen", "rustls", "ws"] } + +eyre = "0.6" +serde = { version = "1.0.144", features = ["derive"] } +serde_json = "1.0.64" +tokio = { version = "1.18", features = ["macros"] } \ No newline at end of file diff --git a/examples/queries/README.md b/examples/queries/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/paginated_logs.rs b/examples/queries/examples/paginated_logs.rs similarity index 84% rename from examples/paginated_logs.rs rename to examples/queries/examples/paginated_logs.rs index 9f94f9e0..563b90f1 100644 --- a/examples/paginated_logs.rs +++ b/examples/queries/examples/paginated_logs.rs @@ -1,4 +1,10 @@ -use ethers::{abi::AbiDecode, prelude::*, providers::Middleware}; +use ethers::{ + core::{ + abi::AbiDecode, + types::{BlockNumber, Filter, U256}, + }, + providers::{Middleware, Provider, StreamExt, Ws}, +}; use eyre::Result; use std::sync::Arc; @@ -15,7 +21,7 @@ async fn main() -> Result<()> { let erc20_transfer_filter = Filter::new().from_block(last_block - 10000).event("Transfer(address,address,uint256)"); - let mut stream = client.get_logs_paginated(&erc20_transfer_filter, 10); + let mut stream = client.get_logs_paginated(&erc20_transfer_filter, 10).take(5); while let Some(res) = stream.next().await { let log = res?; diff --git a/examples/uniswapv2.rs b/examples/queries/examples/uniswapv2_pair.rs similarity index 91% rename from examples/uniswapv2.rs rename to examples/queries/examples/uniswapv2_pair.rs index 8b956112..c9d306da 100644 --- a/examples/uniswapv2.rs +++ b/examples/queries/examples/uniswapv2_pair.rs @@ -1,4 +1,8 @@ -use ethers::prelude::*; +use ethers::{ + contract::abigen, + core::types::Address, + providers::{Http, Provider}, +}; use eyre::Result; use std::sync::Arc; diff --git a/examples/subscribe_contract_events.rs b/examples/subscribe_contract_events.rs deleted file mode 100644 index a6f769f9..00000000 --- a/examples/subscribe_contract_events.rs +++ /dev/null @@ -1,38 +0,0 @@ -use ethers::prelude::*; -use eyre::Result; -use std::sync::Arc; - -// Generate the type-safe contract bindings by providing the ABI -// definition in human readable format -abigen!( - ERC20, - r#"[ - event Transfer(address indexed src, address indexed dst, uint wad) - ]"#, -); - -// In order to run this example you need to include Ws and TLS features -// Run this example with -// `cargo run -p ethers --example subscribe_contract_events --features="ws","rustls"` -#[tokio::main] -async fn main() -> Result<()> { - let client = - Provider::::connect("wss://mainnet.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27") - .await?; - - let client = Arc::new(client); - - // WETH Token - let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse::

()?; - let weth = ERC20::new(address, Arc::clone(&client)); - - // Subscribe Transfer events - let events = weth.events(); - let mut stream = events.stream().await?; - - while let Some(Ok(event)) = stream.next().await { - println!("src: {:?}, dst: {:?}, wad: {:?}", event.src, event.dst, event.wad); - } - - Ok(()) -} diff --git a/examples/subscriptions/Cargo.toml b/examples/subscriptions/Cargo.toml new file mode 100644 index 00000000..9dd76878 --- /dev/null +++ b/examples/subscriptions/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "examples-subscriptions" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0", features = ["abigen", "rustls", "ws"] } + +eyre = "0.6" +serde = { version = "1.0.144", features = ["derive"] } +serde_json = "1.0.64" +tokio = { version = "1.18", features = ["macros"] } \ No newline at end of file diff --git a/examples/subscriptions/README.md b/examples/subscriptions/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/subscribe_events_by_type.rs b/examples/subscriptions/examples/subscribe_events_by_type.rs similarity index 82% rename from examples/subscribe_events_by_type.rs rename to examples/subscriptions/examples/subscribe_events_by_type.rs index 76e394ac..355404a3 100644 --- a/examples/subscribe_events_by_type.rs +++ b/examples/subscriptions/examples/subscribe_events_by_type.rs @@ -1,5 +1,10 @@ -use ethers::{contract::Contract, prelude::*}; +use ethers::{ + contract::{abigen, Contract}, + core::types::ValueOrArray, + providers::{Provider, StreamExt, Ws}, +}; use std::{error::Error, sync::Arc}; + abigen!( AggregatorInterface, r#"[ @@ -14,10 +19,6 @@ const PRICE_FEED_3: &str = "0xebf67ab8cff336d3f609127e8bbf8bd6dd93cd81"; /// Subscribe to a typed event stream without requiring a `Contract` instance. /// In this example we subscribe Chainlink price feeds and filter out them /// by address. -/// ------------------------------------------------------------------------------- -/// In order to run this example you need to include Ws and TLS features -/// Run this example with -/// `cargo run -p ethers --example subscribe_events_by_type --features="ws","rustls"` #[tokio::main] async fn main() -> Result<(), Box> { let client = get_client().await; diff --git a/examples/subscribe_logs.rs b/examples/subscriptions/examples/subscribe_logs.rs similarity index 82% rename from examples/subscribe_logs.rs rename to examples/subscriptions/examples/subscribe_logs.rs index b8cb1891..3ee71259 100644 --- a/examples/subscribe_logs.rs +++ b/examples/subscriptions/examples/subscribe_logs.rs @@ -1,9 +1,13 @@ -use ethers::{abi::AbiDecode, prelude::*}; +use ethers::{ + core::{ + abi::AbiDecode, + types::{Address, BlockNumber, Filter, U256}, + }, + providers::{Middleware, Provider, StreamExt, Ws}, +}; use eyre::Result; use std::sync::Arc; -// In order to run this example you need to include Ws and TLS features -// Run this example with `cargo run -p ethers --example subscribe_logs --features="ws","rustls"` #[tokio::main] async fn main() -> Result<()> { let client = diff --git a/examples/watch_blocks.rs b/examples/subscriptions/examples/watch_blocks.rs similarity index 58% rename from examples/watch_blocks.rs rename to examples/subscriptions/examples/watch_blocks.rs index af1385da..38fb90e5 100644 --- a/examples/watch_blocks.rs +++ b/examples/subscriptions/examples/watch_blocks.rs @@ -1,12 +1,13 @@ -use ethers::{prelude::*, utils::Anvil}; +use ethers::providers::{Middleware, Provider, StreamExt, Ws}; +use eyre::Result; use std::time::Duration; #[tokio::main] -async fn main() -> eyre::Result<()> { - let anvil = Anvil::new().block_time(1u64).spawn(); - let ws = Ws::connect(anvil.ws_endpoint()).await?; +async fn main() -> Result<()> { + let ws_endpoint = "wss://mainnet.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27"; + let ws = Ws::connect(ws_endpoint).await?; let provider = Provider::new(ws).interval(Duration::from_millis(2000)); - let mut stream = provider.watch_blocks().await?.take(5); + let mut stream = provider.watch_blocks().await?.take(1); while let Some(block) = stream.next().await { let block = provider.get_block(block).await?.unwrap(); println!( diff --git a/examples/transactions/Cargo.toml b/examples/transactions/Cargo.toml new file mode 100644 index 00000000..6bdf9412 --- /dev/null +++ b/examples/transactions/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "examples-transactions" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0", features = ["abigen", "rustls", "ws"] } + +eyre = "0.6" +serde = { version = "1.0.144", features = ["derive"] } +serde_json = "1.0.64" +tokio = { version = "1.18", features = ["macros"] } \ No newline at end of file diff --git a/examples/transactions/README.md b/examples/transactions/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/call_override.rs b/examples/transactions/examples/call_override.rs similarity index 90% rename from examples/call_override.rs rename to examples/transactions/examples/call_override.rs index 2237ee1e..b80191e8 100644 --- a/examples/call_override.rs +++ b/examples/transactions/examples/call_override.rs @@ -1,14 +1,21 @@ use ethers::{ - prelude::*, - providers::call_raw::RawCall, - utils::{parse_ether, Geth}, + contract::abigen, + core::{ + types::{Address, TransactionRequest, H256}, + utils::{parse_ether, Geth}, + }, + providers::{ + call_raw::{self, RawCall}, + Http, Provider, + }, }; +use eyre::Result; use std::sync::Arc; abigen!(Greeter, "ethers-contract/tests/solidity-contracts/greeter.json",); #[tokio::main] -async fn main() -> eyre::Result<()> { +async fn main() -> Result<()> { let geth = Geth::new().spawn(); let provider = Provider::::try_from(geth.endpoint()).unwrap(); let client = Arc::new(provider); diff --git a/examples/decode_tx_input.rs b/examples/transactions/examples/decode_input.rs similarity index 94% rename from examples/decode_tx_input.rs rename to examples/transactions/examples/decode_input.rs index f11b6f1b..0eca8c37 100644 --- a/examples/decode_tx_input.rs +++ b/examples/transactions/examples/decode_input.rs @@ -1,4 +1,7 @@ -use ethers::{abi::AbiDecode, prelude::*}; +use ethers::{ + contract::abigen, + core::{abi::AbiDecode, types::Bytes}, +}; use eyre::Result; // Abigen creates a SwapExactTokensForTokensCall struct that can be used to decode diff --git a/examples/ens.rs b/examples/transactions/examples/ens.rs similarity index 87% rename from examples/ens.rs rename to examples/transactions/examples/ens.rs index 5874d5c9..0606288e 100644 --- a/examples/ens.rs +++ b/examples/transactions/examples/ens.rs @@ -1,6 +1,8 @@ -use ethers::{prelude::*, utils::Anvil}; +use ethers::{ + core::{types::TransactionRequest, utils::Anvil}, + providers::{Http, Middleware, Provider}, +}; use eyre::Result; -use std::convert::TryFrom; #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/gas_price_usd.rs b/examples/transactions/examples/gas_price_usd.rs similarity index 92% rename from examples/gas_price_usd.rs rename to examples/transactions/examples/gas_price_usd.rs index 307baf82..eef46a72 100644 --- a/examples/gas_price_usd.rs +++ b/examples/transactions/examples/gas_price_usd.rs @@ -1,10 +1,18 @@ -use ethers::{prelude::*, utils::format_units}; use std::{ error::Error, ops::{Div, Mul}, sync::Arc, }; +use ethers::{ + contract::abigen, + core::{ + types::{Address, I256, U256}, + utils::format_units, + }, + providers::{Http, Middleware, Provider}, +}; + abigen!( AggregatorInterface, r#"[ diff --git a/examples/remove_liquidity.rs b/examples/transactions/examples/remove_liquidity.rs similarity index 92% rename from examples/remove_liquidity.rs rename to examples/transactions/examples/remove_liquidity.rs index 0d3e889d..587f6436 100644 --- a/examples/remove_liquidity.rs +++ b/examples/transactions/examples/remove_liquidity.rs @@ -1,6 +1,13 @@ -use ethers::prelude::*; +use std::sync::Arc; + +use ethers::{ + contract::abigen, + core::types::{Address, U256}, + middleware::SignerMiddleware, + providers::{Http, Middleware, Provider}, + signers::{LocalWallet, Signer}, +}; use eyre::Result; -use std::{convert::TryFrom, sync::Arc}; abigen!( UniswapV2Router, diff --git a/examples/geth_trace_transaction.rs b/examples/transactions/examples/trace.rs similarity index 85% rename from examples/geth_trace_transaction.rs rename to examples/transactions/examples/trace.rs index ef20f738..35ea370d 100644 --- a/examples/geth_trace_transaction.rs +++ b/examples/transactions/examples/trace.rs @@ -1,4 +1,7 @@ -use ethers::prelude::*; +use ethers::{ + core::types::{GethDebugTracingOptions, H256}, + providers::{Http, Middleware, Provider}, +}; use eyre::Result; use std::str::FromStr; diff --git a/examples/transfer_eth.rs b/examples/transactions/examples/transfer_eth.rs similarity index 90% rename from examples/transfer_eth.rs rename to examples/transactions/examples/transfer_eth.rs index 3be81cc9..00a4e6fc 100644 --- a/examples/transfer_eth.rs +++ b/examples/transactions/examples/transfer_eth.rs @@ -1,4 +1,7 @@ -use ethers::{prelude::*, utils::Anvil}; +use ethers::{ + core::{types::TransactionRequest, utils::Anvil}, + providers::{Http, Middleware, Provider}, +}; use eyre::Result; use std::convert::TryFrom; diff --git a/examples/wallets/Cargo.toml b/examples/wallets/Cargo.toml new file mode 100644 index 00000000..c3112132 --- /dev/null +++ b/examples/wallets/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "examples-wallets" +version = "1.0.2" +authors = ["Andrea Simeoni "] +edition = "2021" + +[features] +default = ["ledger", "trezor", "yubi"] +ledger = [] +trezor = [] +yubi = [] + +[dev-dependencies] +ethers = { path = "../..", version = "1.0.0", features = ["abigen", "eip712", "ledger", "rustls", "trezor", "ws", "yubi"] } + +eyre = "0.6" +serde = { version = "1.0.144", features = ["derive"] } +serde_json = "1.0.64" +tokio = { version = "1.18", features = ["macros"] } + diff --git a/examples/wallets/README.md b/examples/wallets/README.md new file mode 100644 index 00000000..e69de29b diff --git a/examples/ledger.rs b/examples/wallets/examples/ledger.rs similarity index 100% rename from examples/ledger.rs rename to examples/wallets/examples/ledger.rs diff --git a/examples/local_signer.rs b/examples/wallets/examples/local_signer.rs similarity index 84% rename from examples/local_signer.rs rename to examples/wallets/examples/local_signer.rs index 764de4f5..b7193076 100644 --- a/examples/local_signer.rs +++ b/examples/wallets/examples/local_signer.rs @@ -1,4 +1,9 @@ -use ethers::{prelude::*, utils::Anvil}; +use ethers::{ + core::{types::TransactionRequest, utils::Anvil}, + middleware::SignerMiddleware, + providers::{Http, Middleware, Provider}, + signers::{LocalWallet, Signer}, +}; use eyre::Result; use std::convert::TryFrom; diff --git a/examples/mnemonic.rs b/examples/wallets/examples/mnemonic.rs similarity index 87% rename from examples/mnemonic.rs rename to examples/wallets/examples/mnemonic.rs index 2c14b69d..b04aaea9 100644 --- a/examples/mnemonic.rs +++ b/examples/wallets/examples/mnemonic.rs @@ -1,6 +1,10 @@ -use ethers::signers::{coins_bip39::English, MnemonicBuilder}; +use ethers::{ + core::rand, + signers::{coins_bip39::English, MnemonicBuilder}, +}; +use eyre::Result; -fn main() -> eyre::Result<()> { +fn main() -> Result<()> { let phrase = "work man father plunge mystery proud hollow address reunion sauce theory bonus"; let index = 0u32; let password = "TREZOR123"; diff --git a/examples/permit_hash.rs b/examples/wallets/examples/permit_hash.rs similarity index 89% rename from examples/permit_hash.rs rename to examples/wallets/examples/permit_hash.rs index b313b3a5..ac28588c 100644 --- a/examples/permit_hash.rs +++ b/examples/wallets/examples/permit_hash.rs @@ -1,7 +1,9 @@ use ethers::{ contract::{Eip712, EthAbiType}, - core::types::transaction::eip712::Eip712, - types::{Address, U256}, + core::{ + types::{transaction::eip712::Eip712, Address, U256}, + utils::hex, + }, }; // Generate the EIP712 permit hash to sign for a Uniswap V2 pair. diff --git a/examples/sign.rs b/examples/wallets/examples/sign_message.rs similarity index 91% rename from examples/sign.rs rename to examples/wallets/examples/sign_message.rs index 6f6b592e..07d50d87 100644 --- a/examples/sign.rs +++ b/examples/wallets/examples/sign_message.rs @@ -1,9 +1,9 @@ // use the eyre crate for easy idiomatic error handling use eyre::Result; // use the ethers_core rand for rng -use ethers_core::rand::thread_rng; +use ethers::core::rand::thread_rng; // use the ethers_signers crate to manage LocalWallet and Signer -use ethers_signers::{LocalWallet, Signer}; +use ethers::signers::{LocalWallet, Signer}; // Use the `tokio::main` macro for using async on the main function #[tokio::main] diff --git a/examples/trezor.rs b/examples/wallets/examples/trezor.rs similarity index 100% rename from examples/trezor.rs rename to examples/wallets/examples/trezor.rs diff --git a/examples/yubi.rs b/examples/wallets/examples/yubi.rs similarity index 100% rename from examples/yubi.rs rename to examples/wallets/examples/yubi.rs diff --git a/scripts/examples.sh b/scripts/examples.sh index ee50628e..90537870 100755 --- a/scripts/examples.sh +++ b/scripts/examples.sh @@ -1,25 +1,42 @@ -set -e +#!/bin/bash + +set -e; # Fail fast # shellcheck shell=bash # examples that we can't run because they require some additional infra, docker or ledger for example ignored=( - "moonbeam_with_abi" - "ipc" - "ledger" - "paginated_logs" - "subscribe_logs" - "trezor" - "yubi" - "remove_liquidity" + "examples-contracts:deploy_moonbeam" + "examples-providers:ipc" + "examples-wallets:ledger" + "examples-wallets:trezor" + "examples-wallets:yubi" + "examples-transactions:remove_liquidity" ) -# run all examples -for file in examples/*.rs; do - name="$(echo "$file" | cut -f 1 -d '.')" - if [[ "${ignored[*]}" =~ $(basename "$name") ]]; then - echo "skipping: $file" - continue - fi - echo "running: $file" - cargo r -p ethers --example "$(basename "$name")" --features "ethers-solc rustls ws" +example_crates=$(cargo metadata --format-version 1 | + jq -c '.workspace_members' | + jq -r 'map(select(startswith("examples")) | + sub("\\s.*$";"")) | .[]') + +for crate in $example_crates; do + # Remove "examples-" prefix from crate name (e.g. examples-contracts => contracts) + cratedir="${crate#examples-}" + srcdir="examples/$cratedir/examples" + # Retrieve all example files in crate: + # Transform the absolute path into the filename (e.g. some-path/deploy_anvil.rs => deploy_anvil) + example_files=$(find $srcdir -type f -name '*.rs' -exec basename {} \; | sed 's/\.[^.]*$//') + + for file in $example_files; do + # Build the example + echo "Building example: $crate:$file" + cargo build -p $crate --example $file + + # Run the example + if [[ "${ignored[*]}" =~ $(basename "$crate:$file") ]]; then + echo "skipping: $crate:$file" + continue + fi + echo "running $crate:$file" + cargo run -p $crate --example $file + done done From fcef7c70ad8163f53732069eddc544ab254891fd Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 30 Dec 2022 11:46:52 +0100 Subject: [PATCH 31/40] fix: gwei wei wrong u256 constant (#1992) --- ethers-middleware/src/gas_oracle/mod.rs | 14 +++++++++++++- ethers-middleware/src/gas_oracle/polygon.rs | 13 ++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ethers-middleware/src/gas_oracle/mod.rs b/ethers-middleware/src/gas_oracle/mod.rs index 9be17750..40c1bf42 100644 --- a/ethers-middleware/src/gas_oracle/mod.rs +++ b/ethers-middleware/src/gas_oracle/mod.rs @@ -37,7 +37,7 @@ use std::{error::Error, fmt::Debug}; use thiserror::Error; pub(crate) const GWEI_TO_WEI: u64 = 1_000_000_000; -pub(crate) const GWEI_TO_WEI_U256: U256 = U256([0, 0, 0, GWEI_TO_WEI]); +pub(crate) const GWEI_TO_WEI_U256: U256 = U256([GWEI_TO_WEI, 0, 0, 0]); pub type Result = std::result::Result; @@ -153,3 +153,15 @@ pub trait GasOracle: Send + Sync + Debug { pub(crate) fn from_gwei_f64(gwei: f64) -> U256 { ethers_core::types::u256_from_f64_saturating(gwei) * GWEI_TO_WEI_U256 } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_gwei_wei_constants() { + let as_u256: U256 = GWEI_TO_WEI.into(); + assert_eq!(as_u256, GWEI_TO_WEI_U256); + assert_eq!(GWEI_TO_WEI_U256.as_u64(), GWEI_TO_WEI); + } +} diff --git a/ethers-middleware/src/gas_oracle/polygon.rs b/ethers-middleware/src/gas_oracle/polygon.rs index 5fd63545..f7acf85a 100644 --- a/ethers-middleware/src/gas_oracle/polygon.rs +++ b/ethers-middleware/src/gas_oracle/polygon.rs @@ -20,7 +20,7 @@ pub struct Polygon { /// The response from the Polygon gas station API. /// -/// Gas prices are in Gwei. +/// Gas prices are in __Gwei__. #[derive(Debug, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct Response { @@ -103,3 +103,14 @@ impl Polygon { Ok(response) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_polygon_gas_station_response() { + let s = r#"{"safeLow":{"maxPriorityFee":2.1267086610666666,"maxFee":2.1267086760666665},"standard":{"maxPriorityFee":2.3482958369333335,"maxFee":2.3482958519333335},"fast":{"maxPriorityFee":2.793454819,"maxFee":2.793454834},"estimatedBaseFee":1.5e-8,"blockTime":2,"blockNumber":30328888}"#; + let _resp: Response = serde_json::from_str(s).unwrap(); + } +} From 48dbbbd829c3a8c8651cec9b7e398f75ef454086 Mon Sep 17 00:00:00 2001 From: Georgios Konstantopoulos Date: Fri, 30 Dec 2022 14:18:58 +0200 Subject: [PATCH 32/40] chore: clippy --- ethers-core/src/macros/ethers_crate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethers-core/src/macros/ethers_crate.rs b/ethers-core/src/macros/ethers_crate.rs index 78bc38d8..2c33eb5c 100644 --- a/ethers-core/src/macros/ethers_crate.rs +++ b/ethers-core/src/macros/ethers_crate.rs @@ -63,7 +63,7 @@ pub fn determine_ethers_crates() -> (&'static str, &'static str, &'static str) { let needs_lock_file_cleanup = !std::path::Path::new(&lock_file).exists(); let res = MetadataCommand::new() - .manifest_path(&format!("{manifest_dir}/Cargo.toml")) + .manifest_path(format!("{manifest_dir}/Cargo.toml")) .exec() .ok() .and_then(|metadata| { From c5ff7337028e29cb127b7b78df374a19fe40adcd Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 30 Dec 2022 13:19:41 +0100 Subject: [PATCH 33/40] chore: clippy (#1990) * chore: clippy * chore: clippy --- ethers-solc/benches/compile_many.rs | 1 - ethers-solc/src/artifacts/ast/mod.rs | 4 ++-- ethers-solc/src/compile/mod.rs | 2 +- ethers-solc/src/resolver/mod.rs | 2 +- examples/middleware/examples/create_custom_middleware.rs | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ethers-solc/benches/compile_many.rs b/ethers-solc/benches/compile_many.rs index b667a6b9..b0df3c7a 100644 --- a/ethers-solc/benches/compile_many.rs +++ b/ethers-solc/benches/compile_many.rs @@ -36,7 +36,6 @@ fn load_compiler_inputs() -> Vec { let mut inputs = Vec::new(); for file in std::fs::read_dir(Path::new(&env!("CARGO_MANIFEST_DIR")).join("test-data/in")) .unwrap() - .into_iter() .take(5) { let file = file.unwrap(); diff --git a/ethers-solc/src/artifacts/ast/mod.rs b/ethers-solc/src/artifacts/ast/mod.rs index 82e01a2b..be83cd00 100644 --- a/ethers-solc/src/artifacts/ast/mod.rs +++ b/ethers-solc/src/artifacts/ast/mod.rs @@ -1089,11 +1089,11 @@ mod tests { let result: Result = serde_path_to_error::deserialize(deserializer); match result { Err(e) => { - println!("... {} fail: {e}", path_str); + println!("... {path_str} fail: {e}"); panic!(); } Ok(_) => { - println!("... {} ok", path_str); + println!("... {path_str} ok"); } } }) diff --git a/ethers-solc/src/compile/mod.rs b/ethers-solc/src/compile/mod.rs index fe40cfb9..b34913fe 100644 --- a/ethers-solc/src/compile/mod.rs +++ b/ethers-solc/src/compile/mod.rs @@ -457,7 +457,7 @@ impl Solc { use sha2::Digest; let mut hasher = sha2::Sha256::new(); - hasher.update(&content); + hasher.update(content); let checksum_calc = &hasher.finalize()[..]; let checksum_found = &RELEASES.0.get_checksum(&version).expect("checksum not found"); diff --git a/ethers-solc/src/resolver/mod.rs b/ethers-solc/src/resolver/mod.rs index eceba2e1..848713ad 100644 --- a/ethers-solc/src/resolver/mod.rs +++ b/ethers-solc/src/resolver/mod.rs @@ -649,7 +649,7 @@ impl Graph { return Vec::new() } - let mut result = sets.pop().cloned().expect("not empty; qed.").clone(); + let mut result = sets.pop().cloned().expect("not empty; qed."); if !sets.is_empty() { result.retain(|item| sets.iter().all(|set| set.contains(item))); } diff --git a/examples/middleware/examples/create_custom_middleware.rs b/examples/middleware/examples/create_custom_middleware.rs index 7e19ee3a..56a4a21d 100644 --- a/examples/middleware/examples/create_custom_middleware.rs +++ b/examples/middleware/examples/create_custom_middleware.rs @@ -92,7 +92,7 @@ where }; println!("Original transaction gas: {curr_gas:?} wei"); - let units: U256 = U256::exp10(CONTINGENCY_UNITS.into()); + let units: U256 = U256::exp10(CONTINGENCY_UNITS); let raised_gas: U256 = (curr_gas * self.contingency) / units; tx.set_gas(raised_gas); println!("Raised transaction gas: {raised_gas:?} wei"); From a42cc9f63f861a8979794d6b167bad05c388a5fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Dec 2022 14:43:05 +0200 Subject: [PATCH 34/40] chore(deps): bump once_cell from 1.16.0 to 1.17.0 (#1987) Bumps [once_cell](https://github.com/matklad/once_cell) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/matklad/once_cell/releases) - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: once_cell dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- ethers-addressbook/Cargo.toml | 2 +- ethers-contract/Cargo.toml | 2 +- ethers-core/Cargo.toml | 4 ++-- ethers-middleware/Cargo.toml | 2 +- ethers-providers/Cargo.toml | 2 +- ethers-solc/Cargo.toml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbb66218..f6f73319 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2721,9 +2721,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "oorandom" diff --git a/ethers-addressbook/Cargo.toml b/ethers-addressbook/Cargo.toml index 17907527..3e491ffc 100644 --- a/ethers-addressbook/Cargo.toml +++ b/ethers-addressbook/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/gakonst/ethers-rs" keywords = ["ethereum", "web3", "celo", "ethers"] [dependencies] -once_cell = "1.16.0" +once_cell = "1.17.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/ethers-contract/Cargo.toml b/ethers-contract/Cargo.toml index 821fe3bf..aa9cb7ca 100644 --- a/ethers-contract/Cargo.toml +++ b/ethers-contract/Cargo.toml @@ -20,7 +20,7 @@ ethers-derive-eip712 = { version = "^1.0.0", path = "../ethers-core/ethers-deriv serde = { version = "1.0.124", default-features = false } serde_json = { version = "1.0.64", default-features = false } thiserror = { version = "1.0", default-features = false } -once_cell = { version = "1.16.0" } +once_cell = { version = "1.17.0" } pin-project = { version = "1.0.11", default-features = false } futures-util = { version = "^0.3" } hex = { version = "0.4.3", default-features = false, features = ["std"] } diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml index fbf0e92d..f1bb1692 100644 --- a/ethers-core/Cargo.toml +++ b/ethers-core/Cargo.toml @@ -31,7 +31,7 @@ serde_json = { version = "1.0.64", default-features = false, features = ["arbitr thiserror = { version = "1.0", default-features = false } bytes = { version = "1.3.0", features = ["serde"] } hex = { version = "0.4.3", default-features = false, features = ["std"] } -once_cell = { version = "1.16.0", optional = true } +once_cell = { version = "1.17.0", optional = true } unicode-xid = "0.2.4" strum = { version = "0.24", features = ["derive"] } @@ -48,7 +48,7 @@ num_enum = "0.5.7" tempfile = { version = "3.3.0", default-features = false } serde_json = { version = "1.0.64", default-features = false } bincode = { version = "1.3.3", default-features = false } -once_cell = { version = "1.16.0" } +once_cell = { version = "1.17.0" } hex-literal = "0.3.4" rand = "0.8.5" diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml index 2518a21d..1deadae5 100644 --- a/ethers-middleware/Cargo.toml +++ b/ethers-middleware/Cargo.toml @@ -47,7 +47,7 @@ ethers-providers = { version = "^1.0.0", path = "../ethers-providers", default-f "ws", "rustls", ] } -once_cell = "1.16.0" +once_cell = "1.17.0" ethers-solc = { version = "^1.0.0", path = "../ethers-solc" } serial_test = "0.10.0" reqwest = { version = "0.11.13", default-features = false, features = ["json", "rustls"] } diff --git a/ethers-providers/Cargo.toml b/ethers-providers/Cargo.toml index d11f4f81..2e3798d3 100644 --- a/ethers-providers/Cargo.toml +++ b/ethers-providers/Cargo.toml @@ -43,7 +43,7 @@ tracing = { version = "0.1.37", default-features = false } tracing-futures = { version = "0.2.5", default-features = false, features = ["std-future"] } bytes = { version = "1.3.0", default-features = false, optional = true } -once_cell = "1.16.0" +once_cell = "1.17.0" hashers = "1.0.1" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index 66002fd5..db2c4955 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -23,7 +23,7 @@ semver = { version = "1.0.16", features = ["serde"] } walkdir = "2.3.2" tokio = { version = "1.18", default-features = false, features = ["rt"] } futures-util = { version = "^0.3", optional = true } -once_cell = "1.16.0" +once_cell = "1.17.0" regex = "1.7.0" md-5 = "0.10.5" thiserror = "1.0" From 4274a27531b73d142470114f4fe14612e4225477 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 30 Dec 2022 13:43:49 +0100 Subject: [PATCH 35/40] fix(examples): deprecated gas oracle (#1986) --- examples/middleware/examples/builder.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/middleware/examples/builder.rs b/examples/middleware/examples/builder.rs index f8c54ad4..c9fb058a 100644 --- a/examples/middleware/examples/builder.rs +++ b/examples/middleware/examples/builder.rs @@ -1,6 +1,10 @@ use ethers::{ core::types::BlockNumber, - middleware::{gas_escalator::*, gas_oracle::*, *}, + middleware::{ + gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice}, + gas_oracle::{GasNow, GasOracleMiddleware}, + MiddlewareBuilder, NonceManagerMiddleware, SignerMiddleware, + }, providers::{Http, Middleware, Provider}, signers::{LocalWallet, Signer}, }; @@ -24,7 +28,7 @@ async fn builder_example() { let signer = SIGNING_KEY.parse::().unwrap(); let address = signer.address(); let escalator = GeometricGasPrice::new(1.125, 60_u64, None::); - let gas_oracle = EthGasStation::new(None); + let gas_oracle = GasNow::new(); let provider = Provider::::try_from(RPC_URL) .unwrap() @@ -48,7 +52,7 @@ async fn builder_example_raw_wrap() { .unwrap() .wrap_into(|p| GasEscalatorMiddleware::new(p, escalator, Frequency::PerBlock)) .wrap_into(|p| SignerMiddleware::new(p, signer)) - .wrap_into(|p| GasOracleMiddleware::new(p, EthGasStation::new(None))) + .wrap_into(|p| GasOracleMiddleware::new(p, GasNow::new())) .wrap_into(|p| NonceManagerMiddleware::new(p, address)); // Outermost layer match provider.get_block(BlockNumber::Latest).await { From 69e0ff73017347ee15727d8ed60cafd4c41a0201 Mon Sep 17 00:00:00 2001 From: Akram Hussein Date: Fri, 30 Dec 2022 09:44:03 -0300 Subject: [PATCH 36/40] fix: doc typo regarding Multicall::call_array (#1985) --- ethers-contract/src/multicall/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethers-contract/src/multicall/mod.rs b/ethers-contract/src/multicall/mod.rs index 56dca427..0b5bc56f 100644 --- a/ethers-contract/src/multicall/mod.rs +++ b/ethers-contract/src/multicall/mod.rs @@ -661,7 +661,7 @@ impl Multicall { /// # /// # let multicall = Multicall::new(client, None).await?; /// // If the all Solidity function calls `returns (uint256)`: - /// let result: Vec = multicall.call().await?; + /// let result: Vec = multicall.call_array().await?; /// # Ok(()) /// # } /// ``` From f94e6f549f933f3a05d3c19e17bdf7e2dc01f8e5 Mon Sep 17 00:00:00 2001 From: 0xKitsune <77890308+0xKitsune@users.noreply.github.com> Date: Fri, 30 Dec 2022 07:45:19 -0500 Subject: [PATCH 37/40] added `from_bytes` for `Wallet` type (#1983) * added `from_bytes` for `Wallet` type * added key_from_bytes test for Wallet::from_bytes * updated changelog --- CHANGELOG.md | 1 + ethers-signers/src/wallet/private_key.rs | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a623363..c5a0d996 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -275,6 +275,7 @@ - `eth-keystore-rs` crate updated. Allow an optional name for the to-be-generated keystore file [#910](https://github.com/gakonst/ethers-rs/pull/910) +- [1983](https://github.com/gakonst/ethers-rs/pull/1983) Added a `from_bytes` function for the `Wallet` type. ### 0.6.0 diff --git a/ethers-signers/src/wallet/private_key.rs b/ethers-signers/src/wallet/private_key.rs index cdddf00a..ed10949c 100644 --- a/ethers-signers/src/wallet/private_key.rs +++ b/ethers-signers/src/wallet/private_key.rs @@ -90,6 +90,13 @@ impl Wallet { let address = secret_key_to_address(&signer); Self { signer, address, chain_id: 1 } } + + /// Creates a new Wallet instance from a raw scalar value (big endian). + pub fn from_bytes(bytes: &[u8]) -> Result { + let signer = SigningKey::from_bytes(bytes)?; + let address = secret_key_to_address(&signer); + Ok(Self { signer, address, chain_id: 1 }) + } } impl PartialEq for Wallet { @@ -305,4 +312,17 @@ mod tests { Address::from_str("6813Eb9362372EEF6200f3b1dbC3f819671cBA69").expect("Decoding failed") ); } + + #[test] + fn key_from_bytes() { + let wallet: Wallet = + "0000000000000000000000000000000000000000000000000000000000000001".parse().unwrap(); + + let key_as_bytes = wallet.signer.to_bytes(); + let wallet_from_bytes = Wallet::from_bytes(&key_as_bytes).unwrap(); + + assert_eq!(wallet.address, wallet_from_bytes.address); + assert_eq!(wallet.chain_id, wallet_from_bytes.chain_id); + assert_eq!(wallet.signer, wallet_from_bytes.signer); + } } From d27231848392199f5d52e3730bd20170546ce305 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 30 Dec 2022 13:48:29 +0100 Subject: [PATCH 38/40] chore: update all rust editions to 2021 (#1979) --- ethers-contract/ethers-contract-abigen/Cargo.toml | 3 ++- ethers-contract/ethers-contract-derive/Cargo.toml | 3 ++- ethers-core/Cargo.toml | 4 ++-- ethers-core/ethers-derive-eip712/Cargo.toml | 8 ++++++-- ethers-etherscan/Cargo.toml | 2 +- ethers-middleware/Cargo.toml | 2 +- ethers-providers/Cargo.toml | 2 +- ethers-signers/Cargo.toml | 2 +- ethers-solc/Cargo.toml | 2 +- examples/ethers-wasm/Cargo.toml | 2 +- 10 files changed, 18 insertions(+), 12 deletions(-) diff --git a/ethers-contract/ethers-contract-abigen/Cargo.toml b/ethers-contract/ethers-contract-abigen/Cargo.toml index f69e2f69..164d8b9e 100644 --- a/ethers-contract/ethers-contract-abigen/Cargo.toml +++ b/ethers-contract/ethers-contract-abigen/Cargo.toml @@ -1,11 +1,12 @@ [package] name = "ethers-contract-abigen" version = "1.0.2" +edition = "2021" +rust-version = "1.64" authors = [ "Nicholas Rodrigues Lordello ", "Georgios Konstantopoulos ", ] -edition = "2018" license = "MIT OR Apache-2.0" description = "Code generation for type-safe bindings to Ethereum smart contracts" homepage = "https://docs.rs/ethers" diff --git a/ethers-contract/ethers-contract-derive/Cargo.toml b/ethers-contract/ethers-contract-derive/Cargo.toml index 1c49c995..0191d2f5 100644 --- a/ethers-contract/ethers-contract-derive/Cargo.toml +++ b/ethers-contract/ethers-contract-derive/Cargo.toml @@ -1,11 +1,12 @@ [package] name = "ethers-contract-derive" version = "1.0.2" +edition = "2021" +rust-version = "1.64" authors = [ "Nicholas Rodrigues Lordello ", "Georgios Konstantopoulos ", ] -edition = "2018" license = "MIT OR Apache-2.0" description = "Proc macro for type-safe bindings generation to Ethereum and Celo smart contracts" homepage = "https://docs.rs/ethers" diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml index f1bb1692..8aa21a6f 100644 --- a/ethers-core/Cargo.toml +++ b/ethers-core/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "ethers-core" -license = "MIT OR Apache-2.0" version = "1.0.2" +edition = "2021" rust-version = "1.64" authors = ["Georgios Konstantopoulos "] -edition = "2018" +license = "MIT OR Apache-2.0" description = "Core structures for the ethers-rs crate" homepage = "https://docs.rs/ethers" repository = "https://github.com/gakonst/ethers-rs" diff --git a/ethers-core/ethers-derive-eip712/Cargo.toml b/ethers-core/ethers-derive-eip712/Cargo.toml index 305bfcfd..61073774 100644 --- a/ethers-core/ethers-derive-eip712/Cargo.toml +++ b/ethers-core/ethers-derive-eip712/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "ethers-derive-eip712" version = "1.0.2" -edition = "2018" +edition = "2021" +rust-version = "1.64" description = "Custom derive macro for EIP-712 typed data" license = "MIT OR Apache-2.0" @@ -11,7 +12,10 @@ proc-macro = true [dependencies] quote = "1.0.9" syn = "1.0.77" -ethers-core = { version = "^1.0.0", path = "../", default-features = false, features = ["eip712", "macros"] } +ethers-core = { version = "^1.0.0", path = "../", default-features = false, features = [ + "eip712", + "macros", +] } hex = "0.4.3" serde_json = "1.0.68" diff --git a/ethers-etherscan/Cargo.toml b/ethers-etherscan/Cargo.toml index abea9a1e..8de6d5ac 100644 --- a/ethers-etherscan/Cargo.toml +++ b/ethers-etherscan/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "ethers-etherscan" version = "1.0.2" +edition = "2021" rust-version = "1.64" authors = [ "Matthias Seitz ", "Georgios Konstantopoulos ", ] license = "MIT OR Apache-2.0" -edition = "2018" readme = "../README.md" documentation = "https://docs.rs/ethers" repository = "https://github.com/gakonst/ethers-rs" diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml index 1deadae5..08c79162 100644 --- a/ethers-middleware/Cargo.toml +++ b/ethers-middleware/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-middleware" version = "1.0.2" -edition = "2018" +edition = "2021" rust-version = "1.64" authors = ["Georgios Konstantopoulos "] license = "MIT OR Apache-2.0" diff --git a/ethers-providers/Cargo.toml b/ethers-providers/Cargo.toml index 2e3798d3..e3117d68 100644 --- a/ethers-providers/Cargo.toml +++ b/ethers-providers/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-providers" version = "1.0.2" -edition = "2018" +edition = "2021" rust-version = "1.64" authors = ["Georgios Konstantopoulos "] license = "MIT OR Apache-2.0" diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml index 02c2bab1..8a25e34f 100644 --- a/ethers-signers/Cargo.toml +++ b/ethers-signers/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-signers" version = "1.0.2" -edition = "2018" +edition = "2021" rust-version = "1.64" authors = ["Georgios Konstantopoulos "] license = "MIT OR Apache-2.0" diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml index db2c4955..3555e1b4 100644 --- a/ethers-solc/Cargo.toml +++ b/ethers-solc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-solc" version = "1.0.2" -edition = "2018" +edition = "2021" rust-version = "1.64" authors = [ "Matthias Seitz ", diff --git a/examples/ethers-wasm/Cargo.toml b/examples/ethers-wasm/Cargo.toml index 181e0f81..6ca4f575 100644 --- a/examples/ethers-wasm/Cargo.toml +++ b/examples/ethers-wasm/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ethers-wasm" version = "0.1.0" -edition = "2018" +edition = "2021" rust-version = "1.64" authors = ["Matthias Seitz "] license = "MIT OR Apache-2.0" From 228f9607fe63977895dadf999f0f41c48a9780ab Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Fri, 30 Dec 2022 07:48:47 -0500 Subject: [PATCH 39/40] feat(core): expose all genesis related structs (#1975) --- ethers-core/src/utils/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethers-core/src/utils/mod.rs b/ethers-core/src/utils/mod.rs index 5a2e1315..ff5ca22a 100644 --- a/ethers-core/src/utils/mod.rs +++ b/ethers-core/src/utils/mod.rs @@ -12,7 +12,7 @@ pub use geth::{Geth, GethInstance}; /// Utilities for working with a `genesis.json` and other chain config structs. mod genesis; -pub use genesis::{ChainConfig, Genesis}; +pub use genesis::{ChainConfig, CliqueConfig, EthashConfig, Genesis, GenesisAccount}; /// Utilities for launching an anvil instance #[cfg(not(target_arch = "wasm32"))] From fd4da49121b0d5bf2f3648a3faed2da57374a6b0 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Sat, 31 Dec 2022 11:47:53 +0100 Subject: [PATCH 40/40] tests: use sepolia (#1989) * tests: use sepolia * update ci * update sleep duration * deprecate ropsten * use goerli * fmt * keys --- ethers-middleware/tests/gas_escalator.rs | 3 ++- ethers-middleware/tests/nonce_manager.rs | 6 +++--- ethers-middleware/tests/signer.rs | 2 +- ethers-providers/src/lib.rs | 21 ++++++++++++--------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/ethers-middleware/tests/gas_escalator.rs b/ethers-middleware/tests/gas_escalator.rs index c2bfbad6..66d7d4ff 100644 --- a/ethers-middleware/tests/gas_escalator.rs +++ b/ethers-middleware/tests/gas_escalator.rs @@ -13,6 +13,7 @@ use std::time::Duration; #[ignore] async fn gas_escalator_live() { // connect to ropsten for getting bad block times + #[allow(deprecated)] let provider = ethers_providers::ROPSTEN.ws().await; let provider = provider.interval(Duration::from_millis(2000u64)); let wallet = "fdb33e2105f08abe41a8ee3b758726a31abdd57b7a443f470f23efce853af169" @@ -34,7 +35,7 @@ async fn gas_escalator_live() { provider.send_transaction(tx.clone().nonce(nonce + 2), None).await.unwrap(); // Wait a bunch of seconds and refresh etherscan to see the transactions get bumped - tokio::time::sleep(std::time::Duration::from_secs(100)).await; + tokio::time::sleep(Duration::from_secs(100)).await; // TODO: Figure out how to test this behavior properly in a local network. If the gas price was // bumped then the tx hash will be different diff --git a/ethers-middleware/tests/nonce_manager.rs b/ethers-middleware/tests/nonce_manager.rs index a1c74915..1be27fec 100644 --- a/ethers-middleware/tests/nonce_manager.rs +++ b/ethers-middleware/tests/nonce_manager.rs @@ -8,7 +8,7 @@ use std::time::Duration; #[tokio::test] async fn nonce_manager() { - let provider = ethers_providers::GOERLI.provider().interval(Duration::from_millis(2000u64)); + let provider = ethers_providers::GOERLI.provider().interval(Duration::from_millis(2000)); let chain_id = provider.get_chainid().await.unwrap().as_u64(); let wallet = std::env::var("GOERLI_PRIVATE_KEY") @@ -44,12 +44,12 @@ async fn nonce_manager() { } // sleep a bit to ensure there's no flakiness in the test - std::thread::sleep(std::time::Duration::new(5, 0)); + tokio::time::sleep(Duration::from_secs(10)).await; let mut nonces = Vec::with_capacity(num_tx); for tx_hash in tx_hashes { nonces.push(provider.get_transaction(tx_hash).await.unwrap().unwrap().nonce.as_u64()); } - assert_eq!(nonces, (nonce..nonce + (num_tx as u64)).collect::>()) + assert_eq!(nonces, (nonce..nonce + num_tx as u64).collect::>()) } diff --git a/ethers-middleware/tests/signer.rs b/ethers-middleware/tests/signer.rs index 9c2176ed..eecd1e65 100644 --- a/ethers-middleware/tests/signer.rs +++ b/ethers-middleware/tests/signer.rs @@ -294,7 +294,7 @@ impl TestWallets { #[allow(unused)] pub async fn fund>(&self, provider: &Provider, n: U) { let addrs = (0..n.into()).map(|i| self.get(i).address()).collect::>(); - // hardcoded funder address private key, goerli + // hardcoded funder address private key, GOERLI let signer = "39aa18eeb5d12c071e5f19d8e9375a872e90cb1f2fa640384ffd8800a2f3e8f1" .parse::() .unwrap() diff --git a/ethers-providers/src/lib.rs b/ethers-providers/src/lib.rs index b7825682..31ef49fe 100644 --- a/ethers-providers/src/lib.rs +++ b/ethers-providers/src/lib.rs @@ -723,7 +723,8 @@ pub trait CeloMiddleware: Middleware { } } -pub use test_provider::{GOERLI, MAINNET, ROPSTEN}; +#[allow(deprecated)] +pub use test_provider::{GOERLI, MAINNET, ROPSTEN, SEPOLIA}; /// Pre-instantiated Infura HTTP clients which rotate through multiple API keys /// to prevent rate limits @@ -743,9 +744,13 @@ pub mod test_provider { "5c812e02193c4ba793f8c214317582bd", ]; - pub static GOERLI: Lazy = Lazy::new(|| TestProvider::new(INFURA_KEYS, "goerli")); pub static MAINNET: Lazy = Lazy::new(|| TestProvider::new(INFURA_KEYS, "mainnet")); + pub static GOERLI: Lazy = Lazy::new(|| TestProvider::new(INFURA_KEYS, "goerli")); + pub static SEPOLIA: Lazy = + Lazy::new(|| TestProvider::new(INFURA_KEYS, "sepolia")); + + #[deprecated = "Ropsten testnet has been deprecated in favor of Goerli or Sepolia."] pub static ROPSTEN: Lazy = Lazy::new(|| TestProvider::new(INFURA_KEYS, "ropsten")); @@ -756,16 +761,14 @@ pub mod test_provider { } impl TestProvider { - pub fn new(keys: &'static [&'static str], network: &str) -> Self { - Self { keys: Mutex::new(keys.iter().cycle()), network: network.to_owned() } + pub fn new(keys: &'static [&'static str], network: impl Into) -> Self { + Self { keys: keys.iter().cycle().into(), network: network.into() } } pub fn url(&self) -> String { - format!( - "https://{}.infura.io/v3/{}", - self.network, - self.keys.lock().unwrap().next().unwrap() - ) + let Self { network, keys } = self; + let key = keys.lock().unwrap().next().unwrap(); + format!("https://{network}.infura.io/v3/{key}") } pub fn provider(&self) -> Provider {