Find a domain mismatch in an EIP-712 signature
Two clients can display the same message text and still sign different digests. Compare the domain separator and the struct hash as two independent values.
Rebuild the digest in two stages
In a test fixture, sign a message with a verifier address A. Recompute its domain separator using address B while preserving the message fields and type definition. If verifyingContract belongs to the domain type, this changes the domain separator while leaving the struct hash unchanged.
keccak256(0x1901 || domainSeparator || hashStruct(message))
Log both intermediate hashes in each implementation. If only the struct hash differs, compare field order and declared types, including nested struct definitions. Use Ethereum Keccak-256 for the final digest.
Check the verifier’s own replay rules
A correctly reconstructed digest can still represent a replayable message. Verify any application nonce, deadline or one-time-use rule independently. EIP-712 defines the structured digest and leaves replay protection to the application. eips.ethereum.org EIP-712