From f1eaee52efbc8bb31cb65b8cc5870c7fec39df0a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 24 Feb 2022 13:07:34 +0100 Subject: [PATCH] feat: add contract code not verified check (#962) --- ethers-contract/ethers-contract-abigen/src/source.rs | 6 +++++- ethers-etherscan/src/contract.rs | 7 +++++-- ethers-etherscan/src/errors.rs | 4 +++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ethers-contract/ethers-contract-abigen/src/source.rs b/ethers-contract/ethers-contract-abigen/src/source.rs index d68df2a1..a3fc1819 100644 --- a/ethers-contract/ethers-contract-abigen/src/source.rs +++ b/ethers-contract/ethers-contract-abigen/src/source.rs @@ -259,7 +259,6 @@ fn get_etherscan_contract(address: Address, domain: &str) -> Result { // NOTE: We do not retrieve the bytecode since deploying contracts with the // same bytecode is unreliable as the libraries have already linked and // probably don't reference anything when deploying on other networks. - let api_key = { let key_res = match domain { "etherscan.io" => env::var("ETHERSCAN_API_KEY").ok(), @@ -276,6 +275,11 @@ fn get_etherscan_contract(address: Address, domain: &str) -> Result { ); let abi = util::http_get(&abi_url).context(format!("failed to retrieve ABI from {}", domain))?; + + if abi.starts_with("Contract source code not verified") { + eyre::bail!("Contract source code not verified: {:?}", address); + } + Ok(abi) } diff --git a/ethers-etherscan/src/contract.rs b/ethers-etherscan/src/contract.rs index a3524b9b..6d7bf431 100644 --- a/ethers-etherscan/src/contract.rs +++ b/ethers-etherscan/src/contract.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use ethers_core::abi::{Abi, Address}; -use crate::{Client, Response, Result}; +use crate::{Client, EtherscanError, Response, Result}; /// Arguments for verifying contracts #[derive(Debug, Clone, Serialize)] @@ -236,6 +236,9 @@ impl Client { pub async fn contract_abi(&self, address: Address) -> Result { let query = self.create_query("contract", "getabi", HashMap::from([("address", address)])); let resp: Response = self.get_json(&query).await?; + if resp.result.starts_with("Contract source code not verified") { + return Err(EtherscanError::ContractCodeNotVerified(address)) + } Ok(serde_json::from_str(&resp.result)?) } @@ -268,7 +271,7 @@ mod tests { use serial_test::serial; use ethers_core::types::Chain; - use ethers_solc::{MinimalCombinedArtifacts, Project, ProjectPathsConfig}; + use ethers_solc::{Project, ProjectPathsConfig}; use crate::{contract::VerifyContract, tests::run_at_least_duration, Client}; diff --git a/ethers-etherscan/src/errors.rs b/ethers-etherscan/src/errors.rs index 8a53ca7a..01b552ad 100644 --- a/ethers-etherscan/src/errors.rs +++ b/ethers-etherscan/src/errors.rs @@ -1,4 +1,4 @@ -use ethers_core::types::Chain; +use ethers_core::types::{Address, Chain}; use std::env::VarError; #[derive(Debug, thiserror::Error)] @@ -19,4 +19,6 @@ pub enum EtherscanError { Reqwest(#[from] reqwest::Error), #[error(transparent)] Serde(#[from] serde_json::Error), + #[error("Contract source code not verified: {0}")] + ContractCodeNotVerified(Address), }