diff --git a/ethers-middleware/Cargo.toml b/ethers-middleware/Cargo.toml index ca8cdd37f..16e37f764 100644 --- a/ethers-middleware/Cargo.toml +++ b/ethers-middleware/Cargo.toml @@ -14,7 +14,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -ethers-contract = { version = "^0.13.0", path = "../ethers-contract", default-features = false, features = ["abigen"] } +ethers-contract = { version = "^0.13.0", path = "../ethers-contract", default-features = false } ethers-core = { version = "^0.13.0", path = "../ethers-core", default-features = false } ethers-etherscan = { version = "^0.13.0", path = "../ethers-etherscan", default-features = false } ethers-providers = { version = "^0.13.0", path = "../ethers-providers", default-features = false } @@ -43,7 +43,7 @@ hex = { version = "0.4.3", default-features = false, features = ["std"] } rand = { version = "0.8.5", default-features = false } ethers-providers = { version = "^0.13.0", path = "../ethers-providers", default-features = false, features = ["ws", "rustls"] } once_cell = "1.13.0" -ethers-solc = { version = "^0.13.0", path = "../ethers-solc", default-features = false } +ethers-solc = { version = "^0.13.0", path = "../ethers-solc" } serial_test = "0.8.0" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] diff --git a/ethers-middleware/src/transformer/ds_proxy/factory.rs b/ethers-middleware/src/transformer/ds_proxy/factory.rs index 8de0c88fd..c6f0561d0 100644 --- a/ethers-middleware/src/transformer/ds_proxy/factory.rs +++ b/ethers-middleware/src/transformer/ds_proxy/factory.rs @@ -37,12 +37,16 @@ mod dsproxyfactory_mod { Contract, EthEvent, Lazy, }; use ethers_core::{ - abi::{parse_abi, Abi, Detokenize, InvalidOutputType, Token, Tokenizable}, + abi::{ + parse_abi, Abi, Detokenize, InvalidOutputType, ParamType, Token, Tokenizable, + TokenizableItem, + }, types::*, }; use ethers_providers::Middleware; #[doc = "DsProxyFactory was auto-generated with ethers-rs Abigen. More information at: https://github.com/gakonst/ethers-rs"] use std::sync::Arc; + pub static DSPROXYFACTORY_ABI: Lazy = Lazy::new(|| { serde_json :: from_str ("[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"isProxy\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cache\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"build\",\"outputs\":[{\"name\":\"proxy\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"build\",\"outputs\":[{\"name\":\"proxy\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"proxy\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"cache\",\"type\":\"address\"}],\"name\":\"Created\",\"type\":\"event\"}]\n") . expect ("invalid abi") }); @@ -78,18 +82,13 @@ mod dsproxyfactory_mod { .expect("method not found (this should never happen)") } ///Calls the contract's `build` (0x8e1a55fc) function - pub fn build_with_sender( - &self, - ) -> ethers_contract::builders::ContractCall { + pub fn build_with_sender(&self) -> ContractCall { self.0 .method_hash([142, 26, 85, 252], ()) .expect("method not found (this should never happen)") } ///Calls the contract's `build` (0xf3701da2) function - pub fn build( - &self, - owner: ethers_core::types::Address, - ) -> ethers_contract::builders::ContractCall { + pub fn build(&self, owner: Address) -> ContractCall { self.0 .method_hash([243, 112, 29, 162], owner) .expect("method not found (this should never happen)") @@ -101,24 +100,107 @@ mod dsproxyfactory_mod { .expect("method not found (this should never happen)") } ///Gets the contract's `Created` event - pub fn created_filter(&self) -> ethers_contract::builders::Event { + pub fn created_filter(&self) -> Event { self.0.event() } /// Returns an [`Event`](ethers_contract::builders::Event) builder for all events of this /// contract - pub fn events(&self) -> ethers_contract::builders::Event { + pub fn events(&self) -> Event { self.0.event_with_filter(Default::default()) } } - #[derive(Clone, Debug, Default, Eq, PartialEq, EthEvent)] - #[ethevent(name = "Created")] + + #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct CreatedFilter { - #[ethevent(indexed)] pub sender: Address, - #[ethevent(indexed)] pub owner: Address, pub proxy: Address, pub cache: Address, } + + impl ethers_core::abi::AbiType for CreatedFilter { + fn param_type() -> ParamType { + ParamType::Tuple(::std::vec![ + ParamType::Address; 4 + ]) + } + } + impl ethers_core::abi::AbiArrayType for CreatedFilter {} + + impl Tokenizable for CreatedFilter { + fn from_token(token: Token) -> Result + where + Self: Sized, + { + if let Token::Tuple(tokens) = token { + if tokens.len() != 4usize { + return Err(InvalidOutputType(format!( + "Expected {} tokens, got {}: {:?}", + 4usize, + tokens.len(), + tokens + ))) + } + let mut iter = tokens.into_iter(); + Ok(Self { + sender: Tokenizable::from_token(iter.next().unwrap())?, + owner: Tokenizable::from_token(iter.next().unwrap())?, + proxy: Tokenizable::from_token(iter.next().unwrap())?, + cache: Tokenizable::from_token(iter.next().unwrap())?, + }) + } else { + Err(InvalidOutputType(format!("Expected Tuple, got {:?}", token))) + } + } + fn into_token(self) -> Token { + Token::Tuple(::std::vec![ + self.sender.into_token(), + self.owner.into_token(), + self.proxy.into_token(), + self.cache.into_token(), + ]) + } + } + impl TokenizableItem for CreatedFilter {} + + impl ethers_contract::EthEvent for CreatedFilter { + fn name() -> std::borrow::Cow<'static, str> { + "Created".into() + } + fn signature() -> H256 { + H256([ + 37, 155, 48, 202, 57, 136, 92, 109, 128, 26, 11, 93, 188, 152, 134, 64, 243, 194, + 94, 47, 55, 83, 31, 225, 56, 197, 197, 175, 137, 85, 212, 27, + ]) + } + fn abi_signature() -> std::borrow::Cow<'static, str> { + "Created(address,address,address,address)".into() + } + fn decode_log(log: ðers_core::abi::RawLog) -> Result + where + Self: Sized, + { + let ethers_core::abi::RawLog { data, topics } = log; + let event_signature = topics.get(0).ok_or(ethers_core::abi::Error::InvalidData)?; + if event_signature != &Self::signature() { + return Err(ethers_core::abi::Error::InvalidData) + } + let topic_types = ::std::vec![ParamType::Address, ParamType::Address]; + let data_types = [ParamType::Address, ParamType::Address]; + let flat_topics = + topics.iter().skip(1).flat_map(|t| t.as_ref().to_vec()).collect::>(); + let topic_tokens = ethers_core::abi::decode(&topic_types, &flat_topics)?; + if topic_tokens.len() != topics.len() - 1 { + return Err(ethers_core::abi::Error::InvalidData) + } + let data_tokens = ethers_core::abi::decode(&data_types, data)?; + let tokens: Vec<_> = topic_tokens.into_iter().chain(data_tokens.into_iter()).collect(); + Tokenizable::from_token(Token::Tuple(tokens)) + .map_err(|_| ethers_core::abi::Error::InvalidData) + } + fn is_anonymous() -> bool { + false + } + } }