Verify smart contracts on Etherscan-compatible block explorers. This skill should be used when the user asks to "verify contract", "verify on etherscan", "verify on chain scan"...
Contract verification on Etherscan-compatible explorers using Foundry's forge verify-contract. Covers standard
verification, unsupported chains via Etherscan V2 API, proxy patterns, and factory-created contracts.
| Requirement | How to Get |
|---|---|
| Foundry ≥1.3.6 | Run forge -V to check version |
| Contract address | From deployment broadcast or user |
| Chain ID | From explorer or network configuration |
| Explorer API key | From Etherscan account (works for V2 multi-chain) |
| Source code | Must match deployed bytecode exactly |
Before proceeding, verify Foundry version:
forge -V
Stop if version is below 1.3.6.
For chains Foundry supports natively:
FOUNDRY_PROFILE=optimized forge verify-contract \
<CONTRACT_ADDRESS> \
src/<Contract>.sol:<Contract> \
--rpc-url <chain_name> \
--verifier etherscan \
--etherscan-api-key $ETHERSCAN_API_KEY \
--watch
When Foundry shows "No known Etherscan API URL for chain X":
FOUNDRY_PROFILE=optimized forge verify-contract \
<CONTRACT_ADDRESS> \
src/<Contract>.sol:<Contract> \
--verifier etherscan \
--verifier-url "https://api.etherscan.io/v2/api?chainid=<CHAIN_ID>" \
--etherscan-api-key $ETHERSCAN_API_KEY \
--watch
Supported chains: https://docs.etherscan.io/supported-chains
For contracts with constructor parameters:
FOUNDRY_PROFILE=optimized forge verify-contract \
<CONTRACT_ADDRESS> \
src/<Contract>.sol:<Contract> \
--verifier etherscan \
--verifier-url "https://api.etherscan.io/v2/api?chainid=<CHAIN_ID>" \
--etherscan-api-key $ETHERSCAN_API_KEY \
--constructor-args <ABI_ENCODED_ARGS> \
--watch
Generate constructor args with cast abi-encode:
cast abi-encode "constructor(address,uint256)" 0x123... 1000
Reference: ./references/special-cases.md
Verify implementation and proxy separately. See reference for ERC1967 pattern.
Extract constructor args from broadcast initCode using scripts/extract_constructor_args.py.
For libraries, use full path:
src/libraries/<Library>.sol:<Library>
Reference: ./references/troubleshooting.md
| Error | Cause | Solution |
|---|---|---|
| "No known Etherscan API URL" | Chain not in Foundry | Use --verifier-url with V2 API |
| "Bytecode does not match" | Compilation drift | Checkout deployment commit + reinstall deps |
| "Constructor args mismatch" | Wrong/missing args | Extract from broadcast or encode manually |
| "Already verified" | Previously verified | No action needed |
After successful verification:
Reference: ./references/examples.md for real-world verification examples from Monad deployment.