Skip to content

Commit 6094bb7

Browse files
authored
Merge branch 'master' into utils/memory
2 parents ac92bb4 + be547e4 commit 6094bb7

File tree

6 files changed

+88
-62
lines changed

6 files changed

+88
-62
lines changed

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ Note as well that the Solidity language itself only guarantees security updates
4040

4141
## Legal
4242

43-
Smart contracts are a nascent technology and carry a high level of technical risk and uncertainty. OpenZeppelin Contracts is made available under the MIT License, which disclaims all warranties in relation to the project and which limits the liability of those that contribute and maintain the project, including OpenZeppelin. Your use of the project is also governed by the terms found at www.openzeppelin.com/tos (the "Terms"). As set out in the Terms, you are solely responsible for any use of OpenZeppelin Contracts and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an ongoing duty by any contributor, including OpenZeppelin, to correct any flaws or alert you to all or any of the potential risks of utilizing the project.
43+
Blockchain is a nascent technology and carries a high level of risk and uncertainty. OpenZeppelin makes certain software available under open source licenses, which disclaim all warranties in relation to the project and which limits the liability of OpenZeppelin. Subject to any particular licensing terms, your use of the project is governed by the terms found at [www.openzeppelin.com/tos](https://www.openzeppelin.com/tos) (the "Terms"). As set out in the Terms, you are solely responsible for any use of the project and you assume all risks associated with any such use. This Security Policy in no way evidences or represents an ongoing duty by any contributor, including OpenZeppelin, to correct any issues or vulnerabilities or alert you to all or any of the risks of utilizing the project.

contracts/utils/cryptography/SignatureChecker.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ library SignatureChecker {
2727
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
2828
* change through time. It could return true at block N and false at block N+1 (or the opposite).
2929
*
30-
* NOTE: For an extended version of this function that supports ERC-7913 signatures, see {isValidERC7913SignatureNow}.
30+
* NOTE: For an extended version of this function that supports ERC-7913 signatures, see {isValidSignatureNow-bytes-bytes32-bytes-}.
3131
*/
3232
function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
3333
if (signer.code.length == 0) {
@@ -73,7 +73,7 @@ library SignatureChecker {
7373
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
7474
* change through time. It could return true at block N and false at block N+1 (or the opposite).
7575
*/
76-
function isValidERC7913SignatureNow(
76+
function isValidSignatureNow(
7777
bytes memory signer,
7878
bytes32 hash,
7979
bytes memory signature
@@ -102,7 +102,7 @@ library SignatureChecker {
102102
* NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
103103
* change through time. It could return true at block N and false at block N+1 (or the opposite).
104104
*/
105-
function areValidERC7913SignaturesNow(
105+
function areValidSignaturesNow(
106106
bytes32 hash,
107107
bytes[] memory signers,
108108
bytes[] memory signatures
@@ -115,7 +115,7 @@ library SignatureChecker {
115115
bytes memory signer = signers[i];
116116

117117
// If one of the signatures is invalid, reject the batch
118-
if (!isValidERC7913SignatureNow(signer, hash, signatures[i])) return false;
118+
if (!isValidSignatureNow(signer, hash, signatures[i])) return false;
119119

120120
bytes32 id = keccak256(signer);
121121
// If the current signer ID is greater than all previous IDs, then this is a new signer.

contracts/utils/cryptography/signers/MultiSignerERC7913.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ abstract contract MultiSignerERC7913 is AbstractSigner {
209209
* Returns whether whether the signers are authorized and the signatures are valid for the given hash.
210210
*
211211
* IMPORTANT: Sorting the signers by their `keccak256` hash will improve the gas efficiency of this function.
212-
* See {SignatureChecker-areValidERC7913SignaturesNow} for more details.
212+
* See {SignatureChecker-areValidSignaturesNow-bytes32-bytes[]-bytes[]} for more details.
213213
*
214214
* Requirements:
215215
*
@@ -225,7 +225,7 @@ abstract contract MultiSignerERC7913 is AbstractSigner {
225225
return false;
226226
}
227227
}
228-
return hash.areValidERC7913SignaturesNow(signers, signatures);
228+
return hash.areValidSignaturesNow(signers, signatures);
229229
}
230230

231231
/**

contracts/utils/cryptography/signers/SignerERC7913.sol

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ abstract contract SignerERC7913 is AbstractSigner {
4141
_signer = signer_;
4242
}
4343

44-
/// @dev Verifies a signature using {SignatureChecker-isValidERC7913SignatureNow} with {signer}, `hash` and `signature`.
44+
/**
45+
* @dev Verifies a signature using {SignatureChecker-isValidSignatureNow-bytes-bytes32-bytes-}
46+
* with {signer}, `hash` and `signature`.
47+
*/
4548
function _rawSignatureValidation(
4649
bytes32 hash,
4750
bytes calldata signature
4851
) internal view virtual override returns (bool) {
49-
return SignatureChecker.isValidERC7913SignatureNow(signer(), hash, signature);
52+
return SignatureChecker.isValidSignatureNow(signer(), hash, signature);
5053
}
5154
}

docs/modules/ROOT/pages/utilities.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ A signer is represented as a `bytes` object that concatenates a verifier address
142142
[source,solidity]
143143
----
144144
function _verifyERC7913Signature(bytes memory signer, bytes32 hash, bytes memory signature) internal view returns (bool) {
145-
return SignatureChecker.isValidERC7913SignatureNow(signer, hash, signature);
145+
return SignatureChecker.isValidSignatureNow(signer, hash, signature);
146146
}
147147
----
148148

@@ -163,7 +163,7 @@ function _verifyMultipleSignatures(
163163
bytes[] memory signers,
164164
bytes[] memory signatures
165165
) internal view returns (bool) {
166-
return SignatureChecker.areValidERC7913SignaturesNow(hash, signers, signatures);
166+
return SignatureChecker.areValidSignaturesNow(hash, signers, signatures);
167167
}
168168
----
169169

test/utils/cryptography/SignatureChecker.test.js

Lines changed: 74 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -33,97 +33,121 @@ describe('SignatureChecker (ERC1271)', function () {
3333

3434
describe('EOA account', function () {
3535
it('with matching signer and signature', async function () {
36-
await expect(this.mock.$isValidSignatureNow(this.signer, TEST_MESSAGE_HASH, this.signature)).to.eventually.be
37-
.true;
36+
await expect(
37+
this.mock.$isValidSignatureNow(ethers.Typed.address(this.signer.address), TEST_MESSAGE_HASH, this.signature),
38+
).to.eventually.be.true;
3839
});
3940

4041
it('with invalid signer', async function () {
41-
await expect(this.mock.$isValidSignatureNow(this.other, TEST_MESSAGE_HASH, this.signature)).to.eventually.be
42-
.false;
42+
await expect(
43+
this.mock.$isValidSignatureNow(ethers.Typed.address(this.other.address), TEST_MESSAGE_HASH, this.signature),
44+
).to.eventually.be.false;
4345
});
4446

4547
it('with invalid signature', async function () {
46-
await expect(this.mock.$isValidSignatureNow(this.signer, WRONG_MESSAGE_HASH, this.signature)).to.eventually.be
47-
.false;
48+
await expect(
49+
this.mock.$isValidSignatureNow(ethers.Typed.address(this.signer.address), WRONG_MESSAGE_HASH, this.signature),
50+
).to.eventually.be.false;
4851
});
4952
});
5053

5154
describe('ERC1271 wallet', function () {
5255
for (const fn of ['isValidERC1271SignatureNow', 'isValidSignatureNow']) {
5356
describe(fn, function () {
5457
it('with matching signer and signature', async function () {
55-
await expect(this.mock.getFunction(`$${fn}`)(this.wallet, TEST_MESSAGE_HASH, this.signature)).to.eventually.be
56-
.true;
58+
await expect(
59+
this.mock.getFunction(`$${fn}`)(
60+
ethers.Typed.address(this.wallet.target),
61+
TEST_MESSAGE_HASH,
62+
this.signature,
63+
),
64+
).to.eventually.be.true;
5765
});
5866

5967
it('with invalid signer', async function () {
60-
await expect(this.mock.getFunction(`$${fn}`)(this.mock, TEST_MESSAGE_HASH, this.signature)).to.eventually.be
61-
.false;
68+
await expect(
69+
this.mock.getFunction(`$${fn}`)(ethers.Typed.address(this.mock.target), TEST_MESSAGE_HASH, this.signature),
70+
).to.eventually.be.false;
6271
});
6372

6473
it('with identity precompile', async function () {
65-
await expect(this.mock.getFunction(`$${fn}`)(precompile.identity, TEST_MESSAGE_HASH, this.signature)).to
66-
.eventually.be.false;
74+
await expect(
75+
this.mock.getFunction(`$${fn}`)(
76+
ethers.Typed.address(precompile.identity),
77+
TEST_MESSAGE_HASH,
78+
this.signature,
79+
),
80+
).to.eventually.be.false;
6781
});
6882

6983
it('with invalid signature', async function () {
70-
await expect(this.mock.getFunction(`$${fn}`)(this.wallet, WRONG_MESSAGE_HASH, this.signature)).to.eventually
71-
.be.false;
84+
await expect(
85+
this.mock.getFunction(`$${fn}`)(
86+
ethers.Typed.address(this.wallet.target),
87+
WRONG_MESSAGE_HASH,
88+
this.signature,
89+
),
90+
).to.eventually.be.false;
7291
});
7392

7493
it('with malicious wallet', async function () {
75-
await expect(this.mock.getFunction(`$${fn}`)(this.malicious, TEST_MESSAGE_HASH, this.signature)).to.eventually
76-
.be.false;
94+
await expect(
95+
this.mock.getFunction(`$${fn}`)(
96+
ethers.Typed.address(this.malicious.target),
97+
TEST_MESSAGE_HASH,
98+
this.signature,
99+
),
100+
).to.eventually.be.false;
77101
});
78102
});
79103
}
80104
});
81105

82106
describe('ERC7913', function () {
83-
describe('isValidERC7913SignatureNow', function () {
107+
describe('isValidSignatureNow', function () {
84108
describe('with EOA signer', function () {
85109
it('with matching signer and signature', async function () {
86110
const eoaSigner = ethers.zeroPadValue(this.signer.address, 20);
87111
const signature = await this.signer.signMessage(TEST_MESSAGE);
88-
await expect(this.mock.$isValidERC7913SignatureNow(eoaSigner, TEST_MESSAGE_HASH, signature)).to.eventually.be
89-
.true;
112+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(eoaSigner), TEST_MESSAGE_HASH, signature)).to
113+
.eventually.be.true;
90114
});
91115

92116
it('with invalid signer', async function () {
93117
const eoaSigner = ethers.zeroPadValue(this.other.address, 20);
94118
const signature = await this.signer.signMessage(TEST_MESSAGE);
95-
await expect(this.mock.$isValidERC7913SignatureNow(eoaSigner, TEST_MESSAGE_HASH, signature)).to.eventually.be
96-
.false;
119+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(eoaSigner), TEST_MESSAGE_HASH, signature)).to
120+
.eventually.be.false;
97121
});
98122

99123
it('with invalid signature', async function () {
100124
const eoaSigner = ethers.zeroPadValue(this.signer.address, 20);
101125
const signature = await this.signer.signMessage(TEST_MESSAGE);
102-
await expect(this.mock.$isValidERC7913SignatureNow(eoaSigner, WRONG_MESSAGE_HASH, signature)).to.eventually.be
103-
.false;
126+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(eoaSigner), WRONG_MESSAGE_HASH, signature)).to
127+
.eventually.be.false;
104128
});
105129
});
106130

107131
describe('with ERC-1271 wallet', function () {
108132
it('with matching signer and signature', async function () {
109133
const walletSigner = ethers.zeroPadValue(this.wallet.target, 20);
110134
const signature = await this.signer.signMessage(TEST_MESSAGE);
111-
await expect(this.mock.$isValidERC7913SignatureNow(walletSigner, TEST_MESSAGE_HASH, signature)).to.eventually
112-
.be.true;
135+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(walletSigner), TEST_MESSAGE_HASH, signature))
136+
.to.eventually.be.true;
113137
});
114138

115139
it('with invalid signer', async function () {
116140
const walletSigner = ethers.zeroPadValue(this.mock.target, 20);
117141
const signature = await this.signer.signMessage(TEST_MESSAGE);
118-
await expect(this.mock.$isValidERC7913SignatureNow(walletSigner, TEST_MESSAGE_HASH, signature)).to.eventually
119-
.be.false;
142+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(walletSigner), TEST_MESSAGE_HASH, signature))
143+
.to.eventually.be.false;
120144
});
121145

122146
it('with invalid signature', async function () {
123147
const walletSigner = ethers.zeroPadValue(this.wallet.target, 20);
124148
const signature = await this.signer.signMessage(TEST_MESSAGE);
125-
await expect(this.mock.$isValidERC7913SignatureNow(walletSigner, WRONG_MESSAGE_HASH, signature)).to.eventually
126-
.be.false;
149+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(walletSigner), WRONG_MESSAGE_HASH, signature))
150+
.to.eventually.be.false;
127151
});
128152
});
129153

@@ -136,8 +160,8 @@ describe('SignatureChecker (ERC1271)', function () {
136160
]);
137161
const signature = await aliceP256.signMessage(TEST_MESSAGE);
138162

139-
await expect(this.mock.$isValidERC7913SignatureNow(signer, TEST_MESSAGE_HASH, signature)).to.eventually.be
140-
.true;
163+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(signer), TEST_MESSAGE_HASH, signature)).to
164+
.eventually.be.true;
141165
});
142166

143167
it('with invalid verifier', async function () {
@@ -148,16 +172,16 @@ describe('SignatureChecker (ERC1271)', function () {
148172
]);
149173
const signature = await aliceP256.signMessage(TEST_MESSAGE);
150174

151-
await expect(this.mock.$isValidERC7913SignatureNow(signer, TEST_MESSAGE_HASH, signature)).to.eventually.be
152-
.false;
175+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(signer), TEST_MESSAGE_HASH, signature)).to
176+
.eventually.be.false;
153177
});
154178

155179
it('with invalid key', async function () {
156180
const signer = ethers.concat([this.verifier.target, ethers.randomBytes(32)]);
157181
const signature = await aliceP256.signMessage(TEST_MESSAGE);
158182

159-
await expect(this.mock.$isValidERC7913SignatureNow(signer, TEST_MESSAGE_HASH, signature)).to.eventually.be
160-
.false;
183+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(signer), TEST_MESSAGE_HASH, signature)).to
184+
.eventually.be.false;
161185
});
162186

163187
it('with invalid signature', async function () {
@@ -168,29 +192,28 @@ describe('SignatureChecker (ERC1271)', function () {
168192
]);
169193
const signature = ethers.randomBytes(65); // invalid (random) signature
170194

171-
await expect(this.mock.$isValidERC7913SignatureNow(signer, TEST_MESSAGE_HASH, signature)).to.eventually.be
172-
.false;
195+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(signer), TEST_MESSAGE_HASH, signature)).to
196+
.eventually.be.false;
173197
});
174198

175199
it('with signer too short', async function () {
176200
const signer = ethers.randomBytes(19); // too short
177201
const signature = await aliceP256.signMessage(TEST_MESSAGE);
178-
await expect(this.mock.$isValidERC7913SignatureNow(signer, TEST_MESSAGE_HASH, signature)).to.eventually.be
179-
.false;
202+
await expect(this.mock.$isValidSignatureNow(ethers.Typed.bytes(signer), TEST_MESSAGE_HASH, signature)).to
203+
.eventually.be.false;
180204
});
181205
});
182206
});
183207

184-
describe('areValidERC7913SignaturesNow', function () {
208+
describe('areValidSignaturesNow', function () {
185209
const sortSigners = (...signers) =>
186210
signers.sort(({ signer: a }, { signer: b }) => ethers.keccak256(b) - ethers.keccak256(a));
187211

188212
it('should validate a single signature', async function () {
189213
const signer = ethers.zeroPadValue(this.signer.address, 20);
190214
const signature = await this.signer.signMessage(TEST_MESSAGE);
191215

192-
await expect(this.mock.$areValidERC7913SignaturesNow(TEST_MESSAGE_HASH, [signer], [signature])).to.eventually.be
193-
.true;
216+
await expect(this.mock.$areValidSignaturesNow(TEST_MESSAGE_HASH, [signer], [signature])).to.eventually.be.true;
194217
});
195218

196219
it('should validate multiple signatures with different signer types', async function () {
@@ -214,7 +237,7 @@ describe('SignatureChecker (ERC1271)', function () {
214237
);
215238

216239
await expect(
217-
this.mock.$areValidERC7913SignaturesNow(
240+
this.mock.$areValidSignaturesNow(
218241
TEST_MESSAGE_HASH,
219242
signers.map(({ signer }) => signer),
220243
signers.map(({ signature }) => signature),
@@ -235,7 +258,7 @@ describe('SignatureChecker (ERC1271)', function () {
235258
);
236259

237260
await expect(
238-
this.mock.$areValidERC7913SignaturesNow(
261+
this.mock.$areValidSignaturesNow(
239262
TEST_MESSAGE_HASH,
240263
signers.map(({ signer }) => signer),
241264
signers.map(({ signature }) => signature),
@@ -256,7 +279,7 @@ describe('SignatureChecker (ERC1271)', function () {
256279
);
257280

258281
await expect(
259-
this.mock.$areValidERC7913SignaturesNow(
282+
this.mock.$areValidSignaturesNow(
260283
TEST_MESSAGE_HASH,
261284
signers.map(({ signer }) => signer),
262285
signers.map(({ signature }) => signature),
@@ -285,7 +308,7 @@ describe('SignatureChecker (ERC1271)', function () {
285308
);
286309

287310
await expect(
288-
this.mock.$areValidERC7913SignaturesNow(
311+
this.mock.$areValidSignaturesNow(
289312
TEST_MESSAGE_HASH,
290313
signers.map(({ signer }) => signer),
291314
signers.map(({ signature }) => signature),
@@ -314,7 +337,7 @@ describe('SignatureChecker (ERC1271)', function () {
314337
).reverse(); // reverse
315338

316339
await expect(
317-
this.mock.$areValidERC7913SignaturesNow(
340+
this.mock.$areValidSignaturesNow(
318341
TEST_MESSAGE_HASH,
319342
signers.map(({ signer }) => signer),
320343
signers.map(({ signature }) => signature),
@@ -335,7 +358,7 @@ describe('SignatureChecker (ERC1271)', function () {
335358
);
336359

337360
await expect(
338-
this.mock.$areValidERC7913SignaturesNow(
361+
this.mock.$areValidSignaturesNow(
339362
TEST_MESSAGE_HASH,
340363
signers.map(({ signer }) => signer),
341364
signers.map(({ signature }) => signature),
@@ -356,7 +379,7 @@ describe('SignatureChecker (ERC1271)', function () {
356379
);
357380

358381
await expect(
359-
this.mock.$areValidERC7913SignaturesNow(
382+
this.mock.$areValidSignaturesNow(
360383
TEST_MESSAGE_HASH,
361384
signers.map(({ signer }) => signer),
362385
signers.map(({ signature }) => signature),
@@ -377,7 +400,7 @@ describe('SignatureChecker (ERC1271)', function () {
377400
);
378401

379402
await expect(
380-
this.mock.$areValidERC7913SignaturesNow(
403+
this.mock.$areValidSignaturesNow(
381404
TEST_MESSAGE_HASH,
382405
signers.map(({ signer }) => signer),
383406
signers.map(({ signature }) => signature).slice(1),
@@ -386,7 +409,7 @@ describe('SignatureChecker (ERC1271)', function () {
386409
});
387410

388411
it('should pass with empty arrays', async function () {
389-
await expect(this.mock.$areValidERC7913SignaturesNow(TEST_MESSAGE_HASH, [], [])).to.eventually.be.true;
412+
await expect(this.mock.$areValidSignaturesNow(TEST_MESSAGE_HASH, [], [])).to.eventually.be.true;
390413
});
391414
});
392415
});

0 commit comments

Comments
 (0)