Skip to content

Commit

Permalink
Merge branch 'develop' into actualGasUsed-penalty
Browse files Browse the repository at this point in the history
  • Loading branch information
shahafn committed Jan 30, 2025
2 parents 884b137 + a7be727 commit 908792c
Show file tree
Hide file tree
Showing 23 changed files with 159 additions and 2,202 deletions.
3 changes: 1 addition & 2 deletions contracts/core/BaseAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ abstract contract BaseAccount is IAccount {
function _payPrefund(uint256 missingAccountFunds) internal virtual {
if (missingAccountFunds != 0) {
(bool success, ) = payable(msg.sender).call{
value: missingAccountFunds,
gas: type(uint256).max
value: missingAccountFunds
}("");
(success);
//ignore failure (its EntryPoint's job to verify, not account.)
Expand Down
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 - 500;
}


//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
14 changes: 7 additions & 7 deletions contracts/interfaces/IAggregator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ import "./PackedUserOperation.sol";
*/
interface IAggregator {
/**
* Validate aggregated signature.
* Revert if the aggregated signature does not match the given list of operations.
* @param userOps - Array of UserOperations to validate the signature for.
* Validate an aggregated signature.
* Reverts if the aggregated signature does not match the given list of operations.
* @param userOps - An array of UserOperations to validate the signature for.
* @param signature - The aggregated signature.
*/
function validateSignatures(
PackedUserOperation[] calldata userOps,
bytes calldata signature
) external view;
) external;

/**
* Validate signature of a single userOp.
* Validate the signature of a single userOp.
* This method should be called by bundler after EntryPointSimulation.simulateValidation() returns
* the aggregator this account uses.
* First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.
Expand All @@ -34,8 +34,8 @@ interface IAggregator {
/**
* Aggregate multiple signatures into a single value.
* This method is called off-chain to calculate the signature to pass with handleOps()
* bundler MAY use optimized custom code perform this aggregation.
* @param userOps - Array of UserOperations to collect the signatures from.
* bundler MAY use optimized custom code to perform this aggregation.
* @param userOps - An array of UserOperations to collect the signatures from.
* @return aggregatedSignature - The aggregated signature.
*/
function aggregateSignatures(
Expand Down
4 changes: 2 additions & 2 deletions contracts/interfaces/IEntryPoint.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ interface IEntryPoint is IStakeManager, INonceManager {
* @param userOpHash - The request unique identifier.
* @param sender - The sender of this request.
* @param nonce - The nonce used in the request.
* @param revertReason - The return bytes from the (reverted) call to "callData".
* @param revertReason - The return bytes from the reverted "callData" call.
*/
event UserOperationRevertReason(
bytes32 indexed userOpHash,
Expand All @@ -70,7 +70,7 @@ interface IEntryPoint is IStakeManager, INonceManager {
* @param userOpHash - The request unique identifier.
* @param sender - The sender of this request.
* @param nonce - The nonce used in the request.
* @param revertReason - The return bytes from the (reverted) call to "callData".
* @param revertReason - The return bytes from the reverted call to "postOp".
*/
event PostOpRevertReason(
bytes32 indexed userOpHash,
Expand Down
115 changes: 0 additions & 115 deletions contracts/samples/LegacyTokenPaymaster.sol

This file was deleted.

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
Loading

0 comments on commit 908792c

Please sign in to comment.