From 5416f307b1ff980fa809b84c70496f296365e6bd Mon Sep 17 00:00:00 2001 From: 0xKoiner Date: Mon, 6 Apr 2026 13:44:21 +0200 Subject: [PATCH 1/5] Pre-built Calldata --- .gitignore | 3 ++- src/data/contracts/registry.rs | 12 ++++++++++++ src/helpers/pre_conditions.rs | 18 ++++++++++++------ src/utils/deploy.rs | 15 +++++++++------ src/utils/verifier.rs | 2 +- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index be7bb84..c6ff3bb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ cache/* out/ .notes.md ks-0x12240F5668f61fd4dF728584206b21d70dD87232 -ks-0xA84E4F9D72cb37A8276090D3FC50895BD8E5Aaf1 \ No newline at end of file +ks-0xA84E4F9D72cb37A8276090D3FC50895BD8E5Aaf1 +.hack.md \ No newline at end of file diff --git a/src/data/contracts/registry.rs b/src/data/contracts/registry.rs index 08206ea..72d40e1 100644 --- a/src/data/contracts/registry.rs +++ b/src/data/contracts/registry.rs @@ -77,6 +77,18 @@ pub const CONTRACTS: &[ContractSpec] = &[ )), verify_json_path: None, }, + ContractSpec { + name: "LivoSwapHook", + address: Some(address!("0x8d02cfe74ce8c1b7133e45fadf39c23b04a7c0cc")), + salt: None, + path: None, + deployer_tx: Some(&hex!( + "000000000000000000000000000000000000000000000000000000000000666160c060405234801561000f575f5ffd5b5060405161183538038061183583398101604081905261002e916102c4565b6001600160a01b0382166080528161004530610058565b506001600160a01b031660a052506102fc565b61014881610143604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915250604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a08101829052600160c0820181905260e0820181905261010082018390526101208201839052610140820181905261016082015261018081018290526101a081019190915290565b61014b565b50565b805115156120008316151514158061016f5750602081015115156110008316151514155b806101865750604081015115156108008316151514155b8061019d5750606081015115156104008316151514155b806101b45750608081015115156102008316151514155b806101cb575060a081015115156101008316151514155b806101e1575060c0810151151560808316151514155b806101f7575060e0810151151560408316151514155b8061020e5750610100810151151560208316151514155b806102255750610120810151151560108316151514155b8061023c5750610140810151151560088316151514155b806102535750610160810151151560048316151514155b8061026a5750610180810151151560028316151514155b8061028157506101a0810151151560018316151514155b1561029757610297630732d7b560e51b8361029b565b5050565b815f526001600160a01b03811660045260245ffd5b6001600160a01b0381168114610148575f5ffd5b5f5f604083850312156102d5575f5ffd5b82516102e0816102b0565b60208401519092506102f1816102b0565b809150509250929050565b60805160a0516114d26103635f395f818161011b0152610d0c01525f818161036f015281816103bc0152818161041f01528181610489015281816104f201528181610552015281816105ba0152818161061d015281816107bb01526109e101526114d25ff3fe6080604052600436106100c2575f3560e01c80639f063efc1161007c578063c4e833ce11610057578063c4e833ce1461025e578063dc4c90d31461035e578063dc98354e14610391578063e1b4af691461023f575f5ffd5b80639f063efc1461019f578063b47b2fb1146101fd578063b6a8b0fa1461023f575f5ffd5b806321d0ee70146100cd578063259982e5146100cd57806351431d4f1461010a578063575e24b4146101555780636c2bbe7e1461019f5780636fe7e6eb146101de575f5ffd5b366100c957005b5f5ffd5b3480156100d8575f5ffd5b506100ec6100e7366004610e81565b6103b0565b6040516001600160e01b031990911681526020015b60405180910390f35b348015610115575f5ffd5b5061013d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610101565b348015610160575f5ffd5b5061017461016f366004610f08565b610411565b604080516001600160e01b03199094168452602084019290925262ffffff1690820152606001610101565b3480156101aa575f5ffd5b506101be6101b9366004610f62565b61047c565b604080516001600160e01b03199093168352602083019190915201610101565b3480156101e9575f5ffd5b506100ec6101f8366004610fed565b6104e6565b348015610208575f5ffd5b5061021c61021736600461104c565b610545565b604080516001600160e01b03199093168352600f9190910b602083015201610101565b34801561024a575f5ffd5b506100ec6102593660046110cd565b6105ae565b348015610269575f5ffd5b50610351604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915250604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a08101829052600160c0820181905260e0820181905261010082018390526101208201839052610140820181905261016082015261018081018290526101a081019190915290565b6040516101019190611127565b348015610369575f5ffd5b5061013d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039c575f5ffd5b506100ec6103ab366004611248565b610611565b5f336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103fa5760405163570c108560e11b815260040160405180910390fd5b610407868686868661066e565b9695505050505050565b5f8080336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461045d5760405163570c108560e11b815260040160405180910390fd5b61046a8888888888610688565b9250925092505b955095509592505050565b5f80336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104c75760405163570c108560e11b815260040160405180910390fd5b6104d689898989898989610889565b9150915097509795505050505050565b5f336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105305760405163570c108560e11b815260040160405180910390fd5b61053c8585858561066e565b95945050505050565b5f80336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105905760405163570c108560e11b815260040160405180910390fd5b61059e8888888888886108a4565b915091505b965096945050505050565b5f336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105f85760405163570c108560e11b815260040160405180910390fd5b61060687878787878761066e565b979650505050505050565b5f336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461065b5760405163570c108560e11b815260040160405180910390fd5b61066684848461066e565b949350505050565b5f604051630a85dc2960e01b815260040160405180910390fd5b5f80808061069c6040890160208a0161128f565b9050806001600160a01b031663e7c2b7726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106fe91906112be565b61071b57604051634eeed17360e11b815260040160405180910390fd5b61072860208801886112d9565b61074257506315d7892d60e21b92505f9150819050610471565b5f6107506020890135611308565b90505f612710610761606484611322565b61076b919061133f565b90505f5f61077a856001610b19565b915091505f8261078a575f6107a5565b61271061079b61ffff841687611322565b6107a5919061133f565b90505f6107b2828661135e565b905080805f5d507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630b0d9c098f5f0160208101906107fa919061128f565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604481018490526064015f604051808303815f87803b158015610845575f5ffd5b505af1158015610857573d5f5f3e3d5ffd5b50505050610866878684610c02565b6315d7892d60e21b9f60809190911b9e505f9d509b505050505050505050505050565b5f5f604051630a85dc2960e01b815260040160405180910390fd5b5f80806108b76040890160208a0161128f565b90506108c660208801886112d9565b15610968575f6108d96020890135611308565b90505f6108e688600f0b90565b6001600160801b03169050326001600160a01b0316836001600160a01b03167f468a22fa2561e8de33b9a775fc9e6624b48dcb7c117cef07ef608b041650ba0484845f5c60405161094a939291909283526020830191909152604082015260600190565b60405180910390a35063b47b2fb160e01b93505f92506105a3915050565b5f6109738760801d90565b6001600160801b031690505f61271061098d606484611322565b610997919061133f565b90505f5f6109a5855f610b19565b915091505f826109b5575f6109d0565b6127106109c661ffff841687611322565b6109d0919061133f565b90505f6109dd828661135e565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630b0d9c098f5f016020810190610a20919061128f565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604481018490526064015f604051808303815f87803b158015610a6b575f5ffd5b505af1158015610a7d573d5f5f3e3d5ffd5b50505050610a8c878684610c02565b5f610a978d600f0b90565b610aa090611371565b604080516001600160801b0392909216808352602083018a9052908201849052915032906001600160a01b038a16907f247558786bc03377d70bed68b0459f5dd2a2d5b00bf2531cab9111b1b13568669060600160405180910390a35063b47b2fb160e01b9f909e509c50505050505050505050505050565b5f5f5f846001600160a01b0316637c922d886040518163ffffffff1660e01b8152600401608060405180830381865afa158015610b58573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b7c91906113c8565b9050806060015164ffffffffff165f03610b9c575f5f9250925050610bfb565b80604001518160600151610bb09190611451565b64ffffffffff16421115610bca575f5f9250925050610bfb565b83610bd9578060200151610bdc565b80515b91508161ffff165f03610bf5575f5f9250925050610bfb565b60019250505b9250929050565b5f610c0e60028461133f565b90505f610c1b828561146e565b90505f610c28848361135e565b60408051848152602081018690529192506001600160a01b038816917f83a48ea337f6cd96ddd4e04f9e08ebf26564746fbe980641dfd19db87fdc1e04910160405180910390a28315610cb957856001600160a01b03167f64c0ee8138eaa64f1d6e0d48e75e1db2aa923dfd70036faa4c2dcaaa9205692085604051610cb091815260200190565b60405180910390a25b856001600160a01b03166337a4e834826040518263ffffffff1660e01b81526004015f604051808303818588803b158015610cf2575f5ffd5b505af1158015610d04573d5f5f3e3d5ffd5b50505050505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d66573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d8a9190611481565b90505f816001600160a01b0316856040515f6040518083038185875af1925050503d805f8114610dd5576040519150601f19603f3d011682016040523d82523d5f602084013e610dda565b606091505b5050905080610dfc57604051630db2c7f160e31b815260040160405180910390fd5b5050505050505050565b6001600160a01b0381168114610e1a575f5ffd5b50565b5f60a08284031215610e2d575f5ffd5b50919050565b5f60808284031215610e2d575f5ffd5b5f5f83601f840112610e53575f5ffd5b50813567ffffffffffffffff811115610e6a575f5ffd5b602083019150836020828501011115610bfb575f5ffd5b5f5f5f5f5f6101608688031215610e96575f5ffd5b8535610ea181610e06565b9450610eb08760208801610e1d565b9350610ebf8760c08801610e33565b925061014086013567ffffffffffffffff811115610edb575f5ffd5b610ee788828901610e43565b969995985093965092949392505050565b5f60608284031215610e2d575f5ffd5b5f5f5f5f5f6101408688031215610f1d575f5ffd5b8535610f2881610e06565b9450610f378760208801610e1d565b9350610f468760c08801610ef8565b925061012086013567ffffffffffffffff811115610edb575f5ffd5b5f5f5f5f5f5f5f6101a0888a031215610f79575f5ffd5b8735610f8481610e06565b9650610f938960208a01610e1d565b9550610fa28960c08a01610e33565b94506101408801359350610160880135925061018088013567ffffffffffffffff811115610fce575f5ffd5b610fda8a828b01610e43565b989b979a50959850939692959293505050565b5f5f5f5f6101008587031215611001575f5ffd5b843561100c81610e06565b935061101b8660208701610e1d565b925060c085013561102b81610e06565b915060e0850135600281900b8114611041575f5ffd5b939692955090935050565b5f5f5f5f5f5f6101608789031215611062575f5ffd5b863561106d81610e06565b955061107c8860208901610e1d565b945061108b8860c08901610ef8565b9350610120870135925061014087013567ffffffffffffffff8111156110af575f5ffd5b6110bb89828a01610e43565b979a9699509497509295939492505050565b5f5f5f5f5f5f61012087890312156110e3575f5ffd5b86356110ee81610e06565b95506110fd8860208901610e1d565b945060c0870135935060e0870135925061010087013567ffffffffffffffff8111156110af575f5ffd5b8151151581526101c081016020830151611145602084018215159052565b506040830151611159604084018215159052565b50606083015161116d606084018215159052565b506080830151611181608084018215159052565b5060a083015161119560a084018215159052565b5060c08301516111a960c084018215159052565b5060e08301516111bd60e084018215159052565b506101008301516111d361010084018215159052565b506101208301516111e961012084018215159052565b506101408301516111ff61014084018215159052565b5061016083015161121561016084018215159052565b5061018083015161122b61018084018215159052565b506101a08301516112416101a084018215159052565b5092915050565b5f5f5f60e0848603121561125a575f5ffd5b833561126581610e06565b92506112748560208601610e1d565b915060c084013561128481610e06565b809150509250925092565b5f6020828403121561129f575f5ffd5b81356112aa81610e06565b9392505050565b8015158114610e1a575f5ffd5b5f602082840312156112ce575f5ffd5b81516112aa816112b1565b5f602082840312156112e9575f5ffd5b81356112aa816112b1565b634e487b7160e01b5f52601160045260245ffd5b5f600160ff1b820161131c5761131c6112f4565b505f0390565b8082028115828204841417611339576113396112f4565b92915050565b5f8261135957634e487b7160e01b5f52601260045260245ffd5b500490565b80820180821115611339576113396112f4565b5f81600f0b6f7fffffffffffffffffffffffffffffff198103611396576113966112f4565b5f0392915050565b805161ffff811681146113af575f5ffd5b919050565b805164ffffffffff811681146113af575f5ffd5b5f60808284031280156113d9575f5ffd5b506040516080810167ffffffffffffffff8111828210171561140957634e487b7160e01b5f52604160045260245ffd5b6040526114158361139e565b81526114236020840161139e565b6020820152611434604084016113b4565b6040820152611445606084016113b4565b60608201529392505050565b64ffffffffff8181168382160190811115611339576113396112f4565b81810381811115611339576113396112f4565b5f60208284031215611491575f5ffd5b81516112aa81610e0656fea264697066735822122045500dbd57234bf2672c8b90550a6033bb5e7ea8b77aae9e6ec49904c6bf553364736f6c634300081c0033000000000000000000000000000000000004444c5dc75cb358380d2e3de08a9000000000000000000000000043f8bc6d25be185711680987019d20543e6b53f6" + )), + constructor_args: None, + creation_bytecode: None, + verify_json_path: None, + }, // Add more contracts here: // ContractSpec { // name: "MyNewContract", diff --git a/src/helpers/pre_conditions.rs b/src/helpers/pre_conditions.rs index 75ae83a..8efeacd 100644 --- a/src/helpers/pre_conditions.rs +++ b/src/helpers/pre_conditions.rs @@ -43,13 +43,19 @@ pub fn check_before(contract_to_deploy: Option<&ContractSpec>, args: &CliArgs) { info!("verify_json_path contract: {:?}", spec.verify_json_path); info!("salt contract: {:?}", spec.salt); - match verify_create2_address(spec) { - Ok(addr) => { - info!("CREATE2 address verified: {addr}"); + if spec.deployer_tx.is_some() { + if let Some(addr) = spec.address { + info!("Contract address (pre-built tx): {addr}"); } - Err(e) => { - error!("CREATE2 verification failed: {e}"); - exit(1); + } else { + match verify_create2_address(spec) { + Ok(addr) => { + info!("CREATE2 address verified: {addr}"); + } + Err(e) => { + error!("CREATE2 verification failed: {e}"); + exit(1); + } } } } else if args.contract_name.is_some() || args.address.is_some() || args.contract_path.is_some() diff --git a/src/utils/deploy.rs b/src/utils/deploy.rs index dec1c87..5593498 100644 --- a/src/utils/deploy.rs +++ b/src/utils/deploy.rs @@ -28,12 +28,15 @@ pub async fn deploy_contract( .public() .ok_or_else(|| DeployError::NoProvider(wallet.address()))?; - let salt: FixedBytes<32> = spec.salt.ok_or(DeployError::MissingSalt(spec.name))?; - let init_code: Bytes = spec - .full_init_code() - .ok_or(DeployError::MissingInitCode(spec.name))?; - - let calldata: Bytes = build_calldata(&salt, &init_code); + let calldata: Bytes = if let Some(tx_data) = spec.deployer_tx { + Bytes::copy_from_slice(tx_data) + } else { + let salt: FixedBytes<32> = spec.salt.ok_or(DeployError::MissingSalt(spec.name))?; + let init_code: Bytes = spec + .full_init_code() + .ok_or(DeployError::MissingInitCode(spec.name))?; + build_calldata(&salt, &init_code) + }; let tx: TransactionRequest = TransactionRequest::default() .with_to(*Constants::DETERMINISTIC_DEPLOYER) diff --git a/src/utils/verifier.rs b/src/utils/verifier.rs index 997d44a..c014e67 100644 --- a/src/utils/verifier.rs +++ b/src/utils/verifier.rs @@ -328,4 +328,4 @@ pub async fn run_verifications(ready_for_verify: &[WalletClient], spec: &Contrac error!("Verification task panicked: {e}"); } } -} +} \ No newline at end of file From 83ad3e5617d1d0ebc128ec58e25c741602d87bbd Mon Sep 17 00:00:00 2001 From: 0xKoiner Date: Mon, 6 Apr 2026 14:46:22 +0200 Subject: [PATCH 2/5] (feat) Verify with Sourcify --- src/main.rs | 2 +- src/types/config.rs | 1 + src/types/errors.rs | 2 + src/utils/read_buf.rs | 12 +++ src/utils/verifier.rs | 197 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 211 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index e5bf711..670bd82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,6 +100,6 @@ async fn main() { ready_for_verify.extend(deployed); if args.verify { - run_verifications(&ready_for_verify, &spec).await; + run_verifications(&ready_for_verify, &spec, args.source_chain.as_deref()).await; } } diff --git a/src/types/config.rs b/src/types/config.rs index 70fb4e7..613b1b5 100644 --- a/src/types/config.rs +++ b/src/types/config.rs @@ -70,6 +70,7 @@ pub struct CliArgs { pub verify: bool, pub constructor_args: Option, pub keystore: bool, + pub source_chain: Option, } pub struct PrecheckResult { diff --git a/src/types/errors.rs b/src/types/errors.rs index 844aae5..ffb2f9c 100644 --- a/src/types/errors.rs +++ b/src/types/errors.rs @@ -130,6 +130,8 @@ pub enum VerifierError { HttpError(&'static str, String), #[error("forge not found — install Foundry: {0}")] ForgeNotFound(String), + #[error("Contract not verified on source chain {0}")] + NotVerifiedOnSource(String), } #[derive(Debug, thiserror::Error)] diff --git a/src/utils/read_buf.rs b/src/utils/read_buf.rs index baaf650..8b4ee46 100644 --- a/src/utils/read_buf.rs +++ b/src/utils/read_buf.rs @@ -168,6 +168,7 @@ pub fn parse_args() -> Result { let mut verify: bool = false; let mut constructor_args: Option = None; let mut keystore: bool = false; + let mut source_chain: Option = None; let mut chains: Vec = Vec::with_capacity(Chain::COUNT); let mut seen: ChainSet = ChainSet::new(); let mut parser: lexopt::Parser = lexopt::Parser::from_env(); @@ -205,6 +206,15 @@ pub fn parse_args() -> Result { Long("keystore") => { keystore = true; } + Long("source-chain") => { + let val: OsString = parser + .value() + .map_err(|e| CliError::ParseError(e.to_string()))?; + let val_str = val + .to_str() + .ok_or_else(|| CliError::ParseError("invalid UTF-8".to_string()))?; + source_chain = Some(val_str.to_string()); + } Long("constructor-args") => { let val: OsString = parser .value() @@ -266,6 +276,7 @@ pub fn parse_args() -> Result { verify, constructor_args, keystore, + source_chain, }) } @@ -278,6 +289,7 @@ fn print_usage() { eprintln!(" --address Contract address (hex, with or without 0x)"); eprintln!(" --verify Enable contract verification"); eprintln!(" --keystore Create and use an encrypted keystore"); + eprintln!(" --source-chain Chain with verified source (for cross-chain verification)"); eprintln!( " --constructor-args ABI-encoded constructor arguments (hex, with or without 0x)" ); diff --git a/src/utils/verifier.rs b/src/utils/verifier.rs index c014e67..9b5dd7e 100644 --- a/src/utils/verifier.rs +++ b/src/utils/verifier.rs @@ -9,16 +9,161 @@ use alloy::primitives::{Address, hex}; use alloy::transports::http::reqwest; use alloy::transports::http::reqwest::Client; use log::{error, info, warn}; +use serde::Deserialize; use tokio::task::{JoinSet, spawn_blocking}; use tokio::time::sleep; -use crate::types::config::{ContractSpec, EtherscanResponse, PublicClient, WalletClient}; +use crate::types::config::{Chain, ContractSpec, EtherscanResponse, PublicClient, WalletClient}; use crate::types::constants::Constants; use crate::types::errors::VerifierError; const POLL_INTERVAL: Duration = Duration::from_secs(3); const MAX_POLL_ATTEMPTS: u32 = 20; +#[derive(Deserialize)] +struct SourceCodeResult { + #[serde(rename = "SourceCode")] + source_code: String, + #[serde(rename = "ContractName")] + contract_name: String, + #[serde(rename = "CompilerVersion")] + compiler_version: String, + #[serde(rename = "ConstructorArguments")] + constructor_arguments: String, +} + +#[derive(Deserialize)] +struct GetSourceCodeResponse { + status: String, + result: Vec, +} + +fn find_contract_file(source_json: &str, contract_name: &str) -> Option { + let parsed: serde_json::Value = serde_json::from_str(source_json).ok()?; + let sources = parsed.get("sources")?.as_object()?; + let suffix = format!("{contract_name}.sol"); + sources + .keys() + .find(|k| k.ends_with(&suffix)) + .cloned() +} + +async fn fetch_verified_source( + api_key: &str, + chain_id: u64, + address: Address, + name: &'static str, +) -> Result { + let url: String = format!( + "{}?module=contract&action=getsourcecode&address={address}&chainid={chain_id}&apikey={api_key}", + Constants::ETHERSCAN_V2_URL + ); + + let client: Client = reqwest::Client::new(); + let resp: GetSourceCodeResponse = client + .get(&url) + .send() + .await + .map_err(|e| VerifierError::HttpError(name, e.to_string()))? + .json() + .await + .map_err(|e| VerifierError::HttpError(name, e.to_string()))?; + + if resp.status != "1" || resp.result.is_empty() { + return Err(VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}"))); + } + + let mut source = resp.result.into_iter().next().unwrap(); + + if source.source_code.is_empty() || source.contract_name.is_empty() { + return Err(VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}"))); + } + + if source.source_code.starts_with("{{") && source.source_code.ends_with("}}") { + source.source_code = source.source_code[1..source.source_code.len() - 1].to_string(); + } + + if !source.contract_name.contains(':') { + let contract_file = find_contract_file(&source.source_code, &source.contract_name); + if let Some(file) = contract_file { + source.contract_name = format!("{file}:{}", source.contract_name); + } + } + + Ok(source) +} + +async fn verify_cross_chain( + api_key: &str, + source: &SourceCodeResult, + target_chain_id: u64, + address: Address, + name: &'static str, + chain: &str, +) -> Result { + let client: Client = reqwest::Client::new(); + let submit_url: String = format!( + "{}?module=contract&action=verifysourcecode&chainid={target_chain_id}&apikey={api_key}", + Constants::ETHERSCAN_V2_URL + ); + + let addr_str: String = format!("{address}"); + let body: String = build_form_body(&[ + ("contractaddress", &addr_str), + ("sourceCode", &source.source_code), + ("codeformat", "solidity-standard-json-input"), + ("contractname", &source.contract_name), + ("compilerversion", &source.compiler_version), + ("constructorArguements", &source.constructor_arguments), + ]); + + let resp: EtherscanResponse = client + .post(&submit_url) + .header("Content-Type", "application/x-www-form-urlencoded") + .body(body) + .send() + .await + .map_err(|e| VerifierError::HttpError(name, e.to_string()))? + .json() + .await + .map_err(|e| VerifierError::HttpError(name, e.to_string()))?; + + if resp.status != "1" { + return Err(VerifierError::SubmissionFailed(name, resp.result)); + } + + let guid: String = resp.result; + info!("Cross-chain verification submitted for '{name}' on {chain} (guid: {guid})"); + + let status_url: String = format!( + "{}?module=contract&action=checkverifystatus&guid={guid}&chainid={target_chain_id}&apikey={api_key}", + Constants::ETHERSCAN_V2_URL + ); + + for _ in 0..MAX_POLL_ATTEMPTS { + sleep(POLL_INTERVAL).await; + + let status: EtherscanResponse = client + .get(&status_url) + .send() + .await + .map_err(|e| VerifierError::HttpError(name, e.to_string()))? + .json() + .await + .map_err(|e| VerifierError::HttpError(name, e.to_string()))?; + + if status.result.contains("Pass") || status.result.contains("Already Verified") { + return Ok(status.result); + } + + if status.result.contains("Fail") { + return Err(VerifierError::VerificationFailed(name, status.result)); + } + } + + Err(VerifierError::Timeout(name, guid)) +} + fn url_encode(s: &str) -> String { let mut out: String = String::with_capacity(s.len() * 3); for b in s.bytes() { @@ -262,7 +407,11 @@ async fn verify_via_etherscan_api( Err(VerifierError::Timeout(spec.name, guid)) } -pub async fn run_verifications(ready_for_verify: &[WalletClient], spec: &ContractSpec) { +pub async fn run_verifications( + ready_for_verify: &[WalletClient], + spec: &ContractSpec, + source_chain: Option<&str>, +) { if ready_for_verify.is_empty() { return; } @@ -280,6 +429,36 @@ pub async fn run_verifications(ready_for_verify: &[WalletClient], spec: &Contrac let api_key: Option = var(Constants::ETHERSCAN_API_KEY_ENV).ok(); + let cross_chain_source: Option = + if path.is_none() && address.is_some() && api_key.is_some() { + let addr: Address = address.unwrap(); + let key: &str = api_key.as_deref().unwrap(); + + let source_chain_id: Option = source_chain + .and_then(|sc| { + let chain = Chain::from_flag(sc)?; + etherscan_chain_id(chain.as_rpc_key(), chain.network()) + }); + + if let Some(scid) = source_chain_id { + info!("Fetching verified source from source chain (id: {scid})"); + match fetch_verified_source(key, scid, addr, name).await { + Ok(source) => { + info!("Fetched source: {} ({})", source.contract_name, source.compiler_version); + Some(source) + } + Err(e) => { + warn!("Failed to fetch source from source chain: {e}"); + None + } + } + } else { + None + } + } else { + None + }; + let mut verify_set: JoinSet<()> = JoinSet::new(); for (i, deployer) in ready_for_verify.iter().enumerate() { @@ -292,6 +471,11 @@ pub async fn run_verifications(ready_for_verify: &[WalletClient], spec: &Contrac let chain_id: Option = etherscan_chain_id(chain_key, network); let api_key: Option = api_key.clone(); let delay: u64 = i as u64; + let has_cross_chain: bool = cross_chain_source.is_some(); + let cross_source_code: Option = cross_chain_source.as_ref().map(|s| s.source_code.clone()); + let cross_contract_name: Option = cross_chain_source.as_ref().map(|s| s.contract_name.clone()); + let cross_compiler_version: Option = cross_chain_source.as_ref().map(|s| s.compiler_version.clone()); + let cross_constructor_args: Option = cross_chain_source.as_ref().map(|s| s.constructor_arguments.clone()); verify_set.spawn(async move { if delay > 0 { @@ -308,6 +492,15 @@ pub async fn run_verifications(ready_for_verify: &[WalletClient], spec: &Contrac .map_err(|e| VerifierError::VerificationFailed(name, e.to_string())) .and_then(|r| r) } + (Some(addr), None, Some(cid), Some(key)) if has_cross_chain => { + let source = SourceCodeResult { + source_code: cross_source_code.unwrap(), + contract_name: cross_contract_name.unwrap(), + compiler_version: cross_compiler_version.unwrap(), + constructor_arguments: cross_constructor_args.unwrap(), + }; + verify_cross_chain(&key, &source, cid, addr, name, &chain).await + } (None, _, _, _) => Err(VerifierError::MissingAddress(name)), (_, None, _, _) => Err(VerifierError::MissingContractPath(name)), (_, _, None, _) => Err(VerifierError::UnsupportedChain(chain.clone())), From 8829589185ae316262a47e57a6950b1643f20563 Mon Sep 17 00:00:00 2001 From: 0xKoiner Date: Mon, 6 Apr 2026 15:01:23 +0200 Subject: [PATCH 3/5] fixes, optimization --- src/types/config.rs | 18 ++++++++ src/utils/print_intro.rs | 4 +- src/utils/verifier.rs | 94 +++++++++++++--------------------------- 3 files changed, 50 insertions(+), 66 deletions(-) diff --git a/src/types/config.rs b/src/types/config.rs index 613b1b5..3edaa0f 100644 --- a/src/types/config.rs +++ b/src/types/config.rs @@ -61,6 +61,24 @@ pub struct EtherscanResponse { pub result: String, } +#[derive(Deserialize)] +pub struct SourceCodeResult { + #[serde(rename = "SourceCode")] + pub source_code: String, + #[serde(rename = "ContractName")] + pub contract_name: String, + #[serde(rename = "CompilerVersion")] + pub compiler_version: String, + #[serde(rename = "ConstructorArguments")] + pub constructor_arguments: String, +} + +#[derive(Deserialize)] +pub struct GetSourceCodeResponse { + pub status: String, + pub result: Vec, +} + pub struct CliArgs { pub contract_path: Option, pub chains: Vec, diff --git a/src/utils/print_intro.rs b/src/utils/print_intro.rs index 5491aff..dd1f9ca 100644 --- a/src/utils/print_intro.rs +++ b/src/utils/print_intro.rs @@ -1,4 +1,4 @@ -const INTRO: &'static str = r#" +const INTRO: &str = r" ___________________ / Deploy \ █████ █████ ███ ███ █████ ███ ___________ / Contract in one \ ░░███ ░░███ ░░░ ░░░ ░░███ ░░░ @@ -22,7 +22,7 @@ const INTRO: &'static str = r#" /_____| |_____\ ░░░░░ ░░░░░░ ___| | | |___ (_______| |_______) -"#; +"; pub fn print_intro_log() { diff --git a/src/utils/verifier.rs b/src/utils/verifier.rs index 9b5dd7e..52fb6ec 100644 --- a/src/utils/verifier.rs +++ b/src/utils/verifier.rs @@ -4,44 +4,26 @@ use std::fs::read_to_string; use std::process::Command; use std::process::Output; use std::time::Duration; +use serde_json::{Value, Map}; use alloy::primitives::{Address, hex}; use alloy::transports::http::reqwest; use alloy::transports::http::reqwest::Client; use log::{error, info, warn}; -use serde::Deserialize; use tokio::task::{JoinSet, spawn_blocking}; use tokio::time::sleep; -use crate::types::config::{Chain, ContractSpec, EtherscanResponse, PublicClient, WalletClient}; +use crate::types::config::{Chain, ContractSpec, EtherscanResponse, PublicClient, WalletClient, SourceCodeResult, GetSourceCodeResponse}; use crate::types::constants::Constants; use crate::types::errors::VerifierError; const POLL_INTERVAL: Duration = Duration::from_secs(3); const MAX_POLL_ATTEMPTS: u32 = 20; -#[derive(Deserialize)] -struct SourceCodeResult { - #[serde(rename = "SourceCode")] - source_code: String, - #[serde(rename = "ContractName")] - contract_name: String, - #[serde(rename = "CompilerVersion")] - compiler_version: String, - #[serde(rename = "ConstructorArguments")] - constructor_arguments: String, -} - -#[derive(Deserialize)] -struct GetSourceCodeResponse { - status: String, - result: Vec, -} - fn find_contract_file(source_json: &str, contract_name: &str) -> Option { - let parsed: serde_json::Value = serde_json::from_str(source_json).ok()?; - let sources = parsed.get("sources")?.as_object()?; - let suffix = format!("{contract_name}.sol"); + let parsed: Value = serde_json::from_str(source_json).ok()?; + let sources: &Map = parsed.get("sources")?.as_object()?; + let suffix: String = format!("{contract_name}.sol"); sources .keys() .find(|k| k.ends_with(&suffix)) @@ -73,7 +55,8 @@ async fn fetch_verified_source( return Err(VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}"))); } - let mut source = resp.result.into_iter().next().unwrap(); + let mut source = resp.result.into_iter().next() + .ok_or_else(|| VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}")))?; if source.source_code.is_empty() || source.contract_name.is_empty() { return Err(VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}"))); @@ -84,7 +67,7 @@ async fn fetch_verified_source( } if !source.contract_name.contains(':') { - let contract_file = find_contract_file(&source.source_code, &source.contract_name); + let contract_file: Option = find_contract_file(&source.source_code, &source.contract_name); if let Some(file) = contract_file { source.contract_name = format!("{file}:{}", source.contract_name); } @@ -135,8 +118,18 @@ async fn verify_cross_chain( let guid: String = resp.result; info!("Cross-chain verification submitted for '{name}' on {chain} (guid: {guid})"); + poll_verification_status(&client, target_chain_id, api_key, &guid, name).await +} + +async fn poll_verification_status( + client: &Client, + chain_id: u64, + api_key: &str, + guid: &str, + name: &'static str, +) -> Result { let status_url: String = format!( - "{}?module=contract&action=checkverifystatus&guid={guid}&chainid={target_chain_id}&apikey={api_key}", + "{}?module=contract&action=checkverifystatus&guid={guid}&chainid={chain_id}&apikey={api_key}", Constants::ETHERSCAN_V2_URL ); @@ -161,7 +154,7 @@ async fn verify_cross_chain( } } - Err(VerifierError::Timeout(name, guid)) + Err(VerifierError::Timeout(name, guid.to_string())) } fn url_encode(s: &str) -> String { @@ -378,33 +371,7 @@ async fn verify_via_etherscan_api( spec.name ); - let status_url: String = format!( - "{}?module=contract&action=checkverifystatus&guid={guid}&chainid={chain_id}&apikey={api_key}", - Constants::ETHERSCAN_V2_URL - ); - - for _ in 0..MAX_POLL_ATTEMPTS { - sleep(POLL_INTERVAL).await; - - let status: EtherscanResponse = client - .get(&status_url) - .send() - .await - .map_err(|e| VerifierError::HttpError(spec.name, e.to_string()))? - .json() - .await - .map_err(|e| VerifierError::HttpError(spec.name, e.to_string()))?; - - if status.result.contains("Pass") || status.result.contains("Already Verified") { - return Ok(status.result); - } - - if status.result.contains("Fail") { - return Err(VerifierError::VerificationFailed(spec.name, status.result)); - } - } - - Err(VerifierError::Timeout(spec.name, guid)) + poll_verification_status(&client, chain_id, api_key, &guid, spec.name).await } pub async fn run_verifications( @@ -430,21 +397,20 @@ pub async fn run_verifications( let api_key: Option = var(Constants::ETHERSCAN_API_KEY_ENV).ok(); let cross_chain_source: Option = - if path.is_none() && address.is_some() && api_key.is_some() { - let addr: Address = address.unwrap(); - let key: &str = api_key.as_deref().unwrap(); - - let source_chain_id: Option = source_chain - .and_then(|sc| { - let chain = Chain::from_flag(sc)?; - etherscan_chain_id(chain.as_rpc_key(), chain.network()) - }); + if let (None, Some(addr), Some(key)) = (path, address, &api_key) { + let source_chain_id: Option = source_chain.and_then(|sc| { + let chain = Chain::from_flag(sc)?; + etherscan_chain_id(chain.as_rpc_key(), chain.network()) + }); if let Some(scid) = source_chain_id { info!("Fetching verified source from source chain (id: {scid})"); match fetch_verified_source(key, scid, addr, name).await { Ok(source) => { - info!("Fetched source: {} ({})", source.contract_name, source.compiler_version); + info!( + "Fetched source: {} ({})", + source.contract_name, source.compiler_version + ); Some(source) } Err(e) => { From 2f356f943999e9e01058142fd24e8b2d6159ee93 Mon Sep 17 00:00:00 2001 From: 0xKoiner Date: Mon, 6 Apr 2026 15:13:09 +0200 Subject: [PATCH 4/5] fixes, optimization --- src/data/contracts/registry.rs | 6 +++--- src/utils/deploy.rs | 2 +- src/utils/verifier.rs | 28 ++++++++++------------------ 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/data/contracts/registry.rs b/src/data/contracts/registry.rs index 72d40e1..1d004cd 100644 --- a/src/data/contracts/registry.rs +++ b/src/data/contracts/registry.rs @@ -78,12 +78,12 @@ pub const CONTRACTS: &[ContractSpec] = &[ verify_json_path: None, }, ContractSpec { - name: "LivoSwapHook", - address: Some(address!("0x8d02cfe74ce8c1b7133e45fadf39c23b04a7c0cc")), + name: "ApproveAndSwapKyberSwapHook", + address: Some(address!("0xdC9D10d9710DBf82924a3F7733293457Ad12D37D")), salt: None, path: None, deployer_tx: Some(&hex!( - "000000000000000000000000000000000000000000000000000000000000666160c060405234801561000f575f5ffd5b5060405161183538038061183583398101604081905261002e916102c4565b6001600160a01b0382166080528161004530610058565b506001600160a01b031660a052506102fc565b61014881610143604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915250604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a08101829052600160c0820181905260e0820181905261010082018390526101208201839052610140820181905261016082015261018081018290526101a081019190915290565b61014b565b50565b805115156120008316151514158061016f5750602081015115156110008316151514155b806101865750604081015115156108008316151514155b8061019d5750606081015115156104008316151514155b806101b45750608081015115156102008316151514155b806101cb575060a081015115156101008316151514155b806101e1575060c0810151151560808316151514155b806101f7575060e0810151151560408316151514155b8061020e5750610100810151151560208316151514155b806102255750610120810151151560108316151514155b8061023c5750610140810151151560088316151514155b806102535750610160810151151560048316151514155b8061026a5750610180810151151560028316151514155b8061028157506101a0810151151560018316151514155b1561029757610297630732d7b560e51b8361029b565b5050565b815f526001600160a01b03811660045260245ffd5b6001600160a01b0381168114610148575f5ffd5b5f5f604083850312156102d5575f5ffd5b82516102e0816102b0565b60208401519092506102f1816102b0565b809150509250929050565b60805160a0516114d26103635f395f818161011b0152610d0c01525f818161036f015281816103bc0152818161041f01528181610489015281816104f201528181610552015281816105ba0152818161061d015281816107bb01526109e101526114d25ff3fe6080604052600436106100c2575f3560e01c80639f063efc1161007c578063c4e833ce11610057578063c4e833ce1461025e578063dc4c90d31461035e578063dc98354e14610391578063e1b4af691461023f575f5ffd5b80639f063efc1461019f578063b47b2fb1146101fd578063b6a8b0fa1461023f575f5ffd5b806321d0ee70146100cd578063259982e5146100cd57806351431d4f1461010a578063575e24b4146101555780636c2bbe7e1461019f5780636fe7e6eb146101de575f5ffd5b366100c957005b5f5ffd5b3480156100d8575f5ffd5b506100ec6100e7366004610e81565b6103b0565b6040516001600160e01b031990911681526020015b60405180910390f35b348015610115575f5ffd5b5061013d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610101565b348015610160575f5ffd5b5061017461016f366004610f08565b610411565b604080516001600160e01b03199094168452602084019290925262ffffff1690820152606001610101565b3480156101aa575f5ffd5b506101be6101b9366004610f62565b61047c565b604080516001600160e01b03199093168352602083019190915201610101565b3480156101e9575f5ffd5b506100ec6101f8366004610fed565b6104e6565b348015610208575f5ffd5b5061021c61021736600461104c565b610545565b604080516001600160e01b03199093168352600f9190910b602083015201610101565b34801561024a575f5ffd5b506100ec6102593660046110cd565b6105ae565b348015610269575f5ffd5b50610351604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915250604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a08101829052600160c0820181905260e0820181905261010082018390526101208201839052610140820181905261016082015261018081018290526101a081019190915290565b6040516101019190611127565b348015610369575f5ffd5b5061013d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561039c575f5ffd5b506100ec6103ab366004611248565b610611565b5f336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103fa5760405163570c108560e11b815260040160405180910390fd5b610407868686868661066e565b9695505050505050565b5f8080336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461045d5760405163570c108560e11b815260040160405180910390fd5b61046a8888888888610688565b9250925092505b955095509592505050565b5f80336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104c75760405163570c108560e11b815260040160405180910390fd5b6104d689898989898989610889565b9150915097509795505050505050565b5f336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105305760405163570c108560e11b815260040160405180910390fd5b61053c8585858561066e565b95945050505050565b5f80336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105905760405163570c108560e11b815260040160405180910390fd5b61059e8888888888886108a4565b915091505b965096945050505050565b5f336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105f85760405163570c108560e11b815260040160405180910390fd5b61060687878787878761066e565b979650505050505050565b5f336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461065b5760405163570c108560e11b815260040160405180910390fd5b61066684848461066e565b949350505050565b5f604051630a85dc2960e01b815260040160405180910390fd5b5f80808061069c6040890160208a0161128f565b9050806001600160a01b031663e7c2b7726040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106fe91906112be565b61071b57604051634eeed17360e11b815260040160405180910390fd5b61072860208801886112d9565b61074257506315d7892d60e21b92505f9150819050610471565b5f6107506020890135611308565b90505f612710610761606484611322565b61076b919061133f565b90505f5f61077a856001610b19565b915091505f8261078a575f6107a5565b61271061079b61ffff841687611322565b6107a5919061133f565b90505f6107b2828661135e565b905080805f5d507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630b0d9c098f5f0160208101906107fa919061128f565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604481018490526064015f604051808303815f87803b158015610845575f5ffd5b505af1158015610857573d5f5f3e3d5ffd5b50505050610866878684610c02565b6315d7892d60e21b9f60809190911b9e505f9d509b505050505050505050505050565b5f5f604051630a85dc2960e01b815260040160405180910390fd5b5f80806108b76040890160208a0161128f565b90506108c660208801886112d9565b15610968575f6108d96020890135611308565b90505f6108e688600f0b90565b6001600160801b03169050326001600160a01b0316836001600160a01b03167f468a22fa2561e8de33b9a775fc9e6624b48dcb7c117cef07ef608b041650ba0484845f5c60405161094a939291909283526020830191909152604082015260600190565b60405180910390a35063b47b2fb160e01b93505f92506105a3915050565b5f6109738760801d90565b6001600160801b031690505f61271061098d606484611322565b610997919061133f565b90505f5f6109a5855f610b19565b915091505f826109b5575f6109d0565b6127106109c661ffff841687611322565b6109d0919061133f565b90505f6109dd828661135e565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630b0d9c098f5f016020810190610a20919061128f565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152306024820152604481018490526064015f604051808303815f87803b158015610a6b575f5ffd5b505af1158015610a7d573d5f5f3e3d5ffd5b50505050610a8c878684610c02565b5f610a978d600f0b90565b610aa090611371565b604080516001600160801b0392909216808352602083018a9052908201849052915032906001600160a01b038a16907f247558786bc03377d70bed68b0459f5dd2a2d5b00bf2531cab9111b1b13568669060600160405180910390a35063b47b2fb160e01b9f909e509c50505050505050505050505050565b5f5f5f846001600160a01b0316637c922d886040518163ffffffff1660e01b8152600401608060405180830381865afa158015610b58573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b7c91906113c8565b9050806060015164ffffffffff165f03610b9c575f5f9250925050610bfb565b80604001518160600151610bb09190611451565b64ffffffffff16421115610bca575f5f9250925050610bfb565b83610bd9578060200151610bdc565b80515b91508161ffff165f03610bf5575f5f9250925050610bfb565b60019250505b9250929050565b5f610c0e60028461133f565b90505f610c1b828561146e565b90505f610c28848361135e565b60408051848152602081018690529192506001600160a01b038816917f83a48ea337f6cd96ddd4e04f9e08ebf26564746fbe980641dfd19db87fdc1e04910160405180910390a28315610cb957856001600160a01b03167f64c0ee8138eaa64f1d6e0d48e75e1db2aa923dfd70036faa4c2dcaaa9205692085604051610cb091815260200190565b60405180910390a25b856001600160a01b03166337a4e834826040518263ffffffff1660e01b81526004015f604051808303818588803b158015610cf2575f5ffd5b505af1158015610d04573d5f5f3e3d5ffd5b50505050505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d66573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d8a9190611481565b90505f816001600160a01b0316856040515f6040518083038185875af1925050503d805f8114610dd5576040519150601f19603f3d011682016040523d82523d5f602084013e610dda565b606091505b5050905080610dfc57604051630db2c7f160e31b815260040160405180910390fd5b5050505050505050565b6001600160a01b0381168114610e1a575f5ffd5b50565b5f60a08284031215610e2d575f5ffd5b50919050565b5f60808284031215610e2d575f5ffd5b5f5f83601f840112610e53575f5ffd5b50813567ffffffffffffffff811115610e6a575f5ffd5b602083019150836020828501011115610bfb575f5ffd5b5f5f5f5f5f6101608688031215610e96575f5ffd5b8535610ea181610e06565b9450610eb08760208801610e1d565b9350610ebf8760c08801610e33565b925061014086013567ffffffffffffffff811115610edb575f5ffd5b610ee788828901610e43565b969995985093965092949392505050565b5f60608284031215610e2d575f5ffd5b5f5f5f5f5f6101408688031215610f1d575f5ffd5b8535610f2881610e06565b9450610f378760208801610e1d565b9350610f468760c08801610ef8565b925061012086013567ffffffffffffffff811115610edb575f5ffd5b5f5f5f5f5f5f5f6101a0888a031215610f79575f5ffd5b8735610f8481610e06565b9650610f938960208a01610e1d565b9550610fa28960c08a01610e33565b94506101408801359350610160880135925061018088013567ffffffffffffffff811115610fce575f5ffd5b610fda8a828b01610e43565b989b979a50959850939692959293505050565b5f5f5f5f6101008587031215611001575f5ffd5b843561100c81610e06565b935061101b8660208701610e1d565b925060c085013561102b81610e06565b915060e0850135600281900b8114611041575f5ffd5b939692955090935050565b5f5f5f5f5f5f6101608789031215611062575f5ffd5b863561106d81610e06565b955061107c8860208901610e1d565b945061108b8860c08901610ef8565b9350610120870135925061014087013567ffffffffffffffff8111156110af575f5ffd5b6110bb89828a01610e43565b979a9699509497509295939492505050565b5f5f5f5f5f5f61012087890312156110e3575f5ffd5b86356110ee81610e06565b95506110fd8860208901610e1d565b945060c0870135935060e0870135925061010087013567ffffffffffffffff8111156110af575f5ffd5b8151151581526101c081016020830151611145602084018215159052565b506040830151611159604084018215159052565b50606083015161116d606084018215159052565b506080830151611181608084018215159052565b5060a083015161119560a084018215159052565b5060c08301516111a960c084018215159052565b5060e08301516111bd60e084018215159052565b506101008301516111d361010084018215159052565b506101208301516111e961012084018215159052565b506101408301516111ff61014084018215159052565b5061016083015161121561016084018215159052565b5061018083015161122b61018084018215159052565b506101a08301516112416101a084018215159052565b5092915050565b5f5f5f60e0848603121561125a575f5ffd5b833561126581610e06565b92506112748560208601610e1d565b915060c084013561128481610e06565b809150509250925092565b5f6020828403121561129f575f5ffd5b81356112aa81610e06565b9392505050565b8015158114610e1a575f5ffd5b5f602082840312156112ce575f5ffd5b81516112aa816112b1565b5f602082840312156112e9575f5ffd5b81356112aa816112b1565b634e487b7160e01b5f52601160045260245ffd5b5f600160ff1b820161131c5761131c6112f4565b505f0390565b8082028115828204841417611339576113396112f4565b92915050565b5f8261135957634e487b7160e01b5f52601260045260245ffd5b500490565b80820180821115611339576113396112f4565b5f81600f0b6f7fffffffffffffffffffffffffffffff198103611396576113966112f4565b5f0392915050565b805161ffff811681146113af575f5ffd5b919050565b805164ffffffffff811681146113af575f5ffd5b5f60808284031280156113d9575f5ffd5b506040516080810167ffffffffffffffff8111828210171561140957634e487b7160e01b5f52604160045260245ffd5b6040526114158361139e565b81526114236020840161139e565b6020820152611434604084016113b4565b6040820152611445606084016113b4565b60608201529392505050565b64ffffffffff8181168382160190811115611339576113396112f4565b81810381811115611339576113396112f4565b5f60208284031215611491575f5ffd5b81516112aa81610e0656fea264697066735822122045500dbd57234bf2672c8b90550a6033bb5e7ea8b77aae9e6ec49904c6bf553364736f6c634300081c0033000000000000000000000000000000000004444c5dc75cb358380d2e3de08a9000000000000000000000000043f8bc6d25be185711680987019d20543e6b53f6" + "4cddabff926dd66bb6638bcbe02b70423487b9fb5504ba145189f0d7aa4075c5610100604052348015610010575f5ffd5b5060405161216f38038061216f83398101604081905261002f916100d7565b6040805180820190915260048152630537761760e41b6020909101525f805460ff191690557fbce316f0d9d2a3affa97de1d99bb2aac0538e2666d0d8545545ead241ef0ccab6080526001600160a01b03831661009f57604051630f58648f60e01b815260040160405180910390fd5b6001600160a01b0392831660a05290821660c0521660e052610117565b80516001600160a01b03811681146100d2575f5ffd5b919050565b5f5f5f606084860312156100e9575f5ffd5b6100f2846100bc565b9250610100602085016100bc565b915061010e604085016100bc565b90509250925092565b60805160a05160c05160e05161200261016d5f395f81816102b7015261108101525f81816102de0152610bc201525f818161022401528181610d5501526111f601525f81816101f3015261029001526120025ff3fe608060405234801561000f575f5ffd5b5060043610610127575f3560e01c80636a014517116100a9578063a0cf0aea1161006e578063a0cf0aea146102b2578063c9b4f6da146102d9578063d06a1e8914610300578063e445e7dd14610313578063e77455171461032c575f5ffd5b80636a0145171461021f57806381cbe691146102465780638c4313c1146102595780638e14877614610279578063984d6e7a1461028b575f5ffd5b80632ae2fe3d116100ef5780632ae2fe3d146101ac57806338d52e0f146101bf5780633b5896bc146101d15780635492e677146101f1578063685a943c14610217575f5ffd5b806301bd43ef1461012b57806305b4fe911461014757806314cb37cf1461015c5780631f2646191461016f5780632113522a14610182575b5f5ffd5b61013460035c81565b6040519081526020015b60405180910390f35b61015a61015536600461163f565b61034f565b005b61015a61016a36600461169f565b6103c9565b61015a61017d3660046116ba565b6103ea565b6101946001600160a01b0360045c1681565b6040516001600160a01b03909116815260200161013e565b61015a6101ba36600461163f565b610443565b6101946001600160a01b0360025c1681565b6101e46101df36600461163f565b6104b6565b60405161013e9190611716565b7f0000000000000000000000000000000000000000000000000000000000000000610134565b6101345f5c81565b6101947f000000000000000000000000000000000000000000000000000000000000000081565b61013461025436600461169f565b6106ce565b61026c6102673660046117a3565b6106e6565b60405161013e91906117e1565b6101946001600160a01b0360015c1681565b6101347f000000000000000000000000000000000000000000000000000000000000000081565b6101947f000000000000000000000000000000000000000000000000000000000000000081565b6101947f000000000000000000000000000000000000000000000000000000000000000081565b61015a61030e36600461169f565b6107eb565b5f5461031f9060ff1681565b60405161013e91906117f3565b61033f61033a3660046118ce565b610868565b604051901515815260200161013e565b336001600160a01b038416146103785760405163e15e56c960e01b815260040160405180910390fd5b5f61038284610874565b905061038d81610887565b156103ab5760405163945b63f560e01b815260040160405180910390fd5b6103b6816001610894565b6103c2858585856108aa565b5050505050565b6103d28161090b565b50336004805c6001600160a01b0319168217905d5050565b5f6103f482610874565b90506103ff8161093d565b8061040e575061040e81610887565b1561042c5760405163441e4c7360e11b815260040160405180910390fd5b5f610438826001610946565b905083815d50505050565b336001600160a01b0384161461046c5760405163e15e56c960e01b815260040160405180910390fd5b5f61047684610874565b90506104818161093d565b1561049f57604051630bbb04d960e11b815260040160405180910390fd5b6104aa81600161099b565b6103c2858585856109a7565b60605f6104c5868686866109e9565b9050805160026104d5919061195b565b6001600160401b038111156104ec576104ec611819565b60405190808252806020026020018201604052801561053857816020015b60408051606080820183525f80835260208301529181019190915281526020019060019003908161050a5790505b5091506040518060600160405280306001600160a01b031681526020015f8152602001306001600160a01b0316632ae2fe3d89898989604051602401610581949392919061196e565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050815250825f815181106105c3576105c36119b6565b60209081029190910101525f5b8151811015610624578181815181106105eb576105eb6119b6565b602002602001015183826001610601919061195b565b81518110610611576106116119b6565b60209081029190910101526001016105d0565b506040518060600160405280306001600160a01b031681526020015f8152602001306001600160a01b03166305b4fe918989898960405160240161066b949392919061196e565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505081525082600184516106aa91906119ca565b815181106106ba576106ba6119b6565b602002602001018190525050949350505050565b5f6106e06106db83610874565b610e4b565b92915050565b60605f61072a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525060699250610e58915050565b90505f61077085858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525060899250869150610eba9050565b90505f61078b82600480855161078691906119ca565b610eba565b80602001905181019061079e9190611c67565b90508060600151602001516040516020016107d1919060609190911b6bffffffffffffffffffffffff1916815260140190565b604051602081830303815290604052935050505092915050565b336001600160a01b0360045c16146108165760405163e15e56c960e01b815260040160405180910390fd5b5f61082082610874565b905061082b8161093d565b158061083d575061083b81610887565b155b1561085b57604051634bd439b560e11b815260040160405180910390fd5b61086481610fc1565b5050565b5f6106e0826068610fd8565b5f5f61087f83611004565b5c9392505050565b5f5f61087f836003610946565b5f6108a0836003610946565b905081815d505050565b6109056108b6846106ce565b6108f58585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061107092505050565b6108ff91906119ca565b8461113a565b50505050565b5f6003805c908261091b83611d47565b9190505d505f61092a83611004565b905060035c80825d505060035c92915050565b5f5f61087f8360025b604080517fc41a07c57a776f6217c6d4278dfe7a5d114742afe55627ce458c2802aa4d703460208083019190915281830194909452606080820193909352815180820390930183526080019052805191012090565b5f6108a0836002610946565b6109056108ff8484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061107092505050565b60605f610a2a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509250611152915050565b90505f610a6e85858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525060289250610e58915050565b90505f610ab286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525060689250610fd8915050565b90505f610af687878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525060699250610e58915050565b90505f610b3c88888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525060899250869150610eba9050565b90505f610b48826111b6565b90508315610bef576040516381cbe69160e01b81526001600160a01b038b811660048301525f91908d16906381cbe69190602401602060405180830381865afa158015610b97573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bbb9190611d5f565b9050610be97f0000000000000000000000000000000000000000000000000000000000000000848389611225565b90955091505b60408051600480825260a0820190925290816020015b60408051606080820183525f808352602083015291810191909152815260200190600190039081610c0557905050604080516060810182526001600160a01b03808a1682525f60208301819052835191861660248301526044820152929950919082019060640160408051601f198184030181529190526020810180516001600160e01b031663095ea7b360e01b1790529052875188905f90610caa57610caa6119b6565b60200260200101819052506040518060600160405280876001600160a01b031681526020015f81526020018287604051602401610cfc9291906001600160a01b03929092168252602082015260400190565b60408051601f198184030181529190526020810180516001600160e01b031663095ea7b360e01b1790529052875188906001908110610d3d57610d3d6119b6565b602002602001018190525060405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020015f81526020018381525087600281518110610d9f57610d9f6119b6565b60200260200101819052506040518060600160405280876001600160a01b031681526020015f8152602001825f604051602401610df19291906001600160a01b03929092168252602082015260400190565b60408051601f198184030181529190526020810180516001600160e01b031663095ea7b360e01b1790529052875188906003908110610e3257610e326119b6565b6020026020010181905250505050505050949350505050565b5f5f61087f836001610946565b5f610e6482602061195b565b83511015610eb15760405162461bcd60e51b8152602060048201526015602482015274746f55696e743235365f6f75744f66426f756e647360581b60448201526064015b60405180910390fd5b50016020015190565b60608182601f011015610f005760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610ea8565b610f0a828461195b565b84511015610f4e5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610ea8565b606082158015610f6c5760405191505f825260208201604052610fb6565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015610fa5578051835260209283019201610f8d565b5050858452601f01601f1916604052505b5090505b9392505050565b610fcb815f61099b565b610fd5815f610894565b50565b5f828281518110610feb57610feb6119b6565b01602001516001600160f81b0319161515905092915050565b5f7f8ce092d4869bdfa1a1ce579ddddb2b776c39ace5d7b5d7e70e97ece2a78f4f9b8260405160200161105392919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b604051602081830303815290604052805190602001209050919050565b5f5f61107d836014611152565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316036110ca5750506001600160a01b038216316106e0565b6040516370a0823160e01b81526001600160a01b0385811660048301528216906370a0823190602401602060405180830381865afa15801561110e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111329190611d5f565b949350505050565b5f61114482610874565b90505f610438826001610946565b5f61115e82601461195b565b835110156111a65760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b6044820152606401610ea8565b500160200151600160601b900490565b5f5f6111cb83600480865161078691906119ca565b8060200190518101906111de9190611c67565b60208101519091506001600160a01b031661121b57507f000000000000000000000000000000000000000000000000000000000000000092915050565b6020015192915050565b6060825f0361124757604051630f6fa54560e41b815260040160405180910390fd5b6001600160a01b038516156112d75760405163726d379760e11b81526001600160a01b0386169063e4da6f2e906112849087908790600401611d76565b5f60405180830381865afa9250505080156112c057506040513d5f823e601f3d908101601f191682016040526112bd9190810190611d97565b60015b156112d75781156112d45791506111329050565b50505b6112e28484846112eb565b95945050505050565b6060815f0361130d57604051630f6fa54560e41b815260040160405180910390fd5b5f61132185600480885161078691906119ca565b8060200190518101906113349190611c67565b905061134a84848360600151610100015161147b565b60608201805161010001919091525160e0018490525f5b816060015160600151518110156113cb5761139e826060015160600151828151811061138f5761138f6119b6565b6020026020010151868661150a565b82606001516060015182815181106113b8576113b86119b6565b6020908102919091010152600101611361565b505f5b816060015160a0015151811015611429576113fc826060015160a00151828151811061138f5761138f6119b6565b826060015160a001518281518110611416576114166119b6565b60209081029190910101526001016113ce565b5060405163e21fd0e960e01b90611444908390602001611e5b565b60408051601f19818403018152908290526114629291602001611fb6565b6040516020818303038152906040529150509392505050565b5f825f0361148a575080610fba565b82841461150357828411156114d3575f6114b16114a785876119ca565b620186a08661150a565b90506114c18382620186a061150a565b6114cb908461195b565b925050611503565b5f6114e16114a786866119ca565b90505f6114f28483620186a061150a565b90506114fe81856119ca565b935050505b5092915050565b5f5f5f61151786866115ba565b91509150815f0361153b5783818161153157611531611fe1565b0492505050610fba565b8184116115525761155260038515026011186115d6565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b6001600160a01b0381168114610fd5575f5ffd5b5f5f83601f84011261160b575f5ffd5b5081356001600160401b03811115611621575f5ffd5b602083019150836020828501011115611638575f5ffd5b9250929050565b5f5f5f5f60608587031215611652575f5ffd5b843561165d816115e7565b9350602085013561166d816115e7565b925060408501356001600160401b03811115611687575f5ffd5b611693878288016115fb565b95989497509550505050565b5f602082840312156116af575f5ffd5b8135610fba816115e7565b5f5f604083850312156116cb575f5ffd5b8235915060208301356116dd816115e7565b809150509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561179757868503603f19018452815180516001600160a01b0316865260208082015190870152604090810151606091870182905290611781908701826116e8565b955050602093840193919091019060010161173c565b50929695505050505050565b5f5f602083850312156117b4575f5ffd5b82356001600160401b038111156117c9575f5ffd5b6117d5858286016115fb565b90969095509350505050565b602081525f610fba60208301846116e8565b602081016003831061181357634e487b7160e01b5f52602160045260245ffd5b91905290565b634e487b7160e01b5f52604160045260245ffd5b60405161016081016001600160401b038111828210171561185057611850611819565b60405290565b60405160a081016001600160401b038111828210171561185057611850611819565b604051601f8201601f191681016001600160401b03811182821017156118a0576118a0611819565b604052919050565b5f6001600160401b038211156118c0576118c0611819565b50601f01601f191660200190565b5f602082840312156118de575f5ffd5b81356001600160401b038111156118f3575f5ffd5b8201601f81018413611903575f5ffd5b8035611916611911826118a8565b611878565b81815285602083850101111561192a575f5ffd5b816020840160208301375f91810160200191909152949350505050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156106e0576106e0611947565b6001600160a01b038581168252841660208201526060604082018190528101829052818360808301375f818301608090810191909152601f909201601f191601019392505050565b634e487b7160e01b5f52603260045260245ffd5b818103818111156106e0576106e0611947565b80516119e8816115e7565b919050565b5f82601f8301126119fc575f5ffd5b8151611a0a611911826118a8565b818152846020838601011115611a1e575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f6001600160401b03821115611a5257611a52611819565b5060051b60200190565b5f82601f830112611a6b575f5ffd5b8151611a7961191182611a3a565b8082825260208201915060208360051b860101925085831115611a9a575f5ffd5b602085015b83811015611ac0578051611ab2816115e7565b835260209283019201611a9f565b5095945050505050565b5f82601f830112611ad9575f5ffd5b8151611ae761191182611a3a565b8082825260208201915060208360051b860101925085831115611b08575f5ffd5b602085015b83811015611ac0578051835260209283019201611b0d565b5f6101608284031215611b36575f5ffd5b611b3e61182d565b9050611b49826119dd565b8152611b57602083016119dd565b602082015260408201516001600160401b03811115611b74575f5ffd5b611b8084828501611a5c565b60408301525060608201516001600160401b03811115611b9e575f5ffd5b611baa84828501611aca565b60608301525060808201516001600160401b03811115611bc8575f5ffd5b611bd484828501611a5c565b60808301525060a08201516001600160401b03811115611bf2575f5ffd5b611bfe84828501611aca565b60a083015250611c1060c083016119dd565b60c082015260e08281015190820152610100808301519082015261012080830151908201526101408201516001600160401b03811115611c4e575f5ffd5b611c5a848285016119ed565b6101408301525092915050565b5f60208284031215611c77575f5ffd5b81516001600160401b03811115611c8c575f5ffd5b820160a08185031215611c9d575f5ffd5b611ca5611856565b611cae826119dd565b8152611cbc602083016119dd565b602082015260408201516001600160401b03811115611cd9575f5ffd5b611ce5868285016119ed565b60408301525060608201516001600160401b03811115611d03575f5ffd5b611d0f86828501611b25565b60608301525060808201516001600160401b03811115611d2d575f5ffd5b611d39868285016119ed565b608083015250949350505050565b5f60018201611d5857611d58611947565b5060010190565b5f60208284031215611d6f575f5ffd5b5051919050565b604081525f611d8860408301856116e8565b90508260208301529392505050565b5f5f60408385031215611da8575f5ffd5b82518015158114611db7575f5ffd5b60208401519092506001600160401b03811115611dd2575f5ffd5b611dde858286016119ed565b9150509250929050565b5f8151808452602084019350602083015f5b82811015611e215781516001600160a01b0316865260209586019590910190600101611dfa565b5093949350505050565b5f8151808452602084019350602083015f5b82811015611e21578151865260209586019590910190600101611e3d565b602080825282516001600160a01b0390811683830152908301511660408083019190915282015160a060608301525f90611e9860c08401826116e8565b6060850151848203601f1901608086015280516001600160a01b031682529091506020810151611ed360208401826001600160a01b03169052565b5060408101516101606040840152611eef610160840182611de8565b905060608201518382036060850152611f088282611e2b565b91505060808201518382036080850152611f228282611de8565b91505060a082015183820360a0850152611f3c8282611e2b565b91505060c0820151611f5960c08501826001600160a01b03169052565b5060e082015160e08401526101008201516101008401526101208201516101208401526101408201519150828103610140840152611f9781836116e8565b925050506080840151601f198483030160a08501526112e282826116e8565b6001600160e01b03198316815281515f908060208501600485015e5f92016004019182525092915050565b634e487b7160e01b5f52601260045260245ffdfea164736f6c634300081e000a0000000000000000000000006131b5fae19ea4f9d964eac0408e4408b66337b50000000000000000000000002f577a41bec1be1152aeea12e73b7391d15f655d000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" )), constructor_args: None, creation_bytecode: None, diff --git a/src/utils/deploy.rs b/src/utils/deploy.rs index 5593498..63f6fbd 100644 --- a/src/utils/deploy.rs +++ b/src/utils/deploy.rs @@ -29,7 +29,7 @@ pub async fn deploy_contract( .ok_or_else(|| DeployError::NoProvider(wallet.address()))?; let calldata: Bytes = if let Some(tx_data) = spec.deployer_tx { - Bytes::copy_from_slice(tx_data) + Bytes::from_static(tx_data) } else { let salt: FixedBytes<32> = spec.salt.ok_or(DeployError::MissingSalt(spec.name))?; let init_code: Bytes = spec diff --git a/src/utils/verifier.rs b/src/utils/verifier.rs index 52fb6ec..f4cc97c 100644 --- a/src/utils/verifier.rs +++ b/src/utils/verifier.rs @@ -3,8 +3,9 @@ use std::env::var; use std::fs::read_to_string; use std::process::Command; use std::process::Output; +use std::sync::Arc; use std::time::Duration; -use serde_json::{Value, Map}; +use serde_json::{Value, Map, from_str}; use alloy::primitives::{Address, hex}; use alloy::transports::http::reqwest; @@ -21,7 +22,7 @@ const POLL_INTERVAL: Duration = Duration::from_secs(3); const MAX_POLL_ATTEMPTS: u32 = 20; fn find_contract_file(source_json: &str, contract_name: &str) -> Option { - let parsed: Value = serde_json::from_str(source_json).ok()?; + let parsed: Value = from_str(source_json).ok()?; let sources: &Map = parsed.get("sources")?.as_object()?; let suffix: String = format!("{contract_name}.sol"); sources @@ -55,7 +56,7 @@ async fn fetch_verified_source( return Err(VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}"))); } - let mut source = resp.result.into_iter().next() + let mut source: SourceCodeResult = resp.result.into_iter().next() .ok_or_else(|| VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}")))?; if source.source_code.is_empty() || source.contract_name.is_empty() { @@ -116,7 +117,7 @@ async fn verify_cross_chain( } let guid: String = resp.result; - info!("Cross-chain verification submitted for '{name}' on {chain} (guid: {guid})"); + warn!("Cross-chain verification submitted for '{name}' on {chain} (guid: {guid})"); poll_verification_status(&client, target_chain_id, api_key, &guid, name).await } @@ -396,7 +397,7 @@ pub async fn run_verifications( let api_key: Option = var(Constants::ETHERSCAN_API_KEY_ENV).ok(); - let cross_chain_source: Option = + let cross_chain_source: Option> = if let (None, Some(addr), Some(key)) = (path, address, &api_key) { let source_chain_id: Option = source_chain.and_then(|sc| { let chain = Chain::from_flag(sc)?; @@ -411,7 +412,7 @@ pub async fn run_verifications( "Fetched source: {} ({})", source.contract_name, source.compiler_version ); - Some(source) + Some(Arc::new(source)) } Err(e) => { warn!("Failed to fetch source from source chain: {e}"); @@ -437,11 +438,7 @@ pub async fn run_verifications( let chain_id: Option = etherscan_chain_id(chain_key, network); let api_key: Option = api_key.clone(); let delay: u64 = i as u64; - let has_cross_chain: bool = cross_chain_source.is_some(); - let cross_source_code: Option = cross_chain_source.as_ref().map(|s| s.source_code.clone()); - let cross_contract_name: Option = cross_chain_source.as_ref().map(|s| s.contract_name.clone()); - let cross_compiler_version: Option = cross_chain_source.as_ref().map(|s| s.compiler_version.clone()); - let cross_constructor_args: Option = cross_chain_source.as_ref().map(|s| s.constructor_arguments.clone()); + let cross_source: Option> = cross_chain_source.clone(); verify_set.spawn(async move { if delay > 0 { @@ -458,13 +455,8 @@ pub async fn run_verifications( .map_err(|e| VerifierError::VerificationFailed(name, e.to_string())) .and_then(|r| r) } - (Some(addr), None, Some(cid), Some(key)) if has_cross_chain => { - let source = SourceCodeResult { - source_code: cross_source_code.unwrap(), - contract_name: cross_contract_name.unwrap(), - compiler_version: cross_compiler_version.unwrap(), - constructor_arguments: cross_constructor_args.unwrap(), - }; + (Some(addr), None, Some(cid), Some(key)) if cross_source.is_some() => { + let source = cross_source.unwrap(); verify_cross_chain(&key, &source, cid, addr, name, &chain).await } (None, _, _, _) => Err(VerifierError::MissingAddress(name)), From 088038498c4def17817e09822a573257dfd5a771 Mon Sep 17 00:00:00 2001 From: 0xKoiner Date: Mon, 6 Apr 2026 15:13:32 +0200 Subject: [PATCH 5/5] cargo fmt --- src/main.rs | 2 +- src/utils/mod.rs | 2 +- src/utils/print_intro.rs | 3 +-- src/utils/read_buf.rs | 4 +++- src/utils/verifier.rs | 30 +++++++++++++++++++----------- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index 670bd82..370519e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,6 @@ use log::{Level, error, warn}; use std::env::var; use std::process::exit; -use deterministic_deployer_evm::utils::print_intro::print_intro_log; use deterministic_deployer_evm::client::wallet_client::create_deployers; use deterministic_deployer_evm::data::contracts::create_contract_spec_from_args; use deterministic_deployer_evm::helpers::contract_searcher::resolve_contract; @@ -16,6 +15,7 @@ use deterministic_deployer_evm::types::constants::Constants; use deterministic_deployer_evm::types::errors::CliError; use deterministic_deployer_evm::utils::create_keystore::load_or_create_keystore; use deterministic_deployer_evm::utils::deploy::run_deployments; +use deterministic_deployer_evm::utils::print_intro::print_intro_log; use deterministic_deployer_evm::utils::read_buf::parse_args; use deterministic_deployer_evm::utils::verifier::run_verifications; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 6103946..d082050 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -4,6 +4,6 @@ pub mod create_keystore; pub mod deploy; pub mod init_explorers; pub mod init_rpc; +pub mod print_intro; pub mod read_buf; pub mod verifier; -pub mod print_intro; \ No newline at end of file diff --git a/src/utils/print_intro.rs b/src/utils/print_intro.rs index dd1f9ca..d6dd9e2 100644 --- a/src/utils/print_intro.rs +++ b/src/utils/print_intro.rs @@ -24,7 +24,6 @@ const INTRO: &str = r" (_______| |_______) "; - pub fn print_intro_log() { println!("\x1b[32m{INTRO}\x1b[0m"); -} \ No newline at end of file +} diff --git a/src/utils/read_buf.rs b/src/utils/read_buf.rs index 8b4ee46..00efeda 100644 --- a/src/utils/read_buf.rs +++ b/src/utils/read_buf.rs @@ -289,7 +289,9 @@ fn print_usage() { eprintln!(" --address Contract address (hex, with or without 0x)"); eprintln!(" --verify Enable contract verification"); eprintln!(" --keystore Create and use an encrypted keystore"); - eprintln!(" --source-chain Chain with verified source (for cross-chain verification)"); + eprintln!( + " --source-chain Chain with verified source (for cross-chain verification)" + ); eprintln!( " --constructor-args ABI-encoded constructor arguments (hex, with or without 0x)" ); diff --git a/src/utils/verifier.rs b/src/utils/verifier.rs index f4cc97c..6dfacd6 100644 --- a/src/utils/verifier.rs +++ b/src/utils/verifier.rs @@ -1,3 +1,4 @@ +use serde_json::{Map, Value, from_str}; use std::borrow::Cow; use std::env::var; use std::fs::read_to_string; @@ -5,7 +6,6 @@ use std::process::Command; use std::process::Output; use std::sync::Arc; use std::time::Duration; -use serde_json::{Value, Map, from_str}; use alloy::primitives::{Address, hex}; use alloy::transports::http::reqwest; @@ -14,7 +14,10 @@ use log::{error, info, warn}; use tokio::task::{JoinSet, spawn_blocking}; use tokio::time::sleep; -use crate::types::config::{Chain, ContractSpec, EtherscanResponse, PublicClient, WalletClient, SourceCodeResult, GetSourceCodeResponse}; +use crate::types::config::{ + Chain, ContractSpec, EtherscanResponse, GetSourceCodeResponse, PublicClient, SourceCodeResult, + WalletClient, +}; use crate::types::constants::Constants; use crate::types::errors::VerifierError; @@ -25,10 +28,7 @@ fn find_contract_file(source_json: &str, contract_name: &str) -> Option let parsed: Value = from_str(source_json).ok()?; let sources: &Map = parsed.get("sources")?.as_object()?; let suffix: String = format!("{contract_name}.sol"); - sources - .keys() - .find(|k| k.ends_with(&suffix)) - .cloned() + sources.keys().find(|k| k.ends_with(&suffix)).cloned() } async fn fetch_verified_source( @@ -53,14 +53,21 @@ async fn fetch_verified_source( .map_err(|e| VerifierError::HttpError(name, e.to_string()))?; if resp.status != "1" || resp.result.is_empty() { - return Err(VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}"))); + return Err(VerifierError::NotVerifiedOnSource(format!( + "chain_id {chain_id}" + ))); } - let mut source: SourceCodeResult = resp.result.into_iter().next() + let mut source: SourceCodeResult = resp + .result + .into_iter() + .next() .ok_or_else(|| VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}")))?; if source.source_code.is_empty() || source.contract_name.is_empty() { - return Err(VerifierError::NotVerifiedOnSource(format!("chain_id {chain_id}"))); + return Err(VerifierError::NotVerifiedOnSource(format!( + "chain_id {chain_id}" + ))); } if source.source_code.starts_with("{{") && source.source_code.ends_with("}}") { @@ -68,7 +75,8 @@ async fn fetch_verified_source( } if !source.contract_name.contains(':') { - let contract_file: Option = find_contract_file(&source.source_code, &source.contract_name); + let contract_file: Option = + find_contract_file(&source.source_code, &source.contract_name); if let Some(file) = contract_file { source.contract_name = format!("{file}:{}", source.contract_name); } @@ -479,4 +487,4 @@ pub async fn run_verifications( error!("Verification task panicked: {e}"); } } -} \ No newline at end of file +}