|
| 1 | +// SPDX-License-Identifier: MIT |
| 2 | +pragma solidity ^0.8.28; |
| 3 | + |
| 4 | +import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; |
| 5 | +import "@openzeppelin/contracts/interfaces/IERC1271.sol"; |
| 6 | +import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; |
| 7 | +import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; |
| 8 | +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; |
| 9 | +import "account-abstraction/contracts/core/Helpers.sol"; |
| 10 | +import "account-abstraction/contracts/core/BaseAccount.sol"; |
| 11 | + |
| 12 | +/** |
| 13 | + * Simple7702Account.sol |
| 14 | + * A minimal account to be used with EIP-7702 (for batching) and ERC-4337 (for gas sponsoring) |
| 15 | + */ |
| 16 | +contract Simple7702Account is BaseAccount, IERC165, IERC1271, ERC1155Holder, ERC721Holder { |
| 17 | + |
| 18 | + // address of entryPoint v0.8 |
| 19 | + function entryPoint() public pure override returns (IEntryPoint) { |
| 20 | + return IEntryPoint(0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108); |
| 21 | + } |
| 22 | + |
| 23 | + /** |
| 24 | + * Make this account callable through ERC-4337 EntryPoint. |
| 25 | + * The UserOperation should be signed by this account's private key. |
| 26 | + */ |
| 27 | + function _validateSignature( |
| 28 | + PackedUserOperation calldata userOp, |
| 29 | + bytes32 userOpHash |
| 30 | + ) internal virtual override returns (uint256 validationData) { |
| 31 | + |
| 32 | + return _checkSignature(userOpHash, userOp.signature) ? SIG_VALIDATION_SUCCESS : SIG_VALIDATION_FAILED; |
| 33 | + } |
| 34 | + |
| 35 | + function isValidSignature(bytes32 hash, bytes memory signature) public view returns (bytes4 magicValue) { |
| 36 | + return _checkSignature(hash, signature) ? this.isValidSignature.selector : bytes4(0xffffffff); |
| 37 | + } |
| 38 | + |
| 39 | + function _checkSignature(bytes32 hash, bytes memory signature) internal view returns (bool) { |
| 40 | + return ECDSA.recover(hash, signature) == address(this); |
| 41 | + } |
| 42 | + |
| 43 | + function _requireForExecute() internal view virtual override { |
| 44 | + require( |
| 45 | + msg.sender == address(this) || |
| 46 | + msg.sender == address(entryPoint()), |
| 47 | + "not from self or EntryPoint" |
| 48 | + ); |
| 49 | + } |
| 50 | + |
| 51 | + function supportsInterface(bytes4 id) public override(ERC1155Holder, IERC165) pure returns (bool) { |
| 52 | + return |
| 53 | + id == type(IERC165).interfaceId || |
| 54 | + id == type(IAccount).interfaceId || |
| 55 | + id == type(IERC1271).interfaceId || |
| 56 | + id == type(IERC1155Receiver).interfaceId || |
| 57 | + id == type(IERC721Receiver).interfaceId; |
| 58 | + } |
| 59 | + |
| 60 | + // accept incoming calls (with or without value), to mimic an EOA. |
| 61 | + fallback() external payable { |
| 62 | + } |
| 63 | + |
| 64 | + receive() external payable { |
| 65 | + } |
| 66 | +} |
0 commit comments