Repository navigation
bug: testnet.arcscan.app contract verification API rejects all standard Blockscout formats #210
Description
Summary
The testnet.arcscan.app block explorer's contract verification API does not accept submissions via any standard Blockscout format. The only working verification path is the browser UI — which doesn't scale for multi-contract or multi-chain deployments.
Reproduction
Tested with four contracts (Paymaster, GasRelayer, FeeRouter, YieldVault) compiled with:
- Solidity
0.8.20 - Optimizer: enabled, 200 runs
evmVersion: "paris"
Format 1: Blockscout v1 flat source (POST /api?module=contract&action=verifysourcecode)
curl -X POST "https://testnet.arcscan.app/api?module=contract&action=verifysourcecode" \
--data-urlencode "addressHash=0x..." \
--data-urlencode "name=Paymaster" \
--data-urlencode "codeformat=solidity-single-file" \
--data-urlencode "compilerVersion=v0.8.20+commit.a1b79de6" \
--data-urlencode "optimization=true" \
--data-urlencode "optimizationRuns=200" \
--data-urlencode "evmVersion=paris" \
--data-urlencode "contractSourceCode@Paymaster.sol"Response: {"message":"Missing codeformat field","result":null,"status":"0"}
This error is returned even when codeformat is included in the request body. Tested with both application/x-www-form-urlencoded and multipart/form-data content types.
Format 2: Blockscout v2 JSON (POST /api/v2/smart-contracts/{address}/verification/via/flattened-code)
curl -X POST "https://testnet.arcscan.app/api/v2/smart-contracts/0x.../verification/via/flattened-code" \
-H "Content-Type: application/json" \
-d '{"compiler_version":"v0.8.20+commit.a1b79de6","contract_name":"Paymaster","files":{"Paymaster.sol":"..."},"is_optimization_enabled":true,"optimization_runs":200,"evm_version":"paris","constructor_args":"..."}'Response: "Bad request"
Format 3: Blockscout v2 multipart
curl -X POST "https://testnet.arcscan.app/api/v2/smart-contracts/0x.../verification/via/flattened-code" \
-F "compiler_version=v0.8.20+commit.a1b79de6" \
-F "contract_name=Paymaster" \
-F "files[]=@Paymaster.sol;type=text/plain" \
-F "is_optimization_enabled=true" \
-F "optimization_runs=200" \
-F "evm_version=paris" \
-F "constructor_args=..."Response: "Bad request"
Hardhat and Foundry
npx hardhat verify --network arcTestnet 0x...
# Error: Failed to send contract verification request.
# Endpoint URL: https://testnet.arcscan.app/api?module=contract&action=verifysourcecode
# Reason: Missing codeformat fieldforge verify-contract 0x... Paymaster \
--verifier blockscout \
--verifier-url https://testnet.arcscan.app/api
# same underlying v1 errorWhat works
The browser UI works:
- Open
https://testnet.arcscan.app/address/{address} - Click Contract → Verify & Publish
- Choose Solidity (Single file)
- Fill in compiler version, optimizer settings, paste source, paste constructor args
This works but requires one browser session per contract per chain — not viable for a 4-contract × 4-chain deployment.
Impact
- Builders cannot use
hardhat-verify,forge verify-contract, or custom CI scripts to verify contracts on Arc - All four standard Blockscout API formats fail
- No verified source means no ABI auto-read in Arcscan, which blocks contract UI and read/write tabs for users
Questions
- Is programmatic API verification intentionally disabled on
testnet.arcscan.app? - If not, what field name or format does the endpoint actually expect?
- Is there a plan to expose a working verification endpoint, or to integrate with a hosted verification service (e.g. Sourcify)?
Workaround (until fixed)
Use the Blockscout UI manually per contract. If deploying multiple contracts, keep a script that generates the ABI-encoded constructor args for each — the UI accepts a hex-encoded constructor arguments field.
import { ethers } from "ethers";
const coder = ethers.AbiCoder.defaultAbiCoder();
// Paymaster: constructor(address usdc, address relayer, address feeRecipient, uint256 gasRate)
const args = coder.encode(
["address","address","address","uint256"],
[USDC_ADDRESS, RELAYER, FEE_RECIPIENT, GAS_RATE]
).slice(2); // remove 0x prefix — paste this into the Arcscan UI
Activity
kutluhaneth46 commentedon Sep 12, 2026
Taking this. The v1 contract verify API does accept submissions when the request uses Etherscan-compatible field names; I will document the working Hardhat/Foundry path and the Blockscout-native field-name pitfall that produces the Misleading Missing codeformat error.
kutluhaneth46 commentedon Sep 12, 2026
Root cause confirmed: Arcscan
/apispeaks the Etherscan V1 verify dialect. Blockscout-native fields (addressHash,name,contractSourceCode) produce the misleadingMissing codeformat fieldresponse even whencodeformatis present. Etherscan-compatible fields (contractaddress,contractname,sourceCode,codeformat, …) accept the submission (status: 1+ GUID).Opened a docs + Foundry config PR: #396
docs(contracts): document Arcscan Etherscan-compatible verify API
osr21 commentedon Sep 14, 2026
External, unaffiliated contributor to Arc and Circle — advisory only, no write access. Verified the claims below independently against live endpoints before posting.
Confirmed the field-name diagnosis: hitting
testnet.arcscan.app/api?module=contract&action=verifysourcecodewith Blockscout-native fields reproduces the exactMissing codeformat fieldresponse, and switching to Etherscan V1 field names gets past that stage to a different validation error — consistent with the endpoint speaking the Etherscan dialect, not Blockscout's own. Also checkedhardhat.config.tsonmain: there's currently noetherscan/customChains/sourcifyentry at all, so the Hardhat half of this issue stays open even once #396 merges — worth its own issue rather than assuming it rides along with the Foundry fix.On the "hosted verification service" question in the original report: Sourcify already supports this chain today. Its public chain registry lists Arc Testnet (chain ID 5042002) as
supported: true, and the Memo contract used in #396's own repro (0x5294E9927c3306DcBaDb03fe70b92e01cCede505) already has anexact_matchverification recorded there from 2026-06-03 — earlier than, and independent of, its Arcscan verification (Arcscan's own record for the same address showsis_verified_via_sourcify: false, so the two verification stores aren't linked to each other). Practically, that means@nomicfoundation/hardhat-verify's built-insourcify: { enabled: true }(orsourcify-clidirectly) verifies against Arc Testnet right now with none of the Etherscan-dialect handling #396 has to document for Arcscan. For anyone blocked on CI verification today, that's a working path in parallel with the Arcscan fix, not just a fallback once Hardhat wiring for Arcscan lands.kutluhaneth46 commentedon Sep 14, 2026
Thanks @osr21 for the independent confirmation on the field-name diagnosis, and for the Sourcify note.
Agree the Hardhat half should not ride silently on #396. That path is already tracked separately in #384, which wires
@nomicfoundation/hardhat-verify+ ArcscancustomChainsfor Arc Testnet in this repo. #396 stays focused on the Arcscan Etherscan-dialect docs and Foundry config; #384 covers the in-repo Hardhat reference.The Sourcify observation is useful for anyone blocked on CI today: Arc Testnet is already in Sourcify's public registry, and the Memo address from the #396 repro has an
exact_matchthere independent of Arcscan. Worth calling out as a parallel verification path while Arcscan Hardhat wiring lands.huklaa commentedon Oct 9, 2026
@ZhiyuCircle @romac — could you assign #210 to me (@huklaa), or approve the scope below? With #396 now closed, I would like to take responsibility for the remaining Arcscan API verification guidance.
My proposed approach:
I will credit the diagnosis and prior work recorded by @kutluhaneth46 and @osr21, and distinguish fresh verification from checking an already-verified contract. Per CONTRIBUTING.md, I will wait for maintainer assignment/approval before submitting a PR. Please confirm the scope and whether the explorer/docs owners should be involved.
osr21 commentedon Oct 9, 2026
@huklaa I agree to this, @ZhiyuCircle please assign @huklaa
huklaa commentedon Oct 9, 2026
Thanks @osr21. I have prepared a scoped draft on my fork: https://github.com/huklaa/arc-node/blob/docs-210-verification-evidence/docs/arcscan-verification.md . It credits the prior diagnosis and keeps Hardhat work in #384 / #84.
New checks: the pinned Foundry v1.4.4 already uses Sourcify v2; no toolchain upgrade is needed just for that API migration. The existing Memo record reports runtimeMatch=exact_match but creationMatch=null, so I document that distinction. Its original compiler/optimizer/EVM settings and remappings also need to be preserved, rather than assuming today's repository defaults reproduce the deployment.
The draft covers terminal status polling and independent source/ABI checks; a GUID alone is not success. Fresh Arcscan validation is still outstanding: the read-only API request returned 403 in my environment and the embedded browser could not open that endpoint. I have not deployed or submitted a new verification.
I remain available to take this on once a maintainer confirms assignment/scope. A maintainer-approved, existing unverified deployment with its original build artifacts would let me complete the fresh end-to-end verification before an upstream PR.
osr21 commentedon Oct 10, 2026
Be sure to give credit