Skip to content

Commit

Permalink
Merge branch 'develop' into drortirosh-patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
drortirosh committed Jan 23, 2025
2 parents 974bd46 + 7cbc19b commit 5d0e320
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 58 deletions.
27 changes: 21 additions & 6 deletions contracts/core/EntryPoint.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,38 @@ pragma solidity ^0.8.23;

import "../interfaces/IAccount.sol";
import "../interfaces/IAccountExecute.sol";
import "../interfaces/IPaymaster.sol";
import "../interfaces/IEntryPoint.sol";
import "../interfaces/IPaymaster.sol";

import "../utils/Exec.sol";
import "./StakeManager.sol";
import "./SenderCreator.sol";
import "./Helpers.sol";
import "./NonceManager.sol";
import "./SenderCreator.sol";
import "./StakeManager.sol";
import "./UserOperationLib.sol";

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

/*
* Account-Abstraction (EIP-4337) singleton EntryPoint implementation.
* Only one instance required on each chain.
*/

/// @custom:security-contact https://bounty.ethereum.org
contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuardTransient, ERC165 {
contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuardTransient, ERC165, EIP712 {

using UserOperationLib for PackedUserOperation;

SenderCreator private immutable _senderCreator = new SenderCreator();

string constant internal DOMAIN_NAME = "ERC4337";
string constant internal DOMAIN_VERSION = "1";

constructor() EIP712(DOMAIN_NAME, DOMAIN_VERSION) {
}

function senderCreator() public view virtual returns (ISenderCreator) {
return _senderCreator;
}
Expand Down Expand Up @@ -359,12 +366,20 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuardT
}
}

function getPackedUserOpTypeHash() public pure returns (bytes32) {
return UserOperationLib.PACKED_USEROP_TYPEHASH;
}

function getDomainSeparatorV4() public virtual view returns (bytes32) {
return _domainSeparatorV4();
}

/// @inheritdoc IEntryPoint
function getUserOpHash(
PackedUserOperation calldata userOp
) public view returns (bytes32) {
return
keccak256(abi.encode(userOp.hash(), address(this), block.chainid));
MessageHashUtils.toTypedDataHash(getDomainSeparatorV4(), userOp.hash());
}

/**
Expand Down
24 changes: 24 additions & 0 deletions contracts/core/EntryPointSimulations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {

SenderCreator private _senderCreator;

bytes32 private __domainSeparatorV4;

function initSenderCreator() internal virtual {
//this is the address of the first contract created with CREATE by this address.
address createdObj = address(uint160(uint256(keccak256(abi.encodePacked(hex"d694", address(this), hex"01")))));
_senderCreator = SenderCreator(createdObj);

initDomainSeparator();
}

function senderCreator() public view virtual override(EntryPoint, IEntryPoint) returns (ISenderCreator) {
Expand Down Expand Up @@ -191,4 +195,24 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
return verificationGasLimit - 300;
}


//copied from EIP712.sol
bytes32 private constant TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

function __buildDomainSeparator() private view returns (bytes32) {
bytes32 _hashedName = keccak256(bytes(DOMAIN_NAME));
bytes32 _hashedVersion = keccak256(bytes(DOMAIN_VERSION));
return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
}

//can't rely on "immutable" (constructor-initialized) variables" in simulation
function initDomainSeparator() internal {
__domainSeparatorV4 = __buildDomainSeparator();
}

function getDomainSeparatorV4() public override view returns (bytes32) {
return __domainSeparatorV4;
}

}
6 changes: 6 additions & 0 deletions contracts/core/UserOperationLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ library UserOperationLib {
}
}

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

/**
* Pack the user operation data into bytes for hashing.
* @param userOp - The user operation data.
Expand All @@ -64,6 +69,7 @@ library UserOperationLib {
bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);

return abi.encode(
UserOperationLib.PACKED_USEROP_TYPEHASH,
sender, nonce,
hashInitCode, hashCallData,
accountGasLimits, preVerificationGas, gasFees,
Expand Down
5 changes: 3 additions & 2 deletions contracts/samples/SimpleAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ contract SimpleAccount is BaseAccount, TokenCallbackHandler, UUPSUpgradeable, In
/// implement template method of BaseAccount
function _validateSignature(PackedUserOperation calldata userOp, bytes32 userOpHash)
internal override virtual returns (uint256 validationData) {
bytes32 hash = MessageHashUtils.toEthSignedMessageHash(userOpHash);
if (owner != ECDSA.recover(hash, userOp.signature))

//userOpHash can be generated using eth_signTypedData_v4
if (owner != ECDSA.recover(userOpHash, userOp.signature))
return SIG_VALIDATION_FAILED;
return SIG_VALIDATION_SUCCESS;
}
Expand Down
3 changes: 1 addition & 2 deletions contracts/test/TestExpiryAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ contract TestExpiryAccount is SimpleAccount {
/// implement template method of BaseAccount
function _validateSignature(PackedUserOperation calldata userOp, bytes32 userOpHash)
internal override view returns (uint256 validationData) {
bytes32 hash = MessageHashUtils.toEthSignedMessageHash(userOpHash);
address signer = ECDSA.recover(hash,userOp.signature);
address signer = ECDSA.recover(userOpHash,userOp.signature);
uint48 _until = ownerUntil[signer];
uint48 _after = ownerAfter[signer];

Expand Down
42 changes: 21 additions & 21 deletions reports/gas-checker.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
the destination is "account.entryPoint()", which is known to be "hot" address used by this account
it little higher than EOA call: its an exec from entrypoint (or account owner) into account contract, verifying msg.sender and exec to target)
╔══════════════════════════╤════════╗
║ gas estimate "simple" │ 29259
║ gas estimate "simple" │ 29235
╟──────────────────────────┼────────╢
║ gas estimate "big tx 5k" │ 114702 ║
╚══════════════════════════╧════════╝
Expand All @@ -12,44 +12,44 @@
║ │ │ │ (delta for │ (compared to ║
║ │ │ │ one UserOp) │ account.exec()) ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple │ 1 │ 77452 │ │ ║
║ simple │ 1 │ 77438 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple - diff from previous │ 2 │ │ 4164412385
║ simple - diff from previous │ 2 │ │ 4161012375
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple │ 10 │ 452555 │ │ ║
║ simple │ 10 │ 452004 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple - diff from previous │ 11 │ │ 4172312464
║ simple - diff from previous │ 11 │ │ 4163512400
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster │ 1 │ 83295 │ │ ║
║ simple paymaster │ 1 │ 83281 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster with diff │ 2 │ │ 4018810929
║ simple paymaster with diff │ 2 │ │ 4014210907
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster │ 10 │ 445222 │ │ ║
║ simple paymaster │ 10 │ 444690 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster with diff │ 11 │ │ 4024010981
║ simple paymaster with diff │ 11 │ │ 4015110916
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx 5k │ 1 │ 167225 │ │ ║
║ big tx 5k │ 1 │ 167209 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx - diff from previous │ 2 │ │ 13088316181
║ big tx - diff from previous │ 2 │ │ 13079916097
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx 5k │ 10 │ 1345259 │ │ ║
║ big tx 5k │ 10 │ 1344678 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx - diff from previous │ 11 │ │ 13090316201
║ big tx - diff from previous │ 11 │ │ 13082416122
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ paymaster+postOp │ 1 │ 84460 │ │ ║
║ paymaster+postOp │ 1 │ 84446 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ paymaster+postOp with diff │ 2 │ │ 4136512106
║ paymaster+postOp with diff │ 2 │ │ 4133012095
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ paymaster+postOp │ 10 │ 457036 │ │ ║
║ paymaster+postOp │ 10 │ 456453 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ paymaster+postOp with diff │ 11 │ │ 4139812139
║ paymaster+postOp with diff │ 11 │ │ 4133312098
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ token paymaster │ 1 │ 121518 │ │ ║
║ token paymaster │ 1 │ 121560 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ token paymaster with diff │ 2 │ │ 6115731898
║ token paymaster with diff │ 2 │ │ 6113031895
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ token paymaster │ 10 │ 672052 │ │ ║
║ token paymaster │ 10 │ 671937 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ token paymaster with diff │ 11 │ │ 6116531906
║ token paymaster with diff │ 11 │ │ 6120031965
╚════════════════════════════════╧═══════╧═══════════════╧════════════════╧═════════════════════╝

Loading

0 comments on commit 5d0e320

Please sign in to comment.