@ensuro/account-abstraction 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # Sample Hardhat Project
2
+
3
+ This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.
4
+
5
+ Try running some of the following tasks:
6
+
7
+ ```shell
8
+ npx hardhat help
9
+ npx hardhat test
10
+ REPORT_GAS=true npx hardhat test
11
+ npx hardhat node
12
+ npx hardhat ignition deploy ./ignition/modules/Lock.js
13
+ ```
@@ -0,0 +1,516 @@
1
+ {
2
+ "_format": "hh-sol-artifact-1",
3
+ "contractName": "AccessControlAccount",
4
+ "sourceName": "contracts/AccessControlAccount.sol",
5
+ "abi": [
6
+ {
7
+ "inputs": [
8
+ {
9
+ "internalType": "contract IEntryPoint",
10
+ "name": "anEntryPoint",
11
+ "type": "address"
12
+ },
13
+ {
14
+ "internalType": "address",
15
+ "name": "admin",
16
+ "type": "address"
17
+ },
18
+ {
19
+ "internalType": "address[]",
20
+ "name": "executors",
21
+ "type": "address[]"
22
+ }
23
+ ],
24
+ "stateMutability": "nonpayable",
25
+ "type": "constructor"
26
+ },
27
+ {
28
+ "inputs": [],
29
+ "name": "AccessControlBadConfirmation",
30
+ "type": "error"
31
+ },
32
+ {
33
+ "inputs": [
34
+ {
35
+ "internalType": "address",
36
+ "name": "account",
37
+ "type": "address"
38
+ },
39
+ {
40
+ "internalType": "bytes32",
41
+ "name": "neededRole",
42
+ "type": "bytes32"
43
+ }
44
+ ],
45
+ "name": "AccessControlUnauthorizedAccount",
46
+ "type": "error"
47
+ },
48
+ {
49
+ "inputs": [],
50
+ "name": "ECDSAInvalidSignature",
51
+ "type": "error"
52
+ },
53
+ {
54
+ "inputs": [
55
+ {
56
+ "internalType": "uint256",
57
+ "name": "length",
58
+ "type": "uint256"
59
+ }
60
+ ],
61
+ "name": "ECDSAInvalidSignatureLength",
62
+ "type": "error"
63
+ },
64
+ {
65
+ "inputs": [
66
+ {
67
+ "internalType": "bytes32",
68
+ "name": "s",
69
+ "type": "bytes32"
70
+ }
71
+ ],
72
+ "name": "ECDSAInvalidSignatureS",
73
+ "type": "error"
74
+ },
75
+ {
76
+ "inputs": [
77
+ {
78
+ "internalType": "address",
79
+ "name": "sender",
80
+ "type": "address"
81
+ }
82
+ ],
83
+ "name": "RequiredEntryPointOrExecutor",
84
+ "type": "error"
85
+ },
86
+ {
87
+ "inputs": [],
88
+ "name": "WrongArrayLength",
89
+ "type": "error"
90
+ },
91
+ {
92
+ "anonymous": false,
93
+ "inputs": [
94
+ {
95
+ "indexed": true,
96
+ "internalType": "bytes32",
97
+ "name": "role",
98
+ "type": "bytes32"
99
+ },
100
+ {
101
+ "indexed": true,
102
+ "internalType": "bytes32",
103
+ "name": "previousAdminRole",
104
+ "type": "bytes32"
105
+ },
106
+ {
107
+ "indexed": true,
108
+ "internalType": "bytes32",
109
+ "name": "newAdminRole",
110
+ "type": "bytes32"
111
+ }
112
+ ],
113
+ "name": "RoleAdminChanged",
114
+ "type": "event"
115
+ },
116
+ {
117
+ "anonymous": false,
118
+ "inputs": [
119
+ {
120
+ "indexed": true,
121
+ "internalType": "bytes32",
122
+ "name": "role",
123
+ "type": "bytes32"
124
+ },
125
+ {
126
+ "indexed": true,
127
+ "internalType": "address",
128
+ "name": "account",
129
+ "type": "address"
130
+ },
131
+ {
132
+ "indexed": true,
133
+ "internalType": "address",
134
+ "name": "sender",
135
+ "type": "address"
136
+ }
137
+ ],
138
+ "name": "RoleGranted",
139
+ "type": "event"
140
+ },
141
+ {
142
+ "anonymous": false,
143
+ "inputs": [
144
+ {
145
+ "indexed": true,
146
+ "internalType": "bytes32",
147
+ "name": "role",
148
+ "type": "bytes32"
149
+ },
150
+ {
151
+ "indexed": true,
152
+ "internalType": "address",
153
+ "name": "account",
154
+ "type": "address"
155
+ },
156
+ {
157
+ "indexed": true,
158
+ "internalType": "address",
159
+ "name": "sender",
160
+ "type": "address"
161
+ }
162
+ ],
163
+ "name": "RoleRevoked",
164
+ "type": "event"
165
+ },
166
+ {
167
+ "inputs": [],
168
+ "name": "DEFAULT_ADMIN_ROLE",
169
+ "outputs": [
170
+ {
171
+ "internalType": "bytes32",
172
+ "name": "",
173
+ "type": "bytes32"
174
+ }
175
+ ],
176
+ "stateMutability": "view",
177
+ "type": "function"
178
+ },
179
+ {
180
+ "inputs": [],
181
+ "name": "EXECUTOR_ROLE",
182
+ "outputs": [
183
+ {
184
+ "internalType": "bytes32",
185
+ "name": "",
186
+ "type": "bytes32"
187
+ }
188
+ ],
189
+ "stateMutability": "view",
190
+ "type": "function"
191
+ },
192
+ {
193
+ "inputs": [],
194
+ "name": "WITHDRAW_ROLE",
195
+ "outputs": [
196
+ {
197
+ "internalType": "bytes32",
198
+ "name": "",
199
+ "type": "bytes32"
200
+ }
201
+ ],
202
+ "stateMutability": "view",
203
+ "type": "function"
204
+ },
205
+ {
206
+ "inputs": [],
207
+ "name": "addDeposit",
208
+ "outputs": [],
209
+ "stateMutability": "payable",
210
+ "type": "function"
211
+ },
212
+ {
213
+ "inputs": [],
214
+ "name": "entryPoint",
215
+ "outputs": [
216
+ {
217
+ "internalType": "contract IEntryPoint",
218
+ "name": "",
219
+ "type": "address"
220
+ }
221
+ ],
222
+ "stateMutability": "view",
223
+ "type": "function"
224
+ },
225
+ {
226
+ "inputs": [
227
+ {
228
+ "internalType": "address",
229
+ "name": "dest",
230
+ "type": "address"
231
+ },
232
+ {
233
+ "internalType": "uint256",
234
+ "name": "value",
235
+ "type": "uint256"
236
+ },
237
+ {
238
+ "internalType": "bytes",
239
+ "name": "func",
240
+ "type": "bytes"
241
+ }
242
+ ],
243
+ "name": "execute",
244
+ "outputs": [],
245
+ "stateMutability": "nonpayable",
246
+ "type": "function"
247
+ },
248
+ {
249
+ "inputs": [
250
+ {
251
+ "internalType": "address[]",
252
+ "name": "dest",
253
+ "type": "address[]"
254
+ },
255
+ {
256
+ "internalType": "uint256[]",
257
+ "name": "value",
258
+ "type": "uint256[]"
259
+ },
260
+ {
261
+ "internalType": "bytes[]",
262
+ "name": "func",
263
+ "type": "bytes[]"
264
+ }
265
+ ],
266
+ "name": "executeBatch",
267
+ "outputs": [],
268
+ "stateMutability": "nonpayable",
269
+ "type": "function"
270
+ },
271
+ {
272
+ "inputs": [],
273
+ "name": "getDeposit",
274
+ "outputs": [
275
+ {
276
+ "internalType": "uint256",
277
+ "name": "",
278
+ "type": "uint256"
279
+ }
280
+ ],
281
+ "stateMutability": "view",
282
+ "type": "function"
283
+ },
284
+ {
285
+ "inputs": [],
286
+ "name": "getNonce",
287
+ "outputs": [
288
+ {
289
+ "internalType": "uint256",
290
+ "name": "",
291
+ "type": "uint256"
292
+ }
293
+ ],
294
+ "stateMutability": "view",
295
+ "type": "function"
296
+ },
297
+ {
298
+ "inputs": [
299
+ {
300
+ "internalType": "bytes32",
301
+ "name": "role",
302
+ "type": "bytes32"
303
+ }
304
+ ],
305
+ "name": "getRoleAdmin",
306
+ "outputs": [
307
+ {
308
+ "internalType": "bytes32",
309
+ "name": "",
310
+ "type": "bytes32"
311
+ }
312
+ ],
313
+ "stateMutability": "view",
314
+ "type": "function"
315
+ },
316
+ {
317
+ "inputs": [
318
+ {
319
+ "internalType": "bytes32",
320
+ "name": "role",
321
+ "type": "bytes32"
322
+ },
323
+ {
324
+ "internalType": "address",
325
+ "name": "account",
326
+ "type": "address"
327
+ }
328
+ ],
329
+ "name": "grantRole",
330
+ "outputs": [],
331
+ "stateMutability": "nonpayable",
332
+ "type": "function"
333
+ },
334
+ {
335
+ "inputs": [
336
+ {
337
+ "internalType": "bytes32",
338
+ "name": "role",
339
+ "type": "bytes32"
340
+ },
341
+ {
342
+ "internalType": "address",
343
+ "name": "account",
344
+ "type": "address"
345
+ }
346
+ ],
347
+ "name": "hasRole",
348
+ "outputs": [
349
+ {
350
+ "internalType": "bool",
351
+ "name": "",
352
+ "type": "bool"
353
+ }
354
+ ],
355
+ "stateMutability": "view",
356
+ "type": "function"
357
+ },
358
+ {
359
+ "inputs": [
360
+ {
361
+ "internalType": "bytes32",
362
+ "name": "role",
363
+ "type": "bytes32"
364
+ },
365
+ {
366
+ "internalType": "address",
367
+ "name": "callerConfirmation",
368
+ "type": "address"
369
+ }
370
+ ],
371
+ "name": "renounceRole",
372
+ "outputs": [],
373
+ "stateMutability": "nonpayable",
374
+ "type": "function"
375
+ },
376
+ {
377
+ "inputs": [
378
+ {
379
+ "internalType": "bytes32",
380
+ "name": "role",
381
+ "type": "bytes32"
382
+ },
383
+ {
384
+ "internalType": "address",
385
+ "name": "account",
386
+ "type": "address"
387
+ }
388
+ ],
389
+ "name": "revokeRole",
390
+ "outputs": [],
391
+ "stateMutability": "nonpayable",
392
+ "type": "function"
393
+ },
394
+ {
395
+ "inputs": [
396
+ {
397
+ "internalType": "bytes4",
398
+ "name": "interfaceId",
399
+ "type": "bytes4"
400
+ }
401
+ ],
402
+ "name": "supportsInterface",
403
+ "outputs": [
404
+ {
405
+ "internalType": "bool",
406
+ "name": "",
407
+ "type": "bool"
408
+ }
409
+ ],
410
+ "stateMutability": "view",
411
+ "type": "function"
412
+ },
413
+ {
414
+ "inputs": [
415
+ {
416
+ "components": [
417
+ {
418
+ "internalType": "address",
419
+ "name": "sender",
420
+ "type": "address"
421
+ },
422
+ {
423
+ "internalType": "uint256",
424
+ "name": "nonce",
425
+ "type": "uint256"
426
+ },
427
+ {
428
+ "internalType": "bytes",
429
+ "name": "initCode",
430
+ "type": "bytes"
431
+ },
432
+ {
433
+ "internalType": "bytes",
434
+ "name": "callData",
435
+ "type": "bytes"
436
+ },
437
+ {
438
+ "internalType": "bytes32",
439
+ "name": "accountGasLimits",
440
+ "type": "bytes32"
441
+ },
442
+ {
443
+ "internalType": "uint256",
444
+ "name": "preVerificationGas",
445
+ "type": "uint256"
446
+ },
447
+ {
448
+ "internalType": "bytes32",
449
+ "name": "gasFees",
450
+ "type": "bytes32"
451
+ },
452
+ {
453
+ "internalType": "bytes",
454
+ "name": "paymasterAndData",
455
+ "type": "bytes"
456
+ },
457
+ {
458
+ "internalType": "bytes",
459
+ "name": "signature",
460
+ "type": "bytes"
461
+ }
462
+ ],
463
+ "internalType": "struct PackedUserOperation",
464
+ "name": "userOp",
465
+ "type": "tuple"
466
+ },
467
+ {
468
+ "internalType": "bytes32",
469
+ "name": "userOpHash",
470
+ "type": "bytes32"
471
+ },
472
+ {
473
+ "internalType": "uint256",
474
+ "name": "missingAccountFunds",
475
+ "type": "uint256"
476
+ }
477
+ ],
478
+ "name": "validateUserOp",
479
+ "outputs": [
480
+ {
481
+ "internalType": "uint256",
482
+ "name": "validationData",
483
+ "type": "uint256"
484
+ }
485
+ ],
486
+ "stateMutability": "nonpayable",
487
+ "type": "function"
488
+ },
489
+ {
490
+ "inputs": [
491
+ {
492
+ "internalType": "address payable",
493
+ "name": "withdrawAddress",
494
+ "type": "address"
495
+ },
496
+ {
497
+ "internalType": "uint256",
498
+ "name": "amount",
499
+ "type": "uint256"
500
+ }
501
+ ],
502
+ "name": "withdrawDepositTo",
503
+ "outputs": [],
504
+ "stateMutability": "nonpayable",
505
+ "type": "function"
506
+ },
507
+ {
508
+ "stateMutability": "payable",
509
+ "type": "receive"
510
+ }
511
+ ],
512
+ "bytecode": "0x60a06040523480156200001157600080fd5b50604051620023c4380380620023c483398181016040528101906200003791906200049e565b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050620000806000801b83620000f660201b60201c565b5060005b8151811015620000ec57620000dd7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63838381518110620000c957620000c862000519565b5b6020026020010151620000f660201b60201c565b50808060010191505062000084565b5050505062000548565b60006200010a8383620001f960201b60201c565b620001ee57600160008085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200018a6200026360201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050620001f3565b600090505b92915050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002ac826200027f565b9050919050565b6000620002c0826200029f565b9050919050565b620002d281620002b3565b8114620002de57600080fd5b50565b600081519050620002f281620002c7565b92915050565b62000303816200029f565b81146200030f57600080fd5b50565b6000815190506200032381620002f8565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b62000379826200032e565b810181811067ffffffffffffffff821117156200039b576200039a6200033f565b5b80604052505050565b6000620003b06200026b565b9050620003be82826200036e565b919050565b600067ffffffffffffffff821115620003e157620003e06200033f565b5b602082029050602081019050919050565b600080fd5b60006200040e6200040884620003c3565b620003a4565b90508083825260208201905060208402830185811115620004345762000433620003f2565b5b835b818110156200046157806200044c888262000312565b84526020840193505060208101905062000436565b5050509392505050565b600082601f83011262000483576200048262000329565b5b815162000495848260208601620003f7565b91505092915050565b600080600060608486031215620004ba57620004b962000275565b5b6000620004ca86828701620002e1565b9350506020620004dd8682870162000312565b925050604084015167ffffffffffffffff8111156200050157620005006200027a565b5b6200050f868287016200046b565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b608051611e606200056460003960006109250152611e606000f3fe6080604052600436106101025760003560e01c80634d44560d11610095578063b61d27f611610064578063b61d27f614610331578063c399ec881461035a578063d087d28814610385578063d547741f146103b0578063e02023a1146103d957610109565b80634d44560d1461027557806391d148541461029e578063a217fddf146102db578063b0d691fe1461030657610109565b80632f2ff15d116100d15780632f2ff15d146101f057806336568abe1461021957806347e1da2a146102425780634a58db191461026b57610109565b806301ffc9a71461010e57806307bd02651461014b57806319822f7c14610176578063248a9ca3146101b357610109565b3661010957005b600080fd5b34801561011a57600080fd5b506101356004803603810190610130919061142e565b610404565b6040516101429190611476565b60405180910390f35b34801561015757600080fd5b5061016061047e565b60405161016d91906114aa565b60405180910390f35b34801561018257600080fd5b5061019d6004803603810190610198919061154c565b6104a2565b6040516101aa91906115ca565b60405180910390f35b3480156101bf57600080fd5b506101da60048036038101906101d591906115e5565b6104d5565b6040516101e791906114aa565b60405180910390f35b3480156101fc57600080fd5b5061021760048036038101906102129190611670565b6104f4565b005b34801561022557600080fd5b50610240600480360381019061023b9190611670565b610516565b005b34801561024e57600080fd5b50610269600480360381019061026491906117c1565b610591565b005b610273610798565b005b34801561028157600080fd5b5061029c600480360381019061029791906118b3565b61080d565b005b3480156102aa57600080fd5b506102c560048036038101906102c09190611670565b6108b0565b6040516102d29190611476565b60405180910390f35b3480156102e757600080fd5b506102f061091a565b6040516102fd91906114aa565b60405180910390f35b34801561031257600080fd5b5061031b610921565b6040516103289190611952565b60405180910390f35b34801561033d57600080fd5b50610358600480360381019061035391906119c3565b610949565b005b34801561036657600080fd5b5061036f6109a6565b60405161037c91906115ca565b60405180910390f35b34801561039157600080fd5b5061039a610a2e565b6040516103a791906115ca565b60405180910390f35b3480156103bc57600080fd5b506103d760048036038101906103d29190611670565b610ab9565b005b3480156103e557600080fd5b506103ee610adb565b6040516103fb91906114aa565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610477575061047682610aff565b5b9050919050565b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b60006104ac610b69565b6104b68484610be0565b90506104c58460200135610c95565b6104ce82610c98565b9392505050565b6000806000838152602001908152602001600020600101549050919050565b6104fd826104d5565b61050681610d34565b6105108383610d48565b50505050565b61051e610e39565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610582576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61058c8282610e41565b505050565b610599610f33565b81819050868690501415806105c45750600084849050141580156105c35750818190508484905014155b5b156105fb576040517f2a00e5c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084849050036106c15760005b868690508110156106bb576106ae87878381811061062a57610629611a37565b5b905060200201602081019061063f9190611a66565b600085858581811061065457610653611a37565b5b90506020028101906106669190611aa2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fe1565b8080600101915050610609565b50610790565b60005b8686905081101561078e576107818787838181106106e5576106e4611a37565b5b90506020020160208101906106fa9190611a66565b86868481811061070d5761070c611a37565b5b9050602002013585858581811061072757610726611a37565b5b90506020028101906107399190611aa2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fe1565b80806001019150506106c4565b505b505050505050565b6107a0610921565b73ffffffffffffffffffffffffffffffffffffffff1663b760faf934306040518363ffffffff1660e01b81526004016107d99190611b14565b6000604051808303818588803b1580156107f257600080fd5b505af1158015610806573d6000803e3d6000fd5b5050505050565b7f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec61083781610d34565b61083f610921565b73ffffffffffffffffffffffffffffffffffffffff1663205c287884846040518363ffffffff1660e01b8152600401610879929190611b3e565b600060405180830381600087803b15801561089357600080fd5b505af11580156108a7573d6000803e3d6000fd5b50505050505050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000801b81565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b610951610f33565b6109a0848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fe1565b50505050565b60006109b0610921565b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109e89190611b14565b602060405180830381865afa158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a299190611b7c565b905090565b6000610a38610921565b73ffffffffffffffffffffffffffffffffffffffff166335567e1a3060006040518363ffffffff1660e01b8152600401610a73929190611c08565b602060405180830381865afa158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab49190611b7c565b905090565b610ac2826104d5565b610acb81610d34565b610ad58383610e41565b50505050565b7f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec81565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610b71610921565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd590611c8e565b60405180910390fd5b565b600080610bec83611065565b90506000610c4d8286806101000190610c059190611aa2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061109b565b9050610c797fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63826108b0565b610c8857600192505050610c8f565b6000925050505b92915050565b50565b60008114610d315760003373ffffffffffffffffffffffffffffffffffffffff16827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90604051610ce890611cdf565b600060405180830381858888f193505050503d8060008114610d26576040519150601f19603f3d011682016040523d82523d6000602084013e610d2b565b606091505b50509050505b50565b610d4581610d40610e39565b6110c7565b50565b6000610d5483836108b0565b610e2e57600160008085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610dcb610e39565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050610e33565b600090505b92915050565b600033905090565b6000610e4d83836108b0565b15610f2857600080600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610ec5610e39565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050610f2d565b600090505b92915050565b610f3b610921565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610f9d5750610f9b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63336108b0565b155b15610fdf57336040517ff1a1fdac000000000000000000000000000000000000000000000000000000008152600401610fd69190611b14565b60405180910390fd5b565b6000808473ffffffffffffffffffffffffffffffffffffffff16848460405161100a9190611d5a565b60006040518083038185875af1925050503d8060008114611047576040519150601f19603f3d011682016040523d82523d6000602084013e61104c565b606091505b50915091508161105e57805160208201fd5b5050505050565b60007f19457468657265756d205369676e6564204d6573736167653a0a33320000000060005281601c52603c6000209050919050565b6000806000806110ab8686611118565b9250925092506110bb8282611174565b82935050505092915050565b6110d182826108b0565b6111145780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161110b929190611d71565b60405180910390fd5b5050565b6000806000604184510361115d5760008060006020870151925060408701519150606087015160001a905061114f888285856112d8565b95509550955050505061116d565b60006002855160001b9250925092505b9250925092565b6000600381111561118857611187611d9a565b5b82600381111561119b5761119a611d9a565b5b03156112d457600160038111156111b5576111b4611d9a565b5b8260038111156111c8576111c7611d9a565b5b036111ff576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600381111561121357611212611d9a565b5b82600381111561122657611225611d9a565b5b0361126b578060001c6040517ffce698f700000000000000000000000000000000000000000000000000000000815260040161126291906115ca565b60405180910390fd5b60038081111561127e5761127d611d9a565b5b82600381111561129157611290611d9a565b5b036112d357806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016112ca91906114aa565b60405180910390fd5b5b5050565b60008060007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08460001c11156113185760006003859250925092506113c2565b60006001888888886040516000815260200160405260405161133d9493929190611de5565b6020604051602081039080840390855afa15801561135f573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113b357600060016000801b935093509350506113c2565b8060008060001b935093509350505b9450945094915050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61140b816113d6565b811461141657600080fd5b50565b60008135905061142881611402565b92915050565b600060208284031215611444576114436113cc565b5b600061145284828501611419565b91505092915050565b60008115159050919050565b6114708161145b565b82525050565b600060208201905061148b6000830184611467565b92915050565b6000819050919050565b6114a481611491565b82525050565b60006020820190506114bf600083018461149b565b92915050565b600080fd5b600061012082840312156114e1576114e06114c5565b5b81905092915050565b6114f381611491565b81146114fe57600080fd5b50565b600081359050611510816114ea565b92915050565b6000819050919050565b61152981611516565b811461153457600080fd5b50565b60008135905061154681611520565b92915050565b600080600060608486031215611565576115646113cc565b5b600084013567ffffffffffffffff811115611583576115826113d1565b5b61158f868287016114ca565b93505060206115a086828701611501565b92505060406115b186828701611537565b9150509250925092565b6115c481611516565b82525050565b60006020820190506115df60008301846115bb565b92915050565b6000602082840312156115fb576115fa6113cc565b5b600061160984828501611501565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061163d82611612565b9050919050565b61164d81611632565b811461165857600080fd5b50565b60008135905061166a81611644565b92915050565b60008060408385031215611687576116866113cc565b5b600061169585828601611501565b92505060206116a68582860161165b565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f8401126116d5576116d46116b0565b5b8235905067ffffffffffffffff8111156116f2576116f16116b5565b5b60208301915083602082028301111561170e5761170d6116ba565b5b9250929050565b60008083601f84011261172b5761172a6116b0565b5b8235905067ffffffffffffffff811115611748576117476116b5565b5b602083019150836020820283011115611764576117636116ba565b5b9250929050565b60008083601f840112611781576117806116b0565b5b8235905067ffffffffffffffff81111561179e5761179d6116b5565b5b6020830191508360208202830111156117ba576117b96116ba565b5b9250929050565b600080600080600080606087890312156117de576117dd6113cc565b5b600087013567ffffffffffffffff8111156117fc576117fb6113d1565b5b61180889828a016116bf565b9650965050602087013567ffffffffffffffff81111561182b5761182a6113d1565b5b61183789828a01611715565b9450945050604087013567ffffffffffffffff81111561185a576118596113d1565b5b61186689828a0161176b565b92509250509295509295509295565b600061188082611612565b9050919050565b61189081611875565b811461189b57600080fd5b50565b6000813590506118ad81611887565b92915050565b600080604083850312156118ca576118c96113cc565b5b60006118d88582860161189e565b92505060206118e985828601611537565b9150509250929050565b6000819050919050565b600061191861191361190e84611612565b6118f3565b611612565b9050919050565b600061192a826118fd565b9050919050565b600061193c8261191f565b9050919050565b61194c81611931565b82525050565b60006020820190506119676000830184611943565b92915050565b60008083601f840112611983576119826116b0565b5b8235905067ffffffffffffffff8111156119a05761199f6116b5565b5b6020830191508360018202830111156119bc576119bb6116ba565b5b9250929050565b600080600080606085870312156119dd576119dc6113cc565b5b60006119eb8782880161165b565b94505060206119fc87828801611537565b935050604085013567ffffffffffffffff811115611a1d57611a1c6113d1565b5b611a298782880161196d565b925092505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215611a7c57611a7b6113cc565b5b6000611a8a8482850161165b565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611abf57611abe611a93565b5b80840192508235915067ffffffffffffffff821115611ae157611ae0611a98565b5b602083019250600182023603831315611afd57611afc611a9d565b5b509250929050565b611b0e81611632565b82525050565b6000602082019050611b296000830184611b05565b92915050565b611b3881611875565b82525050565b6000604082019050611b536000830185611b2f565b611b6060208301846115bb565b9392505050565b600081519050611b7681611520565b92915050565b600060208284031215611b9257611b916113cc565b5b6000611ba084828501611b67565b91505092915050565b6000819050919050565b600077ffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bf2611bed611be884611ba9565b6118f3565b611bb3565b9050919050565b611c0281611bd7565b82525050565b6000604082019050611c1d6000830185611b05565b611c2a6020830184611bf9565b9392505050565b600082825260208201905092915050565b7f6163636f756e743a206e6f742066726f6d20456e747279506f696e7400000000600082015250565b6000611c78601c83611c31565b9150611c8382611c42565b602082019050919050565b60006020820190508181036000830152611ca781611c6b565b9050919050565b600081905092915050565b50565b6000611cc9600083611cae565b9150611cd482611cb9565b600082019050919050565b6000611cea82611cbc565b9150819050919050565b600081519050919050565b60005b83811015611d1d578082015181840152602081019050611d02565b60008484015250505050565b6000611d3482611cf4565b611d3e8185611cae565b9350611d4e818560208601611cff565b80840191505092915050565b6000611d668284611d29565b915081905092915050565b6000604082019050611d866000830185611b05565b611d93602083018461149b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060ff82169050919050565b611ddf81611dc9565b82525050565b6000608082019050611dfa600083018761149b565b611e076020830186611dd6565b611e14604083018561149b565b611e21606083018461149b565b9594505050505056fea26469706673582212200d807026ec1f8c046ed52e23b7d33106b05ee848e15ff2de1e9a2200fb783fd264736f6c63430008180033",
513
+ "deployedBytecode": "0x6080604052600436106101025760003560e01c80634d44560d11610095578063b61d27f611610064578063b61d27f614610331578063c399ec881461035a578063d087d28814610385578063d547741f146103b0578063e02023a1146103d957610109565b80634d44560d1461027557806391d148541461029e578063a217fddf146102db578063b0d691fe1461030657610109565b80632f2ff15d116100d15780632f2ff15d146101f057806336568abe1461021957806347e1da2a146102425780634a58db191461026b57610109565b806301ffc9a71461010e57806307bd02651461014b57806319822f7c14610176578063248a9ca3146101b357610109565b3661010957005b600080fd5b34801561011a57600080fd5b506101356004803603810190610130919061142e565b610404565b6040516101429190611476565b60405180910390f35b34801561015757600080fd5b5061016061047e565b60405161016d91906114aa565b60405180910390f35b34801561018257600080fd5b5061019d6004803603810190610198919061154c565b6104a2565b6040516101aa91906115ca565b60405180910390f35b3480156101bf57600080fd5b506101da60048036038101906101d591906115e5565b6104d5565b6040516101e791906114aa565b60405180910390f35b3480156101fc57600080fd5b5061021760048036038101906102129190611670565b6104f4565b005b34801561022557600080fd5b50610240600480360381019061023b9190611670565b610516565b005b34801561024e57600080fd5b50610269600480360381019061026491906117c1565b610591565b005b610273610798565b005b34801561028157600080fd5b5061029c600480360381019061029791906118b3565b61080d565b005b3480156102aa57600080fd5b506102c560048036038101906102c09190611670565b6108b0565b6040516102d29190611476565b60405180910390f35b3480156102e757600080fd5b506102f061091a565b6040516102fd91906114aa565b60405180910390f35b34801561031257600080fd5b5061031b610921565b6040516103289190611952565b60405180910390f35b34801561033d57600080fd5b50610358600480360381019061035391906119c3565b610949565b005b34801561036657600080fd5b5061036f6109a6565b60405161037c91906115ca565b60405180910390f35b34801561039157600080fd5b5061039a610a2e565b6040516103a791906115ca565b60405180910390f35b3480156103bc57600080fd5b506103d760048036038101906103d29190611670565b610ab9565b005b3480156103e557600080fd5b506103ee610adb565b6040516103fb91906114aa565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610477575061047682610aff565b5b9050919050565b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b60006104ac610b69565b6104b68484610be0565b90506104c58460200135610c95565b6104ce82610c98565b9392505050565b6000806000838152602001908152602001600020600101549050919050565b6104fd826104d5565b61050681610d34565b6105108383610d48565b50505050565b61051e610e39565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610582576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61058c8282610e41565b505050565b610599610f33565b81819050868690501415806105c45750600084849050141580156105c35750818190508484905014155b5b156105fb576040517f2a00e5c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084849050036106c15760005b868690508110156106bb576106ae87878381811061062a57610629611a37565b5b905060200201602081019061063f9190611a66565b600085858581811061065457610653611a37565b5b90506020028101906106669190611aa2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fe1565b8080600101915050610609565b50610790565b60005b8686905081101561078e576107818787838181106106e5576106e4611a37565b5b90506020020160208101906106fa9190611a66565b86868481811061070d5761070c611a37565b5b9050602002013585858581811061072757610726611a37565b5b90506020028101906107399190611aa2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fe1565b80806001019150506106c4565b505b505050505050565b6107a0610921565b73ffffffffffffffffffffffffffffffffffffffff1663b760faf934306040518363ffffffff1660e01b81526004016107d99190611b14565b6000604051808303818588803b1580156107f257600080fd5b505af1158015610806573d6000803e3d6000fd5b5050505050565b7f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec61083781610d34565b61083f610921565b73ffffffffffffffffffffffffffffffffffffffff1663205c287884846040518363ffffffff1660e01b8152600401610879929190611b3e565b600060405180830381600087803b15801561089357600080fd5b505af11580156108a7573d6000803e3d6000fd5b50505050505050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000801b81565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b610951610f33565b6109a0848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fe1565b50505050565b60006109b0610921565b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109e89190611b14565b602060405180830381865afa158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a299190611b7c565b905090565b6000610a38610921565b73ffffffffffffffffffffffffffffffffffffffff166335567e1a3060006040518363ffffffff1660e01b8152600401610a73929190611c08565b602060405180830381865afa158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab49190611b7c565b905090565b610ac2826104d5565b610acb81610d34565b610ad58383610e41565b50505050565b7f5d8e12c39142ff96d79d04d15d1ba1269e4fe57bb9d26f43523628b34ba108ec81565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610b71610921565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd590611c8e565b60405180910390fd5b565b600080610bec83611065565b90506000610c4d8286806101000190610c059190611aa2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061109b565b9050610c797fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63826108b0565b610c8857600192505050610c8f565b6000925050505b92915050565b50565b60008114610d315760003373ffffffffffffffffffffffffffffffffffffffff16827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90604051610ce890611cdf565b600060405180830381858888f193505050503d8060008114610d26576040519150601f19603f3d011682016040523d82523d6000602084013e610d2b565b606091505b50509050505b50565b610d4581610d40610e39565b6110c7565b50565b6000610d5483836108b0565b610e2e57600160008085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610dcb610e39565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050610e33565b600090505b92915050565b600033905090565b6000610e4d83836108b0565b15610f2857600080600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610ec5610e39565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050610f2d565b600090505b92915050565b610f3b610921565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610f9d5750610f9b7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e63336108b0565b155b15610fdf57336040517ff1a1fdac000000000000000000000000000000000000000000000000000000008152600401610fd69190611b14565b60405180910390fd5b565b6000808473ffffffffffffffffffffffffffffffffffffffff16848460405161100a9190611d5a565b60006040518083038185875af1925050503d8060008114611047576040519150601f19603f3d011682016040523d82523d6000602084013e61104c565b606091505b50915091508161105e57805160208201fd5b5050505050565b60007f19457468657265756d205369676e6564204d6573736167653a0a33320000000060005281601c52603c6000209050919050565b6000806000806110ab8686611118565b9250925092506110bb8282611174565b82935050505092915050565b6110d182826108b0565b6111145780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161110b929190611d71565b60405180910390fd5b5050565b6000806000604184510361115d5760008060006020870151925060408701519150606087015160001a905061114f888285856112d8565b95509550955050505061116d565b60006002855160001b9250925092505b9250925092565b6000600381111561118857611187611d9a565b5b82600381111561119b5761119a611d9a565b5b03156112d457600160038111156111b5576111b4611d9a565b5b8260038111156111c8576111c7611d9a565b5b036111ff576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600381111561121357611212611d9a565b5b82600381111561122657611225611d9a565b5b0361126b578060001c6040517ffce698f700000000000000000000000000000000000000000000000000000000815260040161126291906115ca565b60405180910390fd5b60038081111561127e5761127d611d9a565b5b82600381111561129157611290611d9a565b5b036112d357806040517fd78bce0c0000000000000000000000000000000000000000000000000000000081526004016112ca91906114aa565b60405180910390fd5b5b5050565b60008060007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08460001c11156113185760006003859250925092506113c2565b60006001888888886040516000815260200160405260405161133d9493929190611de5565b6020604051602081039080840390855afa15801561135f573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113b357600060016000801b935093509350506113c2565b8060008060001b935093509350505b9450945094915050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61140b816113d6565b811461141657600080fd5b50565b60008135905061142881611402565b92915050565b600060208284031215611444576114436113cc565b5b600061145284828501611419565b91505092915050565b60008115159050919050565b6114708161145b565b82525050565b600060208201905061148b6000830184611467565b92915050565b6000819050919050565b6114a481611491565b82525050565b60006020820190506114bf600083018461149b565b92915050565b600080fd5b600061012082840312156114e1576114e06114c5565b5b81905092915050565b6114f381611491565b81146114fe57600080fd5b50565b600081359050611510816114ea565b92915050565b6000819050919050565b61152981611516565b811461153457600080fd5b50565b60008135905061154681611520565b92915050565b600080600060608486031215611565576115646113cc565b5b600084013567ffffffffffffffff811115611583576115826113d1565b5b61158f868287016114ca565b93505060206115a086828701611501565b92505060406115b186828701611537565b9150509250925092565b6115c481611516565b82525050565b60006020820190506115df60008301846115bb565b92915050565b6000602082840312156115fb576115fa6113cc565b5b600061160984828501611501565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061163d82611612565b9050919050565b61164d81611632565b811461165857600080fd5b50565b60008135905061166a81611644565b92915050565b60008060408385031215611687576116866113cc565b5b600061169585828601611501565b92505060206116a68582860161165b565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f8401126116d5576116d46116b0565b5b8235905067ffffffffffffffff8111156116f2576116f16116b5565b5b60208301915083602082028301111561170e5761170d6116ba565b5b9250929050565b60008083601f84011261172b5761172a6116b0565b5b8235905067ffffffffffffffff811115611748576117476116b5565b5b602083019150836020820283011115611764576117636116ba565b5b9250929050565b60008083601f840112611781576117806116b0565b5b8235905067ffffffffffffffff81111561179e5761179d6116b5565b5b6020830191508360208202830111156117ba576117b96116ba565b5b9250929050565b600080600080600080606087890312156117de576117dd6113cc565b5b600087013567ffffffffffffffff8111156117fc576117fb6113d1565b5b61180889828a016116bf565b9650965050602087013567ffffffffffffffff81111561182b5761182a6113d1565b5b61183789828a01611715565b9450945050604087013567ffffffffffffffff81111561185a576118596113d1565b5b61186689828a0161176b565b92509250509295509295509295565b600061188082611612565b9050919050565b61189081611875565b811461189b57600080fd5b50565b6000813590506118ad81611887565b92915050565b600080604083850312156118ca576118c96113cc565b5b60006118d88582860161189e565b92505060206118e985828601611537565b9150509250929050565b6000819050919050565b600061191861191361190e84611612565b6118f3565b611612565b9050919050565b600061192a826118fd565b9050919050565b600061193c8261191f565b9050919050565b61194c81611931565b82525050565b60006020820190506119676000830184611943565b92915050565b60008083601f840112611983576119826116b0565b5b8235905067ffffffffffffffff8111156119a05761199f6116b5565b5b6020830191508360018202830111156119bc576119bb6116ba565b5b9250929050565b600080600080606085870312156119dd576119dc6113cc565b5b60006119eb8782880161165b565b94505060206119fc87828801611537565b935050604085013567ffffffffffffffff811115611a1d57611a1c6113d1565b5b611a298782880161196d565b925092505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215611a7c57611a7b6113cc565b5b6000611a8a8482850161165b565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112611abf57611abe611a93565b5b80840192508235915067ffffffffffffffff821115611ae157611ae0611a98565b5b602083019250600182023603831315611afd57611afc611a9d565b5b509250929050565b611b0e81611632565b82525050565b6000602082019050611b296000830184611b05565b92915050565b611b3881611875565b82525050565b6000604082019050611b536000830185611b2f565b611b6060208301846115bb565b9392505050565b600081519050611b7681611520565b92915050565b600060208284031215611b9257611b916113cc565b5b6000611ba084828501611b67565b91505092915050565b6000819050919050565b600077ffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611bf2611bed611be884611ba9565b6118f3565b611bb3565b9050919050565b611c0281611bd7565b82525050565b6000604082019050611c1d6000830185611b05565b611c2a6020830184611bf9565b9392505050565b600082825260208201905092915050565b7f6163636f756e743a206e6f742066726f6d20456e747279506f696e7400000000600082015250565b6000611c78601c83611c31565b9150611c8382611c42565b602082019050919050565b60006020820190508181036000830152611ca781611c6b565b9050919050565b600081905092915050565b50565b6000611cc9600083611cae565b9150611cd482611cb9565b600082019050919050565b6000611cea82611cbc565b9150819050919050565b600081519050919050565b60005b83811015611d1d578082015181840152602081019050611d02565b60008484015250505050565b6000611d3482611cf4565b611d3e8185611cae565b9350611d4e818560208601611cff565b80840191505092915050565b6000611d668284611d29565b915081905092915050565b6000604082019050611d866000830185611b05565b611d93602083018461149b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060ff82169050919050565b611ddf81611dc9565b82525050565b6000608082019050611dfa600083018761149b565b611e076020830186611dd6565b611e14604083018561149b565b611e21606083018461149b565b9594505050505056fea26469706673582212200d807026ec1f8c046ed52e23b7d33106b05ee848e15ff2de1e9a2200fb783fd264736f6c63430008180033",
514
+ "linkReferences": {},
515
+ "deployedLinkReferences": {}
516
+ }
@@ -0,0 +1,118 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.23;
3
+
4
+ import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
5
+ import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
6
+ import {BaseAccount} from "@account-abstraction/contracts/core/BaseAccount.sol";
7
+ import {SIG_VALIDATION_SUCCESS, SIG_VALIDATION_FAILED} from "@account-abstraction/contracts/core/Helpers.sol";
8
+ import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol";
9
+ import {PackedUserOperation} from "@account-abstraction/contracts/interfaces/PackedUserOperation.sol";
10
+ import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
11
+
12
+ contract AccessControlAccount is AccessControl, BaseAccount {
13
+ bytes32 public constant WITHDRAW_ROLE = keccak256("WITHDRAW_ROLE");
14
+ bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
15
+
16
+ IEntryPoint private immutable _entryPoint;
17
+
18
+ error RequiredEntryPointOrExecutor(address sender);
19
+ error WrongArrayLength();
20
+
21
+ /// @inheritdoc BaseAccount
22
+ function entryPoint() public view virtual override returns (IEntryPoint) {
23
+ return _entryPoint;
24
+ }
25
+
26
+ // solhint-disable-next-line no-empty-blocks
27
+ receive() external payable {}
28
+
29
+ constructor(IEntryPoint anEntryPoint, address admin, address[] memory executors) {
30
+ _entryPoint = anEntryPoint;
31
+ _grantRole(DEFAULT_ADMIN_ROLE, admin);
32
+ for (uint256 i; i < executors.length; i++) {
33
+ _grantRole(EXECUTOR_ROLE, executors[i]);
34
+ }
35
+ }
36
+
37
+ // Require the function call went through EntryPoint or owner
38
+ function _requireFromEntryPointOrExecutor() internal view {
39
+ if (msg.sender != address(entryPoint()) && !hasRole(EXECUTOR_ROLE, msg.sender))
40
+ revert RequiredEntryPointOrExecutor(msg.sender);
41
+ }
42
+
43
+ /**
44
+ * execute a transaction (called directly from owner, or by entryPoint)
45
+ * @param dest destination address to call
46
+ * @param value the value to pass in this call
47
+ * @param func the calldata to pass in this call
48
+ */
49
+ function execute(address dest, uint256 value, bytes calldata func) external {
50
+ _requireFromEntryPointOrExecutor();
51
+ _call(dest, value, func);
52
+ }
53
+
54
+ /**
55
+ * execute a sequence of transactions
56
+ * @dev to reduce gas consumption for trivial case (no value), use a zero-length array to mean zero value
57
+ * @param dest an array of destination addresses
58
+ * @param value an array of values to pass to each call. can be zero-length for no-value calls
59
+ * @param func an array of calldata to pass to each call
60
+ */
61
+ function executeBatch(address[] calldata dest, uint256[] calldata value, bytes[] calldata func) external {
62
+ _requireFromEntryPointOrExecutor();
63
+ if (dest.length != func.length || (value.length != 0 && value.length != func.length)) revert WrongArrayLength();
64
+ if (value.length == 0) {
65
+ for (uint256 i = 0; i < dest.length; i++) {
66
+ _call(dest[i], 0, func[i]);
67
+ }
68
+ } else {
69
+ for (uint256 i = 0; i < dest.length; i++) {
70
+ _call(dest[i], value[i], func[i]);
71
+ }
72
+ }
73
+ }
74
+
75
+ /// implement template method of BaseAccount
76
+ function _validateSignature(
77
+ PackedUserOperation calldata userOp,
78
+ bytes32 userOpHash
79
+ ) internal virtual override returns (uint256 validationData) {
80
+ bytes32 hash = MessageHashUtils.toEthSignedMessageHash(userOpHash);
81
+ address recovered = ECDSA.recover(hash, userOp.signature);
82
+ if (!hasRole(EXECUTOR_ROLE, recovered)) return SIG_VALIDATION_FAILED;
83
+ return SIG_VALIDATION_SUCCESS;
84
+ }
85
+
86
+ function _call(address target, uint256 value, bytes memory data) internal {
87
+ (bool success, bytes memory result) = target.call{value: value}(data);
88
+ if (!success) {
89
+ // solhint-disable-next-line no-inline-assembly
90
+ assembly {
91
+ revert(add(result, 32), mload(result))
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * check current account deposit in the entryPoint
98
+ */
99
+ function getDeposit() public view returns (uint256) {
100
+ return entryPoint().balanceOf(address(this));
101
+ }
102
+
103
+ /**
104
+ * deposit more funds for this account in the entryPoint
105
+ */
106
+ function addDeposit() public payable {
107
+ entryPoint().depositTo{value: msg.value}(address(this));
108
+ }
109
+
110
+ /**
111
+ * withdraw value from the account's deposit
112
+ * @param withdrawAddress target to send to
113
+ * @param amount to withdraw
114
+ */
115
+ function withdrawDepositTo(address payable withdrawAddress, uint256 amount) public onlyRole(WITHDRAW_ROLE) {
116
+ entryPoint().withdrawTo(withdrawAddress, amount);
117
+ }
118
+ }
package/js/userOp.js ADDED
@@ -0,0 +1,160 @@
1
+ const ethers = require("ethers");
2
+ const { ZeroAddress } = ethers;
3
+
4
+ const defaultAbiCoder = ethers.AbiCoder.defaultAbiCoder();
5
+
6
+ function packAccountGasLimits(verificationGasLimit, callGasLimit) {
7
+ return ethers.toBeHex(verificationGasLimit, 16) + ethers.toBeHex(callGasLimit, 16).slice(2);
8
+ }
9
+
10
+ function packUserOp(userOp) {
11
+ const accountGasLimits = packAccountGasLimits(userOp.verificationGasLimit, userOp.callGasLimit);
12
+ const gasFees = packAccountGasLimits(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas);
13
+ let paymasterAndData = "0x";
14
+ if (userOp.paymaster?.length >= 20 && userOp.paymaster !== ZeroAddress) {
15
+ paymasterAndData = packPaymasterData(
16
+ userOp.paymaster,
17
+ userOp.paymasterVerificationGasLimit,
18
+ userOp.paymasterPostOpGasLimit,
19
+ userOp.paymasterData
20
+ );
21
+ }
22
+ return {
23
+ sender: userOp.sender,
24
+ nonce: userOp.nonce,
25
+ callData: userOp.callData,
26
+ accountGasLimits,
27
+ initCode: userOp.initCode,
28
+ preVerificationGas: userOp.preVerificationGas,
29
+ gasFees,
30
+ paymasterAndData,
31
+ signature: userOp.signature,
32
+ };
33
+ }
34
+
35
+ function packedUserOpAsArray(packedUserOp, includeSignature = true) {
36
+ if (includeSignature) {
37
+ return [
38
+ packedUserOp.sender,
39
+ packedUserOp.nonce,
40
+ packedUserOp.initCode,
41
+ packedUserOp.callData,
42
+ packedUserOp.accountGasLimits,
43
+ packedUserOp.preVerificationGas,
44
+ packedUserOp.gasFees,
45
+ packedUserOp.paymasterAndData,
46
+ packedUserOp.signature,
47
+ ];
48
+ } else {
49
+ return [
50
+ packedUserOp.sender,
51
+ packedUserOp.nonce,
52
+ packedUserOp.initCode,
53
+ packedUserOp.callData,
54
+ packedUserOp.accountGasLimits,
55
+ packedUserOp.preVerificationGas,
56
+ packedUserOp.gasFees,
57
+ packedUserOp.paymasterAndData,
58
+ ];
59
+ }
60
+ }
61
+
62
+ function encodeUserOp(userOp, forSignature = true) {
63
+ const packedUserOp = packUserOp(userOp);
64
+ if (forSignature) {
65
+ return defaultAbiCoder.encode(
66
+ ["address", "uint256", "bytes32", "bytes32", "bytes32", "uint256", "bytes32", "bytes32"],
67
+ [
68
+ packedUserOp.sender,
69
+ packedUserOp.nonce,
70
+ ethers.keccak256(packedUserOp.initCode),
71
+ ethers.keccak256(packedUserOp.callData),
72
+ packedUserOp.accountGasLimits,
73
+ packedUserOp.preVerificationGas,
74
+ packedUserOp.gasFees,
75
+ ethers.keccak256(packedUserOp.paymasterAndData),
76
+ ]
77
+ );
78
+ } else {
79
+ // for the purpose of calculating gas cost encode also signature (and no keccak of bytes)
80
+ return defaultAbiCoder.encode(
81
+ ["address", "uint256", "bytes", "bytes", "bytes32", "uint256", "bytes32", "bytes", "bytes"],
82
+ [
83
+ packedUserOp.sender,
84
+ packedUserOp.nonce,
85
+ packedUserOp.initCode,
86
+ packedUserOp.callData,
87
+ packedUserOp.accountGasLimits,
88
+ packedUserOp.preVerificationGas,
89
+ packedUserOp.gasFees,
90
+ packedUserOp.paymasterAndData,
91
+ packedUserOp.signature,
92
+ ]
93
+ );
94
+ }
95
+ }
96
+
97
+ function getUserOpHash(op, entryPoint, chainId) {
98
+ const userOpHash = ethers.keccak256(encodeUserOp(op, true));
99
+ const enc = defaultAbiCoder.encode(["bytes32", "address", "uint256"], [userOpHash, entryPoint, chainId]);
100
+ return ethers.keccak256(enc);
101
+ }
102
+
103
+ const DefaultsForUserOp = {
104
+ sender: ZeroAddress,
105
+ nonce: 0,
106
+ initCode: "0x",
107
+ callData: "0x",
108
+ callGasLimit: 0,
109
+ verificationGasLimit: 150000, // default verification gas. will add create2 cost (3200+200*length) if initCode exists
110
+ preVerificationGas: 21000, // should also cover calldata cost.
111
+ maxFeePerGas: 0,
112
+ maxPriorityFeePerGas: 1e9,
113
+ paymaster: ZeroAddress,
114
+ paymasterData: "0x",
115
+ paymasterVerificationGasLimit: 3e5,
116
+ paymasterPostOpGasLimit: 0,
117
+ signature: "0x",
118
+ };
119
+
120
+ function signUserOp(op, signer, entryPoint, chainId) {
121
+ const message = getUserOpHash(op, entryPoint, chainId);
122
+ const msg1 = Buffer.concat([
123
+ Buffer.from("\x19Ethereum Signed Message:\n32", "ascii"),
124
+ Buffer.from(arrayify(message)),
125
+ ]);
126
+
127
+ const sig = ecsign(keccak256_buffer(msg1), Buffer.from(arrayify(signer.privateKey)));
128
+ // that's equivalent of: await signer.signMessage(message);
129
+ // (but without "async"
130
+ const signedMessage1 = toRpcSig(sig.v, sig.r, sig.s);
131
+ return {
132
+ ...op,
133
+ signature: signedMessage1,
134
+ };
135
+ }
136
+
137
+ function fillUserOpDefaults(op, defaults = DefaultsForUserOp) {
138
+ const partial = { ...op };
139
+ // we want "item:undefined" to be used from defaults, and not override defaults, so we must explicitly
140
+ // remove those so "merge" will succeed.
141
+ for (const key in partial) {
142
+ if (partial[key] == null) {
143
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
144
+ delete partial[key];
145
+ }
146
+ }
147
+ const filled = { ...defaults, ...partial };
148
+ return filled;
149
+ }
150
+
151
+ module.exports = {
152
+ packAccountGasLimits,
153
+ packUserOp,
154
+ packedUserOpAsArray,
155
+ encodeUserOp,
156
+ getUserOpHash,
157
+ DefaultsForUserOp,
158
+ signUserOp,
159
+ fillUserOpDefaults,
160
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@ensuro/account-abstraction",
3
+ "description": "ERC-4337 related contracts by the Ensuro Team",
4
+ "version": "0.0.1",
5
+ "files": [
6
+ "**/*.sol",
7
+ "/build",
8
+ "/js/*.js"
9
+ ],
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git@github.com:ensuro/account-abstraction.git"
13
+ },
14
+ "keywords": [
15
+ "solidity",
16
+ "ethereum",
17
+ "smart",
18
+ "contracts",
19
+ "decentralized",
20
+ "insurance",
21
+ "ensuro",
22
+ "erc4337"
23
+ ],
24
+ "author": "Ensuro <guillermo@ensuro.co>",
25
+ "license": "Apache-2.0",
26
+ "bugs": {
27
+ "url": "https://github.com/ensuro/account-abstraction/issues"
28
+ },
29
+ "homepage": "https://github.com/ensuro/account-abstraction#readme"
30
+ }