Skip to content

Commit

Permalink
Move EIP712 dependency from AccountCore to Account
Browse files Browse the repository at this point in the history
  • Loading branch information
Amxx committed Jan 6, 2025
1 parent 1fd395e commit 36e1aea
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 34 deletions.
36 changes: 35 additions & 1 deletion contracts/account/Account.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

pragma solidity ^0.8.20;

import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import {ERC7739Signer} from "../utils/cryptography/ERC7739Signer.sol";
import {AccountCore} from "./AccountCore.sol";
import {AccountERC7821} from "./extensions/AccountERC7821.sol";
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

/**
* @dev Extension of {AccountCore} with recommended feature that most account abstraction implementation will want:
Expand All @@ -18,4 +20,36 @@ import {AccountERC7821} from "./extensions/AccountERC7821.sol";
* NOTE: To use this contract, the {ERC7739Signer-_rawSignatureValidation} function must be
* implemented using a specific signature verification algorithm. See {SignerECDSA}, {SignerP256} or {SignerRSA}.
*/
abstract contract Account is AccountCore, AccountERC7821, ERC721Holder, ERC1155Holder, ERC7739Signer {}
abstract contract Account is AccountCore, AccountERC7821, EIP712, ERC721Holder, ERC1155Holder, ERC7739Signer {
bytes32 internal constant _PACKED_USER_OPERATION =
keccak256(
"PackedUserOperation(address sender,uint256 nonce,bytes initCode,bytes callData,bytes32 accountGasLimits,uint256 preVerificationGas,bytes32 gasFees,bytes paymasterAndData)"
);

/**
* @dev Specialization of {AccountCore-_signableUserOpHash} that returns a typehash following EIP-712 typed data
* hashing for readability. This assumes the underlying signature scheme implements `signTypedData`, which will be
* the case when combined with {SignerECDSA} or {AccountSignerERC7702}.
*/
function _signableUserOpHash(
PackedUserOperation calldata userOp,
bytes32 /*userOpHash*/
) internal view virtual override returns (bytes32) {
return
_hashTypedDataV4(
keccak256(
abi.encode(
_PACKED_USER_OPERATION,
userOp.sender,
userOp.nonce,
keccak256(userOp.initCode),
keccak256(userOp.callData),
userOp.accountGasLimits,
userOp.preVerificationGas,
userOp.gasFees,
keccak256(userOp.paymasterAndData)
)
)
);
}
}
35 changes: 4 additions & 31 deletions contracts/account/AccountCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ pragma solidity ^0.8.20;

import {PackedUserOperation, IAccount, IEntryPoint} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
import {ERC4337Utils} from "@openzeppelin/contracts/account/utils/draft-ERC4337Utils.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import {AbstractSigner} from "../utils/cryptography/AbstractSigner.sol";

/**
Expand All @@ -23,14 +20,7 @@ import {AbstractSigner} from "../utils/cryptography/AbstractSigner.sol";
* attacker to bypass the account's security measures. Check out {SignerECDSA}, {SignerP256}, or {SignerRSA} for
* digital signature validation implementations.
*/
abstract contract AccountCore is AbstractSigner, EIP712, IAccount {
using MessageHashUtils for bytes32;

bytes32 internal constant _PACKED_USER_OPERATION =
keccak256(
"PackedUserOperation(address sender,uint256 nonce,bytes initCode,bytes callData,bytes32 accountGasLimits,uint256 preVerificationGas,bytes32 gasFees,bytes paymasterAndData)"
);

abstract contract AccountCore is AbstractSigner, IAccount {
/**
* @dev Unauthorized call to the account.
*/
Expand Down Expand Up @@ -93,29 +83,12 @@ abstract contract AccountCore is AbstractSigner, EIP712, IAccount {
*
* Given the `userOpHash` calculation is defined by ERC-4337, offchain signers
* may need to sign again this hash by rehashing it with other schemes (e.g. ERC-191).
*
* Returns a typehash following EIP-712 typed data hashing for readability.
*/
function _signableUserOpHash(
PackedUserOperation calldata userOp,
bytes32 /* userOpHash */
PackedUserOperation calldata /*userOp*/,
bytes32 userOpHash
) internal view virtual returns (bytes32) {
return
_hashTypedDataV4(
keccak256(
abi.encode(
_PACKED_USER_OPERATION,
userOp.sender,
userOp.nonce,
keccak256(userOp.initCode),
keccak256(userOp.callData),
userOp.accountGasLimits,
userOp.preVerificationGas,
userOp.gasFees,
keccak256(userOp.paymasterAndData)
)
)
);
return userOpHash;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions contracts/account/extensions/AccountSignerERC7702.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
pragma solidity ^0.8.20;

import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {AccountCore} from "../AccountCore.sol";
import {AbstractSigner} from "../../utils/cryptography/AbstractSigner.sol";

/**
* @dev {Account} implementation whose low-level signature validation is done by an EOA.
*/
abstract contract AccountSignerERC7702 is AccountCore {
abstract contract AccountSignerERC7702 is AbstractSigner {
/**
* @dev Validates the signature using the EOA's address (ie. `address(this)`).
*/
Expand Down

0 comments on commit 36e1aea

Please sign in to comment.