diff --git a/src/contracts/mixins/SignatureUtils.sol b/src/contracts/mixins/SignatureUtils.sol index 79a5e932a..18f9c8984 100644 --- a/src/contracts/mixins/SignatureUtils.sol +++ b/src/contracts/mixins/SignatureUtils.sol @@ -40,19 +40,21 @@ abstract contract SignatureUtils is ISignatureUtils { * for more detailed information please read EIP-712. * @dev Use `_calculateDomainSeparator` rather than using this function. */ - function domainSeparator() external view virtual returns (bytes32) { - return _calculateDomainSeparator(); + function domainSeparator() public view virtual returns (bytes32) { + /// forgefmt: disable-next-item + return block.chainid == _INITIAL_CHAIN_ID + // If the chain ID is the same, return the original domain separator. + ? _INITIAL_DOMAIN_SEPARATOR + // If the chain ID is different, return the new domain separator. + : _calculateDomainSeparator(); } /// INTERNAL HELPERS - /// @dev Helper for calculating the contract's current domain separator. + /// @dev Helper for calculating the contract's domain separator. function _calculateDomainSeparator() internal view returns (bytes32) { /// forgefmt: disable-next-item - return block.chainid == _INITIAL_CHAIN_ID ? - // If the chain ID is the same, return the original domain separator. - _INITIAL_DOMAIN_SEPARATOR : - // If the chain ID is different, return the new domain separator. + return keccak256( abi.encode( EIP712_DOMAIN_TYPEHASH, @@ -67,7 +69,7 @@ abstract contract SignatureUtils is ISignatureUtils { function _calculateSignableDigest( bytes32 hash ) internal view returns (bytes32) { - return keccak256(abi.encodePacked("\x19\x01", _calculateDomainSeparator(), hash)); + return keccak256(abi.encodePacked("\x19\x01", domainSeparator(), hash)); } /// @dev Helper for checking if a signature is valid, reverts if not valid. diff --git a/src/test/unit/mixins/SignatureUtilsUnit.t.sol b/src/test/unit/mixins/SignatureUtilsUnit.t.sol new file mode 100644 index 000000000..b6dffecfd --- /dev/null +++ b/src/test/unit/mixins/SignatureUtilsUnit.t.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import "forge-std/Test.sol"; +import "src/contracts/mixins/SignatureUtils.sol"; + +contract MockSigner { + mapping(bytes32 => mapping(bytes => bool)) public validSignatures; + + function setValidSignature(bytes32 digest, bytes memory signature, bool valid) public { + validSignatures[digest][signature] = valid; + } + + function isValidSignatureNow(bytes32 digest, bytes memory signature) public view returns (bool) { + return validSignatures[digest][signature]; + } +} + +contract SignatureUtilsUnit is Test, SignatureUtils { + uint256 signerPk; + address signer; + bytes32 hash; + bytes32 digest; + bytes32 expectedDomainSeparator; + + function setUp() public { + vm.chainId(1); + + signerPk = 1; + signer = vm.addr(signerPk); + + hash = keccak256(""); + digest = _calculateSignableDigest(hash); + + expectedDomainSeparator = keccak256( + abi.encode( + keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"), + keccak256(bytes("EigenLayer")), + block.chainid, + address(this) + ) + ); + } + + function test_domainSeparator_NonZero() public { + assertTrue(_INITIAL_DOMAIN_SEPARATOR != 0, "The initial domain separator should be non-zero"); + assertTrue(domainSeparator() != 0, "The domain separator should be non-zero"); + assertTrue(domainSeparator() == expectedDomainSeparator, "The domain separator should be as expected"); + } + + function test_domainSeparator_NewChainId() public { + bytes32 initialDomainSeparator = domainSeparator(); + + // Change the chain ID + vm.chainId(9999); + + bytes32 newDomainSeparator = domainSeparator(); + + assertTrue(newDomainSeparator != 0, "The new domain separator should be non-zero"); + assertTrue( + initialDomainSeparator != newDomainSeparator, + "The domain separator should change when the chain ID changes" + ); + } + + function test_checkIsValidSignatureNow_Expired() public { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, digest); + + vm.expectRevert(ISignatureUtils.SignatureExpired.selector); + _checkIsValidSignatureNow(signer, digest, abi.encode(r, s, v), block.timestamp - 1); + } + + function testFail_checkIsValidSignatureNow_InvalidSignature() public { + _checkIsValidSignatureNow(signer, digest, "", block.timestamp); + } +} \ No newline at end of file