Skip to content

Commit 2b119bf

Browse files
committed
Update account generation to use code from 5.4.0-rc.1
1 parent 4871cb4 commit 2b119bf

File tree

6 files changed

+685
-1261
lines changed

6 files changed

+685
-1261
lines changed

packages/core/solidity/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
},
2424
"devDependencies": {
2525
"@openzeppelin/community-contracts": "https://github.com/OpenZeppelin/openzeppelin-community-contracts",
26-
"@openzeppelin/contracts": "^5.3.0",
27-
"@openzeppelin/contracts-upgradeable": "^5.3.0",
26+
"@openzeppelin/contracts": "^5.4.0-rc.1",
27+
"@openzeppelin/contracts-upgradeable": "^5.4.0-rc.1",
2828
"@types/node": "^20.0.0",
2929
"@types/semver": "^7.5.7",
3030
"ava": "^6.0.0",

packages/core/solidity/src/account.test.ts.md

Lines changed: 550 additions & 1113 deletions
Large diffs are not rendered by default.
-386 Bytes
Binary file not shown.

packages/core/solidity/src/account.ts

Lines changed: 87 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function addParents(c: ContractBuilder, opts: AccountOptions): void {
7676
// Base
7777
c.addParent({
7878
name: 'Account',
79-
path: `@openzeppelin/community-contracts/account/Account.sol`,
79+
path: `@openzeppelin/contracts/account/Account.sol`,
8080
});
8181
c.addOverride({ name: 'Account' }, functions._validateUserOp);
8282

@@ -93,28 +93,26 @@ function addParents(c: ContractBuilder, opts: AccountOptions): void {
9393
}
9494

9595
function addSignatureValidation(c: ContractBuilder, opts: AccountOptions) {
96-
switch (opts.signatureValidation) {
97-
case 'ERC7739':
98-
c.addParent({
99-
name: 'ERC7739',
100-
path: '@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol',
101-
});
102-
break;
103-
case 'ERC1271':
104-
c.addParent({
105-
name: 'IERC1271',
106-
path: '@openzeppelin/contracts/interfaces/IERC1271.sol',
107-
});
108-
c.addOverride({ name: 'IERC1271' }, functions.isValidSignature);
109-
if (!opts.ERC7579Modules) {
110-
c.setFunctionBody(
111-
[
112-
'return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);',
113-
],
114-
functions.isValidSignature,
115-
);
116-
}
117-
break;
96+
if (opts.signatureValidation === 'ERC7739') {
97+
c.addParent({
98+
name: 'ERC7739',
99+
path: '@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol',
100+
});
101+
} else if (opts.signatureValidation === 'ERC1271' && !opts.signatureValidation) {
102+
c.addParent({
103+
name: 'IERC1271',
104+
path: '@openzeppelin/contracts/interfaces/IERC1271.sol',
105+
});
106+
c.addOverride({ name: 'IERC1271' }, functions.isValidSignature);
107+
c.setFunctionBody(
108+
[
109+
'return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);',
110+
],
111+
functions.isValidSignature,
112+
);
113+
} else {
114+
// ERC1271 is natively supported by ERC-7579, no need to expose ERC-1271 manually
115+
// do nothing
118116
}
119117
}
120118

@@ -139,7 +137,7 @@ function addBatchedExecution(c: ContractBuilder, opts: AccountOptions): void {
139137
if (!opts.batchedExecution || !!opts.ERC7579Modules) return;
140138
c.addParent({
141139
name: 'ERC7821',
142-
path: '@openzeppelin/community-contracts/account/extensions/ERC7821.sol',
140+
path: '@openzeppelin/contracts/account/extensions/draft-ERC7821.sol',
143141
});
144142
c.addOverride({ name: 'ERC7821' }, functions._erc7821AuthorizedExecutor);
145143
c.setFunctionBody(
@@ -152,28 +150,30 @@ function addERC7579Modules(c: ContractBuilder, opts: AccountOptions): void {
152150
if (!opts.ERC7579Modules) return;
153151
c.addParent({
154152
name: opts.ERC7579Modules,
155-
path: `@openzeppelin/community-contracts/account/extensions/${opts.ERC7579Modules}.sol`,
153+
path: `@openzeppelin/contracts/account/extensions/draft-${opts.ERC7579Modules}.sol`,
156154
});
157155
if (opts.ERC7579Modules !== 'AccountERC7579') {
158156
c.addImportOnly({
159157
name: 'AccountERC7579',
160-
path: `@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol`,
158+
path: `@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol`,
161159
});
162160
}
163161
c.addOverride({ name: 'AccountERC7579' }, functions.isValidSignature);
164162
c.addOverride({ name: 'AccountERC7579' }, functions._validateUserOp);
165163

166-
if (opts.signatureValidation !== 'ERC7739') return;
167-
c.addOverride({ name: 'ERC7739' }, functions.isValidSignature);
168-
c.setFunctionBody(
169-
[
170-
'// ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).',
171-
'// If the returned value is 0xffffffff, fallback to ERC-7579 validation.',
172-
'bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);',
173-
'return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;',
174-
],
175-
functions.isValidSignature,
176-
);
164+
// ERC-7579 provides ERC-1271 interface. If ERC-7739 is enabled, we need to reconcile
165+
if (opts.signatureValidation === 'ERC7739') {
166+
c.addOverride({ name: 'ERC7739' }, functions.isValidSignature);
167+
c.setFunctionBody(
168+
[
169+
'// ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).',
170+
'// If the returned value is 0xffffffff, fallback to ERC-7579 validation.',
171+
'bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);',
172+
'return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;',
173+
],
174+
functions.isValidSignature,
175+
);
176+
}
177177
}
178178

179179
function addMultisigFunctions(c: ContractBuilder, opts: AccountOptions): void {
@@ -198,7 +198,7 @@ function addMultisigFunctions(c: ContractBuilder, opts: AccountOptions): void {
198198
}
199199

200200
function addEIP712(c: ContractBuilder, opts: AccountOptions): void {
201-
if (opts.signatureValidation != 'ERC7739') return;
201+
if (opts.signatureValidation !== 'ERC7739') return;
202202
c.addParent(
203203
{
204204
name: 'EIP712',
@@ -224,7 +224,7 @@ function overrideRawSignatureValidation(c: ContractBuilder, opts: AccountOptions
224224
if (opts.signer && opts.ERC7579Modules) {
225225
c.addImportOnly({
226226
name: 'AbstractSigner',
227-
path: '@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol',
227+
path: '@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol',
228228
});
229229
c.addOverride({ name: 'AbstractSigner' }, signerFunctions._rawSignatureValidation);
230230
c.addOverride({ name: 'AccountERC7579' }, signerFunctions._rawSignatureValidation);
@@ -244,53 +244,51 @@ function overrideRawSignatureValidation(c: ContractBuilder, opts: AccountOptions
244244
}
245245
}
246246

247-
const functions = {
248-
...defineFunctions({
249-
isValidSignature: {
250-
kind: 'public' as const,
251-
mutability: 'view' as const,
252-
args: [
253-
{ name: 'hash', type: 'bytes32' },
254-
{ name: 'signature', type: 'bytes calldata' },
255-
],
256-
returns: ['bytes4'],
257-
},
258-
_validateUserOp: {
259-
kind: 'internal' as const,
260-
args: [
261-
{ name: 'userOp', type: 'PackedUserOperation calldata' },
262-
{ name: 'userOpHash', type: 'bytes32' },
263-
],
264-
returns: ['uint256'],
265-
},
266-
_erc7821AuthorizedExecutor: {
267-
kind: 'internal' as const,
268-
args: [
269-
{ name: 'caller', type: 'address' },
270-
{ name: 'mode', type: 'bytes32' },
271-
{ name: 'executionData', type: 'bytes calldata' },
272-
],
273-
returns: ['bool'],
274-
mutability: 'view' as const,
275-
},
276-
addSigners: {
277-
kind: 'public' as const,
278-
args: [{ name: 'signers', type: 'bytes[] memory' }],
279-
},
280-
removeSigners: {
281-
kind: 'public' as const,
282-
args: [{ name: 'signers', type: 'bytes[] memory' }],
283-
},
284-
setThreshold: {
285-
kind: 'public' as const,
286-
args: [{ name: 'threshold', type: 'uint256' }],
287-
},
288-
setSignerWeights: {
289-
kind: 'public' as const,
290-
args: [
291-
{ name: 'signers', type: 'bytes[] memory' },
292-
{ name: 'weights', type: 'uint256[] memory' },
293-
],
294-
},
295-
}),
296-
};
247+
const functions = defineFunctions({
248+
isValidSignature: {
249+
kind: 'public' as const,
250+
mutability: 'view' as const,
251+
args: [
252+
{ name: 'hash', type: 'bytes32' },
253+
{ name: 'signature', type: 'bytes calldata' },
254+
],
255+
returns: ['bytes4'],
256+
},
257+
_validateUserOp: {
258+
kind: 'internal' as const,
259+
args: [
260+
{ name: 'userOp', type: 'PackedUserOperation calldata' },
261+
{ name: 'userOpHash', type: 'bytes32' },
262+
],
263+
returns: ['uint256'],
264+
},
265+
_erc7821AuthorizedExecutor: {
266+
kind: 'internal' as const,
267+
args: [
268+
{ name: 'caller', type: 'address' },
269+
{ name: 'mode', type: 'bytes32' },
270+
{ name: 'executionData', type: 'bytes calldata' },
271+
],
272+
returns: ['bool'],
273+
mutability: 'view' as const,
274+
},
275+
addSigners: {
276+
kind: 'public' as const,
277+
args: [{ name: 'signers', type: 'bytes[] memory' }],
278+
},
279+
removeSigners: {
280+
kind: 'public' as const,
281+
args: [{ name: 'signers', type: 'bytes[] memory' }],
282+
},
283+
setThreshold: {
284+
kind: 'public' as const,
285+
args: [{ name: 'threshold', type: 'uint64' }],
286+
},
287+
setSignerWeights: {
288+
kind: 'public' as const,
289+
args: [
290+
{ name: 'signers', type: 'bytes[] memory' },
291+
{ name: 'weights', type: 'uint64[] memory' },
292+
],
293+
},
294+
});

packages/core/solidity/src/signer.ts

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,106 +5,95 @@ export const SignerOptions = [false, 'ERC7702', 'ECDSA', 'P256', 'RSA', 'Multisi
55
export type SignerOptions = (typeof SignerOptions)[number];
66

77
export function addSigner(c: ContractBuilder, signer: SignerOptions): void {
8-
if (!signer) return;
9-
10-
c.addParent(signers[signer]);
11-
c.addOverride(
12-
{ name: signer === 'MultisigWeighted' ? signers.Multisig.name : signers[signer].name },
13-
signerFunctions._rawSignatureValidation,
14-
);
15-
16-
// ERC-7702 doesn't require initialization
17-
if (signer === 'ERC7702') return;
18-
19-
c.addParent({
20-
name: 'Initializable',
21-
path: '@openzeppelin/contracts/proxy/utils/Initializable.sol',
22-
});
23-
24-
// Add locking constructor
25-
c.addNatspecTag('@custom:oz-upgrades-unsafe-allow', 'constructor');
26-
c.addConstructorCode(`_disableInitializers();`);
27-
28-
// Add initializer
29-
const fn = signerFunctions[`initialize${signer}`];
30-
c.addModifier('initializer', fn);
31-
32-
switch (signer) {
33-
case 'Multisig':
34-
c.addFunctionCode(`_addSigners(${fn.args[0]!.name});`, fn);
35-
c.addFunctionCode(`_setThreshold(${fn.args[1]!.name});`, fn);
36-
break;
37-
case 'MultisigWeighted':
38-
c.addFunctionCode(`_addSigners(${fn.args[0]!.name});`, fn);
39-
c.addFunctionCode(`_setSignerWeights(${fn.args[0]!.name}, ${fn.args[1]!.name});`, fn);
40-
c.addFunctionCode(`_setThreshold(${fn.args[2]!.name});`, fn);
8+
// Add parent, and constructor/initializer logic
9+
switch(signer) {
10+
case false:
11+
return;
12+
case 'ERC7702':
13+
{
14+
c.addParent(signers[signer]);
4115
break;
16+
}
4217
case 'ECDSA':
4318
case 'P256':
4419
case 'RSA':
45-
c.addFunctionCode(`_setSigner(${fn.args.map(({ name }) => name).join(', ')});`, fn);
20+
case 'Multisig':
21+
case 'MultisigWeighted':
22+
{
23+
// TODO: support upgradeable here ?
24+
const { args } = signerFunctions[signer];
25+
args.forEach(arg => c.addConstructorArgument(arg));
26+
c.addParent(signers[signer], args.map(arg => ({ lit: arg.name })));
27+
break;
28+
}
4629
}
30+
31+
// override
32+
c.addOverride(
33+
{ name: signer === 'MultisigWeighted' ? signers.Multisig.name : signers[signer].name },
34+
signerFunctions._rawSignatureValidation,
35+
);
4736
}
4837

4938
export const signers = {
5039
ERC7702: {
5140
name: 'SignerERC7702',
52-
path: '@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol',
41+
path: '@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol',
5342
},
5443
ECDSA: {
5544
name: 'SignerECDSA',
56-
path: '@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol',
45+
path: '@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol',
5746
},
5847
P256: {
5948
name: 'SignerP256',
60-
path: '@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol',
49+
path: '@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol',
6150
},
6251
RSA: {
6352
name: 'SignerRSA',
64-
path: '@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol',
53+
path: '@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol',
6554
},
6655
Multisig: {
6756
name: 'MultiSignerERC7913',
68-
path: '@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol',
57+
path: '@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol',
6958
},
7059
MultisigWeighted: {
7160
name: 'MultiSignerERC7913Weighted',
72-
path: '@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol',
61+
path: '@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol',
7362
},
7463
};
7564

7665
export const signerFunctions = defineFunctions({
77-
initializeECDSA: {
66+
ECDSA: {
7867
kind: 'public' as const,
7968
args: [{ name: 'signer', type: 'address' }],
8069
},
81-
initializeP256: {
70+
P256: {
8271
kind: 'public' as const,
8372
args: [
8473
{ name: 'qx', type: 'bytes32' },
8574
{ name: 'qy', type: 'bytes32' },
8675
],
8776
},
88-
initializeRSA: {
77+
RSA: {
8978
kind: 'public' as const,
9079
args: [
9180
{ name: 'e', type: 'bytes memory' },
9281
{ name: 'n', type: 'bytes memory' },
9382
],
9483
},
95-
initializeMultisig: {
84+
Multisig: {
9685
kind: 'public' as const,
9786
args: [
9887
{ name: 'signers', type: 'bytes[] memory' },
99-
{ name: 'threshold', type: 'uint256' },
88+
{ name: 'threshold', type: 'uint64' },
10089
],
10190
},
102-
initializeMultisigWeighted: {
91+
MultisigWeighted: {
10392
kind: 'public' as const,
10493
args: [
10594
{ name: 'signers', type: 'bytes[] memory' },
106-
{ name: 'weights', type: 'uint256[] memory' },
107-
{ name: 'threshold', type: 'uint256' },
95+
{ name: 'weights', type: 'uint64[] memory' },
96+
{ name: 'threshold', type: 'uint64' },
10897
],
10998
},
11099
_rawSignatureValidation: {

0 commit comments

Comments
 (0)