EIP-712 Signature Validation Failing with viem/wagmi & OZ ECDSA.recover Despite Matching Digests #4653
Unanswered
keplerdigitals-avia
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone,
I'm encountering a persistent EIP-712 signature validation issue when trying to deploy an ERC1155 contract using a factory pattern (
ERC1155Factory.sol
) and client-side signing.Context:
wagmi
(useSignTypedDataAsync
) andviem
. Signing is handled by MetaMask.ethers.js
(v6+). Receives the config data and the user's signature, then calls the factory contract.EIP712
andECDSA.recover
for validation. Deployed on Sepolia.nonce
from the factory contract via API.domain
,types
, andmessage
(usingBigInt
fornonce
).signTypedDataAsync
.name
,symbol
,baseURI
,ownerAddress
) and theuserSignature
to the backend API.ERC1155Factory.deploy1155ForUser(name, symbol, baseURI, ownerAddress, userSignature)
.estimateGas
withexecution reverted: "ERC1155Factory: Invalid signature or owner"
. This indicates therequire(signer == owner)
check inside the contract (usingECDSA.recover
) is failing during simulation.Debugging Steps & Findings:
viem
), contract (ERC1155Factory.sol
), and backend (ethers.js
).nonce
is fetched correctly and passed asBigInt
tosignTypedDataAsync
.ERC1155Config
) in the EIP-712 type. Suspecting encoding differences betweenviem
and Solidity, we flattened the structure (DeployERC1155(string name, string symbol, string baseURI, address owner, uint256 nonce)
) across the contract, frontend types/message, and backend validation/hashing.viem
(hashTypedData
) in the frontend exactly matches the digest calculated byethers.js
(TypedDataEncoder.hash
) in the backend just before the contract call.0xb6172fa3ab619dc3f892b1ebb95361f4b85700e1bdcee9f7a40bca019b975593
vm.sign
on the calculated digest) for the exact same flattened contract logic pass successfully.ECDSA.recover
correctly validates the signature generated byvm.sign
.ecrecover
Test: Temporarily replacingECDSA.recover
with nativeecrecover
in the contract also failed to recover the correct address from theviem
/MetaMask signature, suggesting the issue lies with the signature format/interpretation itself. (We reverted back toECDSA.recover
afterwards).v
): Thev
value in the signature generated by the frontend appears correct (e.g.,0x1c
= 28).Core Problem:
Even with matching EIP-712 digests (confirmed across
viem
andethers.js
with the flattened structure) and using the standard OpenZeppelinECDSA.recover
, the signature generated byviem
/wagmi
/MetaMask (0x840f...
in the last test) is not considered valid by the contract duringestimateGas
.Specific Data (from last failing attempt):
0x3360648578FAFB04Eb3B46FdE7A1CF62126B30BD
0xBE1D984e4B9d66F4848a23423435762db7eAF1BD
0xb6172fa3ab619dc3f892b1ebb95361f4b85700e1bdcee9f7a40bca019b975593
viem
/MetaMask):0x840f97e4b53948734113c668ad6fcc12eca26ec4eb8c3925fe8bc128b6ebf37b4a5f549c75b2d34103c63e3ef3544e8161c9842f9a01734a1544613550739d201c
Question:
Has anyone encountered similar validation failures with
ECDSA.recover
for signatures generated byviem
/wagmi
/MetaMask, specifically when the EIP-712 digest is confirmed to be correct? Are there known subtle incompatibilities, signature formatting issues (beyond the standardv
value), or encoding nuances that could cause this?Any insights or suggestions on how to further debug the signature interpretation on the EVM side would be greatly appreciated!
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions