generated from NomicFoundation/hardhat-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathAccount.sol
62 lines (54 loc) · 2.84 KB
/
Account.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@account-abstraction/contracts/core/BaseAccount.sol";
/**
* @dev This contract provides the basic logic for implementing the ERC4337 IAccount interface
*/
abstract contract Account is BaseAccount {
// magic value indicating successfull EIP1271 signature validation.
bytes4 private constant EIP1271_MAGICVALUE = 0x1626ba7e;
// return value in case of signature validation success, with no time-range.
uint256 private constant SIG_VALIDATION_SUCCEEDED = 0;
/**
* @dev Hard-code the ERC4337 entry point contract address so it cannot be changed by anyone
*/
IEntryPoint private constant _entryPoint =
IEntryPoint(0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789);
/// @inheritdoc BaseAccount
function entryPoint() public view virtual override returns (IEntryPoint) {
return _entryPoint;
}
/// @inheritdoc BaseAccount
function _validateNonce(uint256 nonce) internal view virtual override {
// First 192 bits are the sequence key, remaining 64 bits are the sequence number
// We only use the nonce sequence with key 0, so no out-of-order nonce is possible.
require(nonce < type(uint64).max, "Invalid nonce");
}
/**
* @dev Check if the signature is valid for this user operation. Child contracts can override this function to provide a different signature validation logic.
* @param userOp The user operation, including the signature field
* @param userOpHash The hash of the user operation to check the signature against (also hashes the entry point and chain id)
* @return validationData Signature validation result and validity time-range
* <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,
* otherwise, an address of an "authorizer" contract.
* <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite"
* <6-byte> validAfter - first timestamp this operation is valid
* If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.
* Note that the validation code cannot use block.timestamp (or block.number) directly.
*/
function _validateSignature(
UserOperation calldata userOp,
bytes32 userOpHash
) internal view virtual override returns (uint256 validationData) {
bytes32 hash = ECDSA.toEthSignedMessageHash(userOpHash);
if (isValidSignature(hash, userOp.signature) != EIP1271_MAGICVALUE) {
return SIG_VALIDATION_FAILED;
}
return SIG_VALIDATION_SUCCEEDED;
}
function isValidSignature(
bytes32 hash,
bytes memory signature
) public view virtual returns (bytes4 magicValue);
}