@@ -2,17 +2,10 @@ import { ContractBuilder } from './contract';
2
2
import type { Contract } from './contract' ;
3
3
import { defineFunctions } from './utils/define-functions' ;
4
4
import { printContract } from './print' ;
5
- import { makeUpgradeable } from './helpers' ;
6
5
import { defaults as commonDefaults , withCommonDefaults , type CommonOptions } from './common-options' ;
6
+ import { upgradeableName } from './options' ;
7
7
import { setInfo } from './set-info' ;
8
- import {
9
- addLockingConstructorAllowReachable ,
10
- addSigner ,
11
- signerArgs ,
12
- signerFunctions ,
13
- signers ,
14
- type SignerOptions ,
15
- } from './signer' ;
8
+ import { addSigner , signerFunctions , signers , type SignerOptions } from './signer' ;
16
9
import { setUpgradeableAccount } from './set-upgradeable' ;
17
10
18
11
export const defaults : Required < AccountOptions > = {
@@ -75,6 +68,7 @@ export function buildAccount(opts: AccountOptions): Contract {
75
68
c . addImportOnly ( {
76
69
name : 'PackedUserOperation' ,
77
70
path : '@openzeppelin/contracts/interfaces/draft-IERC4337.sol' ,
71
+ transpiled : false , // PackedUserOperation doesn't start with "I" so its not recognized as an "interface object"
78
72
} ) ;
79
73
}
80
74
@@ -86,16 +80,16 @@ function addParents(c: ContractBuilder, opts: AccountOptions): void {
86
80
c . addParent ( {
87
81
name : 'Account' ,
88
82
path : `@openzeppelin/contracts/account/Account.sol` ,
83
+ transpiled : false ,
89
84
} ) ;
90
- c . addOverride ( { name : 'Account' } , functions . _validateUserOp ) ;
85
+ c . addOverride ( { name : 'Account' , transpiled : false } , functions . _validateUserOp ) ;
91
86
92
87
if ( opts . signatureValidation === 'ERC7739' ) addEIP712 ( c , opts ) ;
93
88
94
89
// Extensions
95
90
addSignatureValidation ( c , opts ) ;
96
91
addERC7579Modules ( c , opts ) ;
97
92
addSigner ( c , opts . signer ?? false , opts . upgradeable ?? false ) ;
98
- addSignerInitializer ( c , opts ) ;
99
93
addMultisigFunctions ( c , opts ) ;
100
94
addBatchedExecution ( c , opts ) ;
101
95
addERC721Holder ( c , opts ) ;
@@ -108,6 +102,7 @@ function addSignatureValidation(c: ContractBuilder, opts: AccountOptions) {
108
102
c . addParent ( {
109
103
name : 'ERC7739' ,
110
104
path : '@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol' ,
105
+ transpiled : false ,
111
106
} ) ;
112
107
break ;
113
108
case 'ERC1271' :
@@ -133,6 +128,7 @@ function addERC721Holder(c: ContractBuilder, opts: AccountOptions): void {
133
128
c . addParent ( {
134
129
name : 'ERC721Holder' ,
135
130
path : '@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol' ,
131
+ transpiled : false ,
136
132
} ) ;
137
133
}
138
134
@@ -141,6 +137,7 @@ function addERC1155Holder(c: ContractBuilder, opts: AccountOptions): void {
141
137
c . addParent ( {
142
138
name : 'ERC1155Holder' ,
143
139
path : '@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol' ,
140
+ transpiled : false ,
144
141
} ) ;
145
142
}
146
143
@@ -150,8 +147,9 @@ function addBatchedExecution(c: ContractBuilder, opts: AccountOptions): void {
150
147
c . addParent ( {
151
148
name : 'ERC7821' ,
152
149
path : '@openzeppelin/contracts/account/extensions/draft-ERC7821.sol' ,
150
+ transpiled : false ,
153
151
} ) ;
154
- c . addOverride ( { name : 'ERC7821' } , functions . _erc7821AuthorizedExecutor ) ;
152
+ c . addOverride ( { name : 'ERC7821' , transpiled : false } , functions . _erc7821AuthorizedExecutor ) ;
155
153
c . setFunctionBody (
156
154
[ 'return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);' ] ,
157
155
functions . _erc7821AuthorizedExecutor ,
@@ -161,112 +159,41 @@ function addBatchedExecution(c: ContractBuilder, opts: AccountOptions): void {
161
159
function addERC7579Modules ( c : ContractBuilder , opts : AccountOptions ) : void {
162
160
if ( ! opts . ERC7579Modules ) return ;
163
161
164
- // Base AccountERC7579 account (upgradeable or not)
165
- const name = makeUpgradeable ( 'AccountERC7579' , opts . upgradeable ) ;
166
-
167
162
c . addParent ( {
168
- name : makeUpgradeable ( opts . ERC7579Modules , opts . upgradeable ) ,
169
- path : makeUpgradeable (
170
- `@openzeppelin/contracts/account/extensions/draft-${ opts . ERC7579Modules } .sol` ,
171
- opts . upgradeable ,
172
- ) ,
163
+ name : opts . ERC7579Modules ,
164
+ path : `@openzeppelin/contracts/account/extensions/draft-${ opts . ERC7579Modules } .sol` ,
173
165
} ) ;
174
166
if ( opts . ERC7579Modules !== 'AccountERC7579' ) {
175
167
c . addImportOnly ( {
176
- name : makeUpgradeable ( 'AccountERC7579' , opts . upgradeable ) ,
177
- path : makeUpgradeable ( '@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol' , opts . upgradeable ) ,
168
+ name : 'AccountERC7579' ,
169
+ path : '@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol' ,
178
170
} ) ;
179
171
}
180
172
181
173
// Accounts that use ERC7579 without a signer must be constructed with at least one module (executor of validation)
182
174
if ( ! opts . signer ) {
183
- const args = [
184
- { type : 'uint256' , name : 'moduleTypeId' } ,
185
- { type : 'address' , name : 'module' } ,
186
- { type : 'bytes calldata' , name : 'initData' } ,
187
- ] ;
188
- const body = [
189
- 'require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);' ,
190
- '_installModule(moduleTypeId, module, initData);' ,
191
- ] ;
192
- if ( opts . upgradeable ) {
193
- c . addParent ( {
194
- name : 'Initializable' ,
195
- path : '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol' ,
196
- } ) ;
197
- addLockingConstructorAllowReachable ( c ) ;
198
-
199
- const fn = { name : 'initialize' , kind : 'public' as const , args } ;
200
- c . addModifier ( 'initializer' , fn ) ;
201
- c . setFunctionBody ( body , fn ) ;
202
- } else {
203
- for ( const arg of args ) c . addConstructorArgument ( arg ) ;
204
- for ( const line of body ) c . addConstructorCode ( line ) ;
205
- }
175
+ c . addConstructorArgument ( { type : 'uint256' , name : 'moduleTypeId' } ) ;
176
+ c . addConstructorArgument ( { type : 'address' , name : 'module' } ) ;
177
+ c . addConstructorArgument ( { type : 'bytes calldata' , name : 'initData' } ) ;
178
+ c . addConstructorCode ( 'require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);' ) ;
179
+ c . addConstructorCode ( '_installModule(moduleTypeId, module, initData);' ) ;
206
180
}
207
181
208
- // isValidSignature override
209
- c . addOverride ( { name } , functions . isValidSignature ) ;
182
+ c . addOverride ( { name : 'AccountERC7579' } , functions . _validateUserOp ) ;
183
+ c . addOverride ( { name : 'AccountERC7579' } , functions . isValidSignature ) ;
184
+
210
185
if ( opts . signatureValidation === 'ERC7739' ) {
211
- c . addOverride ( { name : 'ERC7739' } , functions . isValidSignature ) ;
186
+ c . addOverride ( { name : 'ERC7739' , transpiled : false } , functions . isValidSignature ) ;
212
187
c . setFunctionBody (
213
188
[
214
189
'// ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).' ,
215
190
'// If the returned value is 0xffffffff, fallback to ERC-7579 validation.' ,
216
191
'bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);' ,
217
- `return erc7739magic == bytes4(0xffffffff) ? ${ name } .isValidSignature(hash, signature) : erc7739magic;` ,
192
+ `return erc7739magic == bytes4(0xffffffff) ? ${ opts . upgradeable ? upgradeableName ( 'AccountERC7579' ) : 'AccountERC7579' } .isValidSignature(hash, signature) : erc7739magic;` ,
218
193
] ,
219
194
functions . isValidSignature ,
220
195
) ;
221
196
}
222
-
223
- // _validateUserOp override
224
- c . addOverride ( { name } , functions . _validateUserOp ) ;
225
- }
226
-
227
- function addSignerInitializer ( c : ContractBuilder , opts : AccountOptions ) : void {
228
- if ( opts . upgradeable ) {
229
- if ( ! opts . signer ) {
230
- addLockingConstructorAllowReachable ( c ) ;
231
- }
232
- return ; // Initializer added in signer.ts
233
- }
234
- if ( ! opts . signer || opts . signer === 'ERC7702' ) return ; // No initialization required
235
-
236
- c . addParent ( {
237
- name : 'Initializable' ,
238
- path : opts . upgradeable
239
- ? '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol'
240
- : '@openzeppelin/contracts/proxy/utils/Initializable.sol' ,
241
- } ) ;
242
-
243
- addLockingConstructorAllowReachable ( c , [
244
- '// Accounts are typically deployed and initialized as clones during their first user op,' ,
245
- '// therefore, initializers are disabled for the implementation contract' ,
246
- ] ) ;
247
-
248
- const fn = { name : 'initialize' , kind : 'public' as const , args : signerArgs [ opts . signer ] } ;
249
- c . addModifier ( 'initializer' , fn ) ;
250
-
251
- switch ( opts . signer ) {
252
- case 'Multisig' :
253
- c . addFunctionCode ( `_addSigners(${ signerArgs [ opts . signer ] [ 0 ] ! . name } );` , fn ) ;
254
- c . addFunctionCode ( `_setThreshold(${ signerArgs [ opts . signer ] [ 1 ] ! . name } );` , fn ) ;
255
- break ;
256
- case 'MultisigWeighted' :
257
- c . addFunctionCode ( `_addSigners(${ signerArgs [ opts . signer ] [ 0 ] ! . name } );` , fn ) ;
258
- c . addFunctionCode (
259
- `_setSignerWeights(${ signerArgs [ opts . signer ] [ 0 ] ! . name } , ${ signerArgs [ opts . signer ] [ 1 ] ! . name } );` ,
260
- fn ,
261
- ) ;
262
- c . addFunctionCode ( `_setThreshold(${ signerArgs [ opts . signer ] [ 2 ] ! . name } );` , fn ) ;
263
- break ;
264
- case 'ECDSA' :
265
- case 'P256' :
266
- case 'RSA' :
267
- c . addFunctionCode ( `_setSigner(${ signerArgs [ opts . signer ] . map ( ( { name } ) => name ) . join ( ', ' ) } );` , fn ) ;
268
- break ;
269
- }
270
197
}
271
198
272
199
function addMultisigFunctions ( c : ContractBuilder , opts : AccountOptions ) : void {
@@ -296,6 +223,7 @@ function addEIP712(c: ContractBuilder, opts: AccountOptions): void {
296
223
{
297
224
name : 'EIP712' ,
298
225
path : '@openzeppelin/contracts/utils/cryptography/EIP712.sol' ,
226
+ transpiled : false , // do not use the upgradeable variant for in Accounts
299
227
} ,
300
228
[ opts . name , '1' ] ,
301
229
) ;
@@ -309,21 +237,22 @@ function overrideRawSignatureValidation(c: ContractBuilder, opts: AccountOptions
309
237
// to provide a custom validation logic
310
238
if ( ! opts . signer && ! opts . ERC7579Modules ) {
311
239
// Custom validation logic
312
- c . addOverride ( { name : 'Account' } , signerFunctions . _rawSignatureValidation ) ;
240
+ c . addOverride ( { name : 'Account' , transpiled : false } , signerFunctions . _rawSignatureValidation ) ;
313
241
c . setFunctionBody ( [ '// Custom validation logic' , 'return false;' ] , signerFunctions . _rawSignatureValidation ) ;
314
242
}
315
243
316
244
// Disambiguate between Signer and AccountERC7579
317
245
if ( opts . signer && opts . ERC7579Modules ) {
318
- const accountName = makeUpgradeable ( 'AccountERC7579' , opts . upgradeable ) ;
319
- const signerName = makeUpgradeable ( `Signer${ opts . signer } ` , opts . upgradeable ) ;
246
+ const accountName = opts . upgradeable ? upgradeableName ( 'AccountERC7579' ) : 'AccountERC7579' ;
247
+ const signerName = opts . upgradeable ? upgradeableName ( `Signer${ opts . signer } ` ) : `Signer ${ opts . signer } ` ;
320
248
321
249
c . addImportOnly ( {
322
250
name : 'AbstractSigner' ,
323
251
path : '@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol' ,
252
+ transpiled : false ,
324
253
} ) ;
325
- c . addOverride ( { name : 'AbstractSigner' } , signerFunctions . _rawSignatureValidation ) ;
326
- c . addOverride ( { name : accountName } , signerFunctions . _rawSignatureValidation ) ;
254
+ c . addOverride ( { name : 'AbstractSigner' , transpiled : false } , signerFunctions . _rawSignatureValidation ) ;
255
+ c . addOverride ( { name : 'AccountERC7579' } , signerFunctions . _rawSignatureValidation ) ;
327
256
c . setFunctionComments (
328
257
[
329
258
`// IMPORTANT: Make sure ${ signerName } is most derived than ${ accountName } ` ,
@@ -336,10 +265,7 @@ function overrideRawSignatureValidation(c: ContractBuilder, opts: AccountOptions
336
265
337
266
// Base override for `_rawSignatureValidation` given MultiSignerERC7913Weighted is MultiSignerERC7913
338
267
if ( opts . signer === 'MultisigWeighted' ) {
339
- c . addImportOnly ( {
340
- name : makeUpgradeable ( signers . Multisig . name , opts . upgradeable ) ,
341
- path : makeUpgradeable ( signers . Multisig . path , opts . upgradeable ) ,
342
- } ) ;
268
+ c . addImportOnly ( signers . Multisig ) ;
343
269
}
344
270
}
345
271
}
0 commit comments