During a security audit engagement, Veridian Labs discovered a critical signature replay vulnerability in a cross-chain bridge protocol. The bridge's EIP-712 domain separator did not include the chainId parameter, allowing signatures generated on one chain to be replayed on other supported chains.
The bridge contract's domain separator was defined as:
bytes32 DOMAIN_SEPARATOR = keccak256(abi.encode(
keccak256("EIP712Domain(string name,string version,address verifyingContract)"),
keccak256(bytes(name)),
keccak256(bytes(version)),
address(this)
// Missing: chainId
));
This omission meant that a valid withdrawal signature on Ethereum mainnet could be replayed on Arbitrum, Optimism, Base, and all other chains where the bridge was deployed with the same contract address.
An attacker who observed a legitimate withdrawal transaction on any chain could replay the same signature on all other chains, potentially draining bridge liquidity across multiple networks simultaneously.
The vendor added block.chainid to the EIP-712 domain separator in v2.1.4 and invalidated all pending signatures. Existing users were required to re-sign pending transactions.
2026-03-08: Discovered • 2026-03-09: Vendor notified • 2026-03-11: Patch deployed • 2026-03-12: Advisory published
Discovered by Marcus Kim of Veridian Labs during a paid audit engagement.