Add isValidERC1271SignatureNow to SignatureChecker library (#3932)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com> Co-authored-by: Francisco <fg@frang.io>
This commit is contained in:
5
.changeset/slimy-knives-hug.md
Normal file
5
.changeset/slimy-knives-hug.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'openzeppelin-solidity': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
`SignatureChecker`: Add `isValidERC1271SignatureNow` for checking a signature directly against a smart contract using ERC-1271.
|
||||||
@ -23,10 +23,23 @@ library SignatureChecker {
|
|||||||
*/
|
*/
|
||||||
function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
|
function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
|
||||||
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
|
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
|
||||||
if (error == ECDSA.RecoverError.NoError && recovered == signer) {
|
return
|
||||||
return true;
|
(error == ECDSA.RecoverError.NoError && recovered == signer) ||
|
||||||
|
isValidERC1271SignatureNow(signer, hash, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Checks if a signature is valid for a given signer and data hash. The signature is validated
|
||||||
|
* against the signer smart contract using ERC1271.
|
||||||
|
*
|
||||||
|
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
|
||||||
|
* change through time. It could return true at block N and false at block N+1 (or the opposite).
|
||||||
|
*/
|
||||||
|
function isValidERC1271SignatureNow(
|
||||||
|
address signer,
|
||||||
|
bytes32 hash,
|
||||||
|
bytes memory signature
|
||||||
|
) internal view returns (bool) {
|
||||||
(bool success, bytes memory result) = signer.staticcall(
|
(bool success, bytes memory result) = signer.staticcall(
|
||||||
abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
|
abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -40,9 +40,11 @@ contract('SignatureChecker (ERC1271)', function (accounts) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('ERC1271 wallet', function () {
|
context('ERC1271 wallet', function () {
|
||||||
|
for (const signature of ['isValidERC1271SignatureNow', 'isValidSignatureNow']) {
|
||||||
|
context(signature, function () {
|
||||||
it('with matching signer and signature', async function () {
|
it('with matching signer and signature', async function () {
|
||||||
expect(
|
expect(
|
||||||
await this.signaturechecker.$isValidSignatureNow(
|
await this.signaturechecker[`$${signature}`](
|
||||||
this.wallet.address,
|
this.wallet.address,
|
||||||
toEthSignedMessageHash(TEST_MESSAGE),
|
toEthSignedMessageHash(TEST_MESSAGE),
|
||||||
this.signature,
|
this.signature,
|
||||||
@ -52,7 +54,7 @@ contract('SignatureChecker (ERC1271)', function (accounts) {
|
|||||||
|
|
||||||
it('with invalid signer', async function () {
|
it('with invalid signer', async function () {
|
||||||
expect(
|
expect(
|
||||||
await this.signaturechecker.$isValidSignatureNow(
|
await this.signaturechecker[`$${signature}`](
|
||||||
this.signaturechecker.address,
|
this.signaturechecker.address,
|
||||||
toEthSignedMessageHash(TEST_MESSAGE),
|
toEthSignedMessageHash(TEST_MESSAGE),
|
||||||
this.signature,
|
this.signature,
|
||||||
@ -62,7 +64,7 @@ contract('SignatureChecker (ERC1271)', function (accounts) {
|
|||||||
|
|
||||||
it('with invalid signature', async function () {
|
it('with invalid signature', async function () {
|
||||||
expect(
|
expect(
|
||||||
await this.signaturechecker.$isValidSignatureNow(
|
await this.signaturechecker[`$${signature}`](
|
||||||
this.wallet.address,
|
this.wallet.address,
|
||||||
toEthSignedMessageHash(WRONG_MESSAGE),
|
toEthSignedMessageHash(WRONG_MESSAGE),
|
||||||
this.signature,
|
this.signature,
|
||||||
@ -72,7 +74,7 @@ contract('SignatureChecker (ERC1271)', function (accounts) {
|
|||||||
|
|
||||||
it('with malicious wallet', async function () {
|
it('with malicious wallet', async function () {
|
||||||
expect(
|
expect(
|
||||||
await this.signaturechecker.$isValidSignatureNow(
|
await this.signaturechecker[`$${signature}`](
|
||||||
this.malicious.address,
|
this.malicious.address,
|
||||||
toEthSignedMessageHash(TEST_MESSAGE),
|
toEthSignedMessageHash(TEST_MESSAGE),
|
||||||
this.signature,
|
this.signature,
|
||||||
@ -80,4 +82,6 @@ contract('SignatureChecker (ERC1271)', function (accounts) {
|
|||||||
).to.equal(false);
|
).to.equal(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user