forge_verify/etherscan/
standard_json.rs
1use super::{EtherscanSourceProvider, VerifyArgs};
2use crate::{provider::VerificationContext, verify::ContractLanguage};
3use eyre::{Context, Result};
4use foundry_block_explorers::verify::CodeFormat;
5use foundry_compilers::{
6 artifacts::{Source, StandardJsonCompilerInput, vyper::VyperInput},
7 solc::SolcLanguage,
8};
9use std::path::Path;
10
11#[derive(Debug)]
12pub struct EtherscanStandardJsonSource;
13impl EtherscanSourceProvider for EtherscanStandardJsonSource {
14 fn source(
15 &self,
16 args: &VerifyArgs,
17 context: &VerificationContext,
18 ) -> Result<(String, String, CodeFormat)> {
19 let mut input: StandardJsonCompilerInput = context
20 .project
21 .standard_json_input(&context.target_path)
22 .wrap_err("Failed to get standard json input")?
23 .normalize_evm_version(&context.compiler_version);
24
25 let lang = args.detect_language(context);
26
27 let code_format = match lang {
28 ContractLanguage::Solidity => CodeFormat::StandardJsonInput,
29 ContractLanguage::Vyper => CodeFormat::VyperJson,
30 };
31
32 let mut settings = context.compiler_settings.solc.settings.clone();
33 settings.libraries.libs = input
34 .settings
35 .libraries
36 .libs
37 .into_iter()
38 .map(|(f, libs)| {
39 (f.strip_prefix(context.project.root()).unwrap_or(&f).to_path_buf(), libs)
40 })
41 .collect();
42
43 settings.remappings = input.settings.remappings;
44
45 settings.sanitize(&context.compiler_version, SolcLanguage::Solidity);
47
48 input.settings = settings;
49
50 let source = match lang {
51 ContractLanguage::Solidity => {
52 serde_json::to_string(&input).wrap_err("Failed to parse standard json input")?
53 }
54 ContractLanguage::Vyper => {
55 let path = Path::new(&context.target_path);
56 let sources = Source::read_all_from(path, &["vy", "vyi"])?;
57 let input = VyperInput::new(
58 sources,
59 context.clone().compiler_settings.vyper,
60 &context.compiler_version,
61 );
62
63 serde_json::to_string(&input).wrap_err("Failed to parse vyper json input")?
64 }
65 };
66
67 trace!(target: "forge::verify", standard_json=source, "determined standard json input");
68
69 let name = format!(
70 "{}:{}",
71 context
72 .target_path
73 .strip_prefix(context.project.root())
74 .unwrap_or(context.target_path.as_path())
75 .display(),
76 context.target_name.clone()
77 );
78 Ok((source, name, code_format))
79 }
80}