EIP-712 Explained in Detail
EIP-712 is a standard for signing typed structured data. It makes signatures bind to a clear message type and domain instead of an opaque hash.
For auditors, EIP-712 is not replay protection by itself. It is a framework for building safer signed messages.
Smart contract example
A permit-like function may verify a signature over owner, spender, value, nonce, and deadline.
The EIP-712 domain should bind that signature to the expected app, version, chain, and verifying contract. If the contract omits spender or nonce, the signature may authorize more than the user intended.
EIP-712 in Auditing
Many protocols use signatures as access control. If the signed data is incomplete, stale, replayable, or valid in the wrong domain, the contract may execute an action the signer did not intend.
Commonly affected flows include approvals, swaps, withdrawals, orders, claims, and delegated execution.
Red flags in code
-
Domain omits
chainIdorverifyingContract. -
Nonce is missing, not consumed, or consumed after external calls.
-
Deadline is missing or not enforced.
-
Signed struct omits recipient, amount, token, spender, target contract, or action type.
-
Contract hashes data manually with
abi.encodePacked. -
Upgradeable contracts cache a domain separator incorrectly.
-
ecrecoveris used directly without malleability checks.
How to test or review it
-
Rebuild the signed digest from the spec and compare it to the contract implementation.
-
Test replay against the same contract, another contract, another chain, an expired deadline, a reused or invalid nonce, a different recipient, and a different amount.
-
Confirm nonce consumption is atomic.
-
Check that every security-critical execution parameter is included in the signed struct.
-
Recompute hashes with a trusted tool such as the Keccak-256 tool when reviewing custom digest code.
-
Review signature replay risk before reviewing higher-level integrations like Permit2.