Skip to content

docs(ensv2): correct VerifiableFactory verifyContract signature and address prediction - #588

Open
estmcmxci wants to merge 1 commit into
ensdomains:masterfrom
estmcmxci:fix/verifiable-factory-docs
Open

docs(ensv2): correct VerifiableFactory verifyContract signature and address prediction#588
estmcmxci wants to merge 1 commit into
ensdomains:masterfrom
estmcmxci:fix/verifiable-factory-docs

Conversation

@estmcmxci

@estmcmxci estmcmxci commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Two corrections to src/pages/ensv2/verifiable-factory.mdx, found while building an ENSv2 plugin against the Sepolia beta. Both are checked against ensdomains/verifiable-factory main and the deployed factory at 0x10dC6333CDFe1FCEf624c6e0a8221b91804Cd7ef.

1. verifyContract signature

The page documents verifyContract(address proxy, address expectedImplementation) → bool. The contract is:

function verifyContract(address proxy) public view returns (address implementation)

It returns the attested implementation, and reverts with VerificationFailed(proxy) when the proxy is not a contract, does not implement getVerifiableProxyData(), or the CREATE2 reconstruction does not match — it never returns false. A caller wanting a specific implementation compares the returned address. (src/VerifiableFactory.sol, verifyContract.)

2. predictProxyAddress computes the wrong address

The snippet builds initCode = proxyBytecode ‖ abi.encode(factoryAddress, outerSalt). The actual creation code (src/CloneProxyBytecode.sol, creationCode(logic, salt)) is the ERC-1167 minimal-proxy runtime over the factory's proxyLogic(), with the raw 32-byte outerSalt appended:

0x3d604d80600a3d3981f3363d3d373d3d3d363d73 ‖ proxyLogic ‖ 0x5af43d82803e903d91602b57fd5bf3 ‖ outerSalt

The factory address is not part of the initcode, and the salt is appended raw rather than ABI-encoded — so the documented snippet yields an address that will never be deployed. The corrected snippet also takes proxyLogic (read from VerifiableFactory.proxyLogic()) instead of an opaque proxyBytecode, and notes that deployer must be the eventual deployProxy caller since outerSalt mixes in msg.sender.

Verification

The corrected formula reproduces a real deployment on Sepolia. For deployer = owner = 0x0943142F488fb694141841bF46e17Be2bB5C7EE1 with the documented keccak256("OwnedResolver", owner, 0) salt:

  • predicted: 0xeda43c6884FD83bbb7774F2e27B6e2d6fb97D282
  • ProxyDeployed.proxyAddress in tx 0x23c4f73b…560f4ccf: 0xeda43c6884FD83bbb7774F2e27B6e2d6fb97D282
  • verifyContract(0xeda43c…)0x9EAe5C2730a7dD16BDD1DeE6421a1B91e3B0365e (PermissionedResolverImpl)

The same construction matches the repo's own tested helper (test/integration/fixtures/deployVerifiableProxy.ts) and script/setup.ts.

🤖 Generated with Claude Code

…ddress prediction

Two corrections to verifiable-factory.mdx, both checked against
ensdomains/verifiable-factory `main` and the Sepolia ENSv2 beta deployment.

1. verifyContract is `(address proxy) returns (address implementation)`, not
   `(proxy, expectedImplementation) returns (bool)`. It returns the attested
   implementation and reverts with VerificationFailed(proxy) on failure.

2. predictProxyAddress built the wrong initcode: it appended
   abi.encode(factoryAddress, outerSalt) to an opaque proxyBytecode. The
   creation code (CloneProxyBytecode.creationCode) is the ERC-1167 runtime over
   proxyLogic() with the raw 32-byte outerSalt appended; the factory address is
   not part of it. The corrected snippet reproduces a live Sepolia deployment:
   predicted 0xeda43c6884FD83bbb7774F2e27B6e2d6fb97D282 == ProxyDeployed in
   tx 0x23c4f73bd438ca597e60cd07c2bfb9d1c1cec92eb42e6b6e18fc2873560f4ccf.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNB6BYTHTTFPKdYbe1XMXp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant