How EIP-712 domain separators prevent cross-contract signature replay
Answer
Fact. EIP-712 signs the digest
keccak256("\x19\x01" || domainSeparator || hashStruct(message))
and defines domainSeparator as the hash of an EIP712Domain. That domain may contain name, version, chainId, verifyingContract, and salt; verifyingContract is specifically the address of the contract that will verify the signature. Thus the domain is cryptographically included in what the signer signs, rather than being unsigned metadata. EIP-712, specification and domain definition.
Inference from the specification. Suppose contract A and contract B use the same message type and values, but each constructs the expected separator with its own address as verifyingContract. Their separators—and therefore their signed digests—differ. A signature made over A's digest will not authenticate the signer for B's digest (absent a break or collision in the cryptographic primitives). This is the cross-contract replay defense. The EIP's rationale says the separator keeps otherwise identical structures used by different applications from colliding, and notes that a target-contract address separates contracts. EIP-712, rationale.
For isolation across chains as well, the domain should also include the current chainId. ERC-5805 gives the common construction using name, version, chainId, and address(this), and says a separator unique to the contract and chain prevents replay from other domains. ERC-5805, delegateBySig.
Limits and uncertainty
Fact. The protection is not automatic merely because a signature is called “EIP-712.” A verifier must compute the expected domain consistently and actually include that separator in the digest it verifies. EIP-712 permits applications to omit domain fields, so omitting verifyingContract, or configuring two verifiers with the same domain, removes the claimed contract-specific binding. EIP-712, domain definition.
Fact. Domain separation does not prevent replay within the same domain. EIP-712 explicitly leaves repeated-message handling to the application; a nonce, consumed-authorization record, deadline, or idempotent action is still needed as appropriate. ERC-5805, for example, separately requires incrementing a signer nonce. EIP-712, security considerations and ERC-5805, nonce requirement.
Uncertainty / unanswered implementation question. Whether a particular deployed system is protected cannot be determined from EIP-712 compliance alone. Its verifier code, chosen domain fields and values, proxy/delegate-call architecture, chain-ID handling, and nonce or authorization-consumption logic must be inspected.