Verification Failed: no_match - Ethereum Mainnet ERC5202 Contract
Verification Job Failed
Job ID: 8a141550-41c3-4d9f-82ca-b387b8092531
Chain: Ethereum Mainnet (1)
Contract Address: 0xf6134998c7a4e4ADDf71E2Ca1273A480E1d12d5d
Error Code: no_match
Server URL: https://sourcify.dev/server
Error Details
The deployed and recompiled bytecode don't match.
Additional Information
- Job Started: 2025-07-28T09:53:26.000Z
- Job Finished: 2025-07-28T09:53:42.000Z
User Input and Expectation
Why do you expect this verification to succeed? The contract has been verified on ethereum scan on mainnet. This is an ERC-5202 Blueprint contract.
Files Used: https://etherscan.io/address/0xf6134998c7a4e4addf71e2ca1273a480e1d12d5d#code#L1
Just took a look. This is a Vyper contract and an instance of #2233
This doesn't appear to be an instance of #2233. It's not fixed by the latest release of the verification ui
This is a ERC-5202 (Blueprint) contract as pointed out, and such contracts do not fit into the standard verification process of comparing onchain vs recompiled bytecodes. From my understanding the Blueprint pattern is how Vyper handles factories. The bytecode here is structured and we need to take into account the data and metadata snippets. Blockscout has a module handling Blueprints for reference.
Vyper also has a built-in create_from_blueprint function to create children contracts: https://docs.vyperlang.org/en/stable/built-in-functions.html#create_from_blueprint
I'll have a more detailed look tomorrow with a fresh mind
Now I see the situation. To summarize the ERC-5202 lays out an EVM bytecode spec (not a language spec) to deploy factories onchain that are not meant to be interacted with but only to be EXTCODECOPY'ed to save gas for repetetive deployments.
For example, if you deploy a contract with this pattern, you can use the following Vyper snippet to deploy new children contracts:
def deploy_new(name: String[32], symbol: String[32], supply: uint256, blueprint: address) -> address:
# code_offset default is 3, to skip ERC-5202 preamble
new_addr: address = create_from_blueprint(blueprint, name, symbol, supply)
return new_addr
To get the deployment bytecode for blueprint you can use vyper -f blueprint_bytecode
With that, this does not really fit into a standard verification process of comparing onchain vs recompiled bytecodes. Because the onchain code will have prefixes before the recompiled codes of the contract that is "being blueprinted".
For this example above, with their verified source code on Etherscan and Vyper:
- compiled runtime:
<COMPILED_RUNTIME> - compiled creation:
<constructor_code> <COMPILED_RUNTIME> <cbor_auxdata>= `<COMPILED_CREATION> - onchain runtime:
0xfe7100 <COMPILED_CREATION>- Here runtime code has "compiled creation" because the onchain runtime code is basically the initcode that deploys this contract.
-
00means in binary:00000000=00(version) +000000(data length)` so this contract has no data added.
- onchain creation:
0x615ddf3d81600a3d39f3 fe7100 <COMPILED_CREATION>- This is the bytecode snippet to deploys the blueprint as laid out in the spec
deploy_bytecode = b"\x61" + len_bytes + b"\x3d\x81\x60\x0a\x3d\x39\xf3"and can be seen in the Blockscout code.
- This is the bytecode snippet to deploys the blueprint as laid out in the spec
Considering this, again the given source code actually does not produce the onchain bytecode. However the children contracts copying code from this blueprint will actually match the source code.
So to me it seems we can't and maybe should not verify this contract. There's still benefit to verify it as an ERC5202 contract like Etherscan and Blockscout does:
https://etherscan.io/address/0xf6134998c7a4e4addf71e2ca1273a480e1d12d5d#code#L1 https://eth.blockscout.com/address/0xf6134998c7a4e4addf71e2ca1273a480e1d12d5d?tab=contract
For that we need to somehow mark this special case in the database and this seems very complicated to me. Another possibility is to do this on the server's end or on the frontend where, for a contract requested, we first parse the leading 2 bytes to see if it's 0xfe71xxxx and then we can confidently say this is a blueprint bytecode. After that, however, we need to find a matching bytecode for the <COMPILED_CREATION> but we don't do this yet. This will be done with #1642
I think this resembles our discussion on Minimal Proxies #1624. There also there was no source code corresponding to the bytecode. Here we have at least some source code whose bytecode is prefixed with some spec'ed code. I feel resolving this also on the fly is the way to go. But then again the question is should we somehow mark these special cases in the database. Maybe this also shows the need for a special case table in the database.
Let me know what your thoughts are on this.
Btw thanks for reporting this @Argeric
Are you aware of any contracts deployed via this blueprint? Since deployed contracts just copy the bytecode and don't call this blueprint, it's not possible to see those contracts on block explorers.