Skip to content

Commit 1e245aa

Browse files
YamenMerhiAmxxfrangio
authored
Add isValidERC1271SignatureNow to SignatureChecker library (#3932)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com> Co-authored-by: Francisco <fg@frang.io>
1 parent 815bfbf commit 1e245aa

File tree

3 files changed

+61
-39
lines changed

3 files changed

+61
-39
lines changed

.changeset/slimy-knives-hug.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openzeppelin-solidity': minor
3+
---
4+
5+
`SignatureChecker`: Add `isValidERC1271SignatureNow` for checking a signature directly against a smart contract using ERC-1271.

contracts/utils/cryptography/SignatureChecker.sol

+16-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,23 @@ library SignatureChecker {
2323
*/
2424
function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
2525
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
26-
if (error == ECDSA.RecoverError.NoError && recovered == signer) {
27-
return true;
28-
}
26+
return
27+
(error == ECDSA.RecoverError.NoError && recovered == signer) ||
28+
isValidERC1271SignatureNow(signer, hash, signature);
29+
}
2930

31+
/**
32+
* @dev Checks if a signature is valid for a given signer and data hash. The signature is validated
33+
* against the signer smart contract using ERC1271.
34+
*
35+
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
36+
* change through time. It could return true at block N and false at block N+1 (or the opposite).
37+
*/
38+
function isValidERC1271SignatureNow(
39+
address signer,
40+
bytes32 hash,
41+
bytes memory signature
42+
) internal view returns (bool) {
3043
(bool success, bytes memory result) = signer.staticcall(
3144
abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
3245
);

test/utils/cryptography/SignatureChecker.test.js

+40-36
Original file line numberDiff line numberDiff line change
@@ -40,44 +40,48 @@ contract('SignatureChecker (ERC1271)', function (accounts) {
4040
});
4141

4242
context('ERC1271 wallet', function () {
43-
it('with matching signer and signature', async function () {
44-
expect(
45-
await this.signaturechecker.$isValidSignatureNow(
46-
this.wallet.address,
47-
toEthSignedMessageHash(TEST_MESSAGE),
48-
this.signature,
49-
),
50-
).to.equal(true);
51-
});
43+
for (const signature of ['isValidERC1271SignatureNow', 'isValidSignatureNow']) {
44+
context(signature, function () {
45+
it('with matching signer and signature', async function () {
46+
expect(
47+
await this.signaturechecker[`$${signature}`](
48+
this.wallet.address,
49+
toEthSignedMessageHash(TEST_MESSAGE),
50+
this.signature,
51+
),
52+
).to.equal(true);
53+
});
5254

53-
it('with invalid signer', async function () {
54-
expect(
55-
await this.signaturechecker.$isValidSignatureNow(
56-
this.signaturechecker.address,
57-
toEthSignedMessageHash(TEST_MESSAGE),
58-
this.signature,
59-
),
60-
).to.equal(false);
61-
});
55+
it('with invalid signer', async function () {
56+
expect(
57+
await this.signaturechecker[`$${signature}`](
58+
this.signaturechecker.address,
59+
toEthSignedMessageHash(TEST_MESSAGE),
60+
this.signature,
61+
),
62+
).to.equal(false);
63+
});
6264

63-
it('with invalid signature', async function () {
64-
expect(
65-
await this.signaturechecker.$isValidSignatureNow(
66-
this.wallet.address,
67-
toEthSignedMessageHash(WRONG_MESSAGE),
68-
this.signature,
69-
),
70-
).to.equal(false);
71-
});
65+
it('with invalid signature', async function () {
66+
expect(
67+
await this.signaturechecker[`$${signature}`](
68+
this.wallet.address,
69+
toEthSignedMessageHash(WRONG_MESSAGE),
70+
this.signature,
71+
),
72+
).to.equal(false);
73+
});
7274

73-
it('with malicious wallet', async function () {
74-
expect(
75-
await this.signaturechecker.$isValidSignatureNow(
76-
this.malicious.address,
77-
toEthSignedMessageHash(TEST_MESSAGE),
78-
this.signature,
79-
),
80-
).to.equal(false);
81-
});
75+
it('with malicious wallet', async function () {
76+
expect(
77+
await this.signaturechecker[`$${signature}`](
78+
this.malicious.address,
79+
toEthSignedMessageHash(TEST_MESSAGE),
80+
this.signature,
81+
),
82+
).to.equal(false);
83+
});
84+
});
85+
}
8286
});
8387
});

0 commit comments

Comments
 (0)