From d39c02474d72dd6d0adcbd19a81b9aa9f133c530 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Fri, 4 Feb 2022 00:08:52 -0800 Subject: [PATCH] flatten before verification (#828) --- Cargo.lock | 1 + ethers-etherscan/Cargo.toml | 1 + ethers-etherscan/resources/IERC20.sol | 15 +++++++++++ .../resources/UniswapExchange.sol | 19 +++----------- ethers-etherscan/src/contract.rs | 25 ++++++++++++------- 5 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 ethers-etherscan/resources/IERC20.sol diff --git a/Cargo.lock b/Cargo.lock index 349db13c..71c6c318 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1262,6 +1262,7 @@ name = "ethers-etherscan" version = "0.2.0" dependencies = [ "ethers-core", + "ethers-solc", "reqwest", "serde", "serde-aux", diff --git a/ethers-etherscan/Cargo.toml b/ethers-etherscan/Cargo.toml index e1f6efa2..aa6880bf 100644 --- a/ethers-etherscan/Cargo.toml +++ b/ethers-etherscan/Cargo.toml @@ -15,6 +15,7 @@ keywords = ["ethereum", "web3", "etherscan", "ethers"] [dependencies] ethers-core = { version = "^0.6.0", path = "../ethers-core", default-features = false } +ethers-solc = { version = "^0.1.0", path = "../ethers-solc", default-features = false } reqwest = { version = "0.11.9", default-features = false, features = ["json"] } serde = { version = "1.0.124", default-features = false, features = ["derive"] } serde_json = { version = "1.0.64", default-features = false } diff --git a/ethers-etherscan/resources/IERC20.sol b/ethers-etherscan/resources/IERC20.sol new file mode 100644 index 00000000..7d38ff38 --- /dev/null +++ b/ethers-etherscan/resources/IERC20.sol @@ -0,0 +1,15 @@ +interface IERC20 { + function totalSupply() external view returns(uint); + + function balanceOf(address account) external view returns(uint); + + function transfer(address recipient, uint amount) external returns(bool); + + function allowance(address owner, address spender) external view returns(uint); + + function approve(address spender, uint amount) external returns(bool); + + function transferFrom(address sender, address recipient, uint amount) external returns(bool); + event Transfer(address indexed from, address indexed to, uint value); + event Approval(address indexed owner, address indexed spender, uint value); +} diff --git a/ethers-etherscan/resources/UniswapExchange.sol b/ethers-etherscan/resources/UniswapExchange.sol index 4b8ac067..dd13149e 100644 --- a/ethers-etherscan/resources/UniswapExchange.sol +++ b/ethers-etherscan/resources/UniswapExchange.sol @@ -1,23 +1,10 @@ /** - *Submitted for verification at Etherscan.io on 2021-10-03 -*/ + * Submitted for verification at Etherscan.io on 2021-10-03 + */ pragma solidity ^0.5.17; -interface IERC20 { - function totalSupply() external view returns(uint); - function balanceOf(address account) external view returns(uint); - - function transfer(address recipient, uint amount) external returns(bool); - - function allowance(address owner, address spender) external view returns(uint); - - function approve(address spender, uint amount) external returns(bool); - - function transferFrom(address sender, address recipient, uint amount) external returns(bool); - event Transfer(address indexed from, address indexed to, uint value); - event Approval(address indexed owner, address indexed spender, uint value); -} +import "./IERC20.sol"; library Address { function isContract(address account) internal view returns(bool) { diff --git a/ethers-etherscan/src/contract.rs b/ethers-etherscan/src/contract.rs index 634e8469..a7cb2186 100644 --- a/ethers-etherscan/src/contract.rs +++ b/ethers-etherscan/src/contract.rs @@ -262,11 +262,12 @@ impl Client { #[cfg(test)] mod tests { - use std::time::Duration; + use std::{path::PathBuf, time::Duration}; use serial_test::serial; use ethers_core::types::Chain; + use ethers_solc::{MinimalCombinedArtifacts, Project, ProjectPathsConfig}; use crate::{contract::VerifyContract, tests::run_at_least_duration, Client}; @@ -302,26 +303,32 @@ mod tests { #[tokio::test] #[serial] - #[ignore] - async fn can_verify_contract() { + async fn can_flatten_and_verify_contract() { run_at_least_duration(Duration::from_millis(250), async { - // TODO this needs further investigation + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("resources"); + let paths = ProjectPathsConfig::builder() + .sources(&root) + .build() + .expect("failed to resolve project paths"); + let project = Project::::builder() + .paths(paths) + .build() + .expect("failed to build the project"); - // https://etherscan.io/address/0x9e744c9115b74834c0f33f4097f40c02a9ac5c33#code - let contract = include_str!("../resources/UniswapExchange.sol"); let address = "0x9e744c9115b74834c0f33f4097f40c02a9ac5c33".parse().unwrap(); let compiler_version = "v0.5.17+commit.d19bba13"; let constructor_args = "0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000000000007596179537761700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035941590000000000000000000000000000000000000000000000000000000000"; + let contract = project.flatten(&root.join("UniswapExchange.sol")).expect("failed to flatten contract"); let client = Client::new_from_env(Chain::Mainnet).unwrap(); let contract = - VerifyContract::new(address, contract.to_string(), compiler_version.to_string()) + VerifyContract::new(address, contract, compiler_version.to_string()) .constructor_arguments(Some(constructor_args)) .optimization(true) .runs(200); - let _resp = client.submit_contract_verification(&contract).await; - }).await + }) + .await } }