[FIXED] EIP-712 replayable signature in case of fork
Description
EIP-712 is a standard for the hashing and signing of typed, structured data. The standard code does not allow replaying signatures in case of a fork by default, as it rebuilds the domain separator in case the cached address of the contract and the cached chain ID differ to current values.
However, in the case of the project's implementation, the aforementioned checks are removed. The domain separator will not be updated in case of a fork, and the signature can be replayed.
function _domainSeparatorV4() internal view returns (bytes32) {
- if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
return _cachedDomainSeparator;
- } else {
- return _buildDomainSeparator();
- }
}
Impact
Even though the signatures can be replayed, the impact of this issue is relatively limited due to time constraints, mainly affecting the ERC20Permit implementation, which has direct access to user funds. The other contracts that use EIP-712 for verifying signatures do not allow performing actions on behalf of other users, so the impact there is limited to a user's own actions.
Recommendations
We recommend using the default implementation of the EIP-712 standard to remove the possibility of replaying signatures in case of a fork.
Remediation
The Nukem team remediated this issue in commit 46abe2cd↗ by always rebuilding the domain separator.