Skip to content

Commit 5c0658b

Browse files
authored
Optimize ERC-1271 path in isValidSignatureNowCalldata to avoid extra allocation
1 parent 6308fdc commit 5c0658b

File tree

1 file changed

+30
-3
lines changed

1 file changed

+30
-3
lines changed

contracts/utils/cryptography/SignatureChecker.sol

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ library SignatureChecker {
5050
(address recovered, ECDSA.RecoverError err, ) = ECDSA.tryRecoverCalldata(hash, signature);
5151
return err == ECDSA.RecoverError.NoError && recovered == signer;
5252
} else {
53-
return isValidERC1271SignatureNow(signer, hash, signature);
53+
return isValidERC1271SignatureNowCalldata(signer, hash, signature);
5454
}
5555
}
5656

@@ -73,8 +73,8 @@ library SignatureChecker {
7373
// Encoded calldata is :
7474
// [ 0x00 - 0x03 ] <selector>
7575
// [ 0x04 - 0x23 ] <hash>
76-
// [ 0x24 - 0x44 ] <signature offset> (0x40)
77-
// [ 0x44 - 0x64 ] <signature length>
76+
// [ 0x24 - 0x43 ] <signature offset> (0x40)
77+
// [ 0x44 - 0x63 ] <signature length>
7878
// [ 0x64 - ... ] <signature data>
7979
let ptr := mload(0x40)
8080
mstore(ptr, selector)
@@ -87,6 +87,33 @@ library SignatureChecker {
8787
}
8888
}
8989

90+
function isValidERC1271SignatureNowCalldata(
91+
address signer,
92+
bytes32 hash,
93+
bytes calldata signature
94+
) internal view returns (bool result) {
95+
bytes4 selector = IERC1271.isValidSignature.selector;
96+
97+
assembly ("memory-safe") {
98+
// Encoded calldata is :
99+
// [ 0x00 - 0x03 ] <selector>
100+
// [ 0x04 - 0x23 ] <hash>
101+
// [ 0x24 - 0x43 ] <signature offset> (0x40)
102+
// [ 0x44 - 0x63 ] <signature length>
103+
// [ 0x64 - ... ] <signature data>
104+
let ptr := mload(0x40)
105+
mstore(ptr, selector)
106+
mstore(add(ptr, 0x04), hash)
107+
mstore(add(ptr, 0x24), 0x40)
108+
let length := signature.length
109+
mstore(add(ptr, 0x44), length)
110+
calldatacopy(add(ptr, 0x64), signature.offset, length)
111+
112+
let success := staticcall(gas(), signer, ptr, add(length, 0x64), 0x00, 0x20)
113+
result := and(success, and(gt(returndatasize(), 0x1f), eq(mload(0x00), selector)))
114+
}
115+
}
116+
90117
/**
91118
* @dev Verifies a signature for a given ERC-7913 signer and hash.
92119
*

0 commit comments

Comments
 (0)