mirror of
https://github.com/getwax/zk-account-abstraction.git
synced 2026-01-08 20:18:05 -05:00
* EntryPoint to manage Nonce - NonceManager to handle 2d nonces - _validateAndUpdateNonce() called after validateUserOp - getNonce(sender, key) - remove nonce checking from BaseAccount - BaseAccount implements getNonce() using ep.getNonce
200 lines
9.0 KiB
Solidity
200 lines
9.0 KiB
Solidity
/**
|
|
** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.
|
|
** Only one instance required on each chain.
|
|
**/
|
|
// SPDX-License-Identifier: GPL-3.0
|
|
pragma solidity ^0.8.12;
|
|
|
|
/* solhint-disable avoid-low-level-calls */
|
|
/* solhint-disable no-inline-assembly */
|
|
/* solhint-disable reason-string */
|
|
|
|
import "./UserOperation.sol";
|
|
import "./IStakeManager.sol";
|
|
import "./IAggregator.sol";
|
|
import "./INonceManager.sol";
|
|
|
|
interface IEntryPoint is IStakeManager, INonceManager {
|
|
|
|
/***
|
|
* An event emitted after each successful request
|
|
* @param userOpHash - unique identifier for the request (hash its entire content, except signature).
|
|
* @param sender - the account that generates this request.
|
|
* @param paymaster - if non-null, the paymaster that pays for this request.
|
|
* @param nonce - the nonce value from the request.
|
|
* @param success - true if the sender transaction succeeded, false if reverted.
|
|
* @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.
|
|
* @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).
|
|
*/
|
|
event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);
|
|
|
|
/**
|
|
* account "sender" was deployed.
|
|
* @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.
|
|
* @param sender the account that is deployed
|
|
* @param factory the factory used to deploy this account (in the initCode)
|
|
* @param paymaster the paymaster used by this UserOp
|
|
*/
|
|
event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);
|
|
|
|
/**
|
|
* An event emitted if the UserOperation "callData" reverted with non-zero length
|
|
* @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".
|
|
*/
|
|
event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);
|
|
|
|
/**
|
|
* signature aggregator used by the following UserOperationEvents within this bundle.
|
|
*/
|
|
event SignatureAggregatorChanged(address indexed aggregator);
|
|
|
|
/**
|
|
* a custom revert error of handleOps, to identify the offending op.
|
|
* NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.
|
|
* @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)
|
|
* @param reason - revert reason
|
|
* The string starts with a unique code "AAmn", where "m" is "1" for factory, "2" for account and "3" for paymaster issues,
|
|
* so a failure can be attributed to the correct entity.
|
|
* Should be caught in off-chain handleOps simulation and not happen on-chain.
|
|
* Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.
|
|
*/
|
|
error FailedOp(uint256 opIndex, string reason);
|
|
|
|
/**
|
|
* error case when a signature aggregator fails to verify the aggregated signature it had created.
|
|
*/
|
|
error SignatureValidationFailed(address aggregator);
|
|
|
|
/**
|
|
* Successful result from simulateValidation.
|
|
* @param returnInfo gas and time-range returned values
|
|
* @param senderInfo stake information about the sender
|
|
* @param factoryInfo stake information about the factory (if any)
|
|
* @param paymasterInfo stake information about the paymaster (if any)
|
|
*/
|
|
error ValidationResult(ReturnInfo returnInfo,
|
|
StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);
|
|
|
|
/**
|
|
* Successful result from simulateValidation, if the account returns a signature aggregator
|
|
* @param returnInfo gas and time-range returned values
|
|
* @param senderInfo stake information about the sender
|
|
* @param factoryInfo stake information about the factory (if any)
|
|
* @param paymasterInfo stake information about the paymaster (if any)
|
|
* @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)
|
|
* bundler MUST use it to verify the signature, or reject the UserOperation
|
|
*/
|
|
error ValidationResultWithAggregation(ReturnInfo returnInfo,
|
|
StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,
|
|
AggregatorStakeInfo aggregatorInfo);
|
|
|
|
/**
|
|
* return value of getSenderAddress
|
|
*/
|
|
error SenderAddressResult(address sender);
|
|
|
|
/**
|
|
* return value of simulateHandleOp
|
|
*/
|
|
error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);
|
|
|
|
//UserOps handled, per aggregator
|
|
struct UserOpsPerAggregator {
|
|
UserOperation[] userOps;
|
|
|
|
// aggregator address
|
|
IAggregator aggregator;
|
|
// aggregated signature
|
|
bytes signature;
|
|
}
|
|
|
|
/**
|
|
* Execute a batch of UserOperation.
|
|
* no signature aggregator is used.
|
|
* if any account requires an aggregator (that is, it returned an aggregator when
|
|
* performing simulateValidation), then handleAggregatedOps() must be used instead.
|
|
* @param ops the operations to execute
|
|
* @param beneficiary the address to receive the fees
|
|
*/
|
|
function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;
|
|
|
|
/**
|
|
* Execute a batch of UserOperation with Aggregators
|
|
* @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)
|
|
* @param beneficiary the address to receive the fees
|
|
*/
|
|
function handleAggregatedOps(
|
|
UserOpsPerAggregator[] calldata opsPerAggregator,
|
|
address payable beneficiary
|
|
) external;
|
|
|
|
/**
|
|
* generate a request Id - unique identifier for this request.
|
|
* the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.
|
|
*/
|
|
function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);
|
|
|
|
/**
|
|
* Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.
|
|
* @dev this method always revert. Successful result is ValidationResult error. other errors are failures.
|
|
* @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.
|
|
* @param userOp the user operation to validate.
|
|
*/
|
|
function simulateValidation(UserOperation calldata userOp) external;
|
|
|
|
/**
|
|
* gas and return values during simulation
|
|
* @param preOpGas the gas used for validation (including preValidationGas)
|
|
* @param prefund the required prefund for this operation
|
|
* @param sigFailed validateUserOp's (or paymaster's) signature check failed
|
|
* @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)
|
|
* @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)
|
|
* @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)
|
|
*/
|
|
struct ReturnInfo {
|
|
uint256 preOpGas;
|
|
uint256 prefund;
|
|
bool sigFailed;
|
|
uint48 validAfter;
|
|
uint48 validUntil;
|
|
bytes paymasterContext;
|
|
}
|
|
|
|
/**
|
|
* returned aggregated signature info.
|
|
* the aggregator returned by the account, and its current stake.
|
|
*/
|
|
struct AggregatorStakeInfo {
|
|
address aggregator;
|
|
StakeInfo stakeInfo;
|
|
}
|
|
|
|
/**
|
|
* Get counterfactual sender address.
|
|
* Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.
|
|
* this method always revert, and returns the address in SenderAddressResult error
|
|
* @param initCode the constructor code to be passed into the UserOperation.
|
|
*/
|
|
function getSenderAddress(bytes memory initCode) external;
|
|
|
|
|
|
/**
|
|
* simulate full execution of a UserOperation (including both validation and target execution)
|
|
* this method will always revert with "ExecutionResult".
|
|
* it performs full validation of the UserOperation, but ignores signature error.
|
|
* an optional target address is called after the userop succeeds, and its value is returned
|
|
* (before the entire call is reverted)
|
|
* Note that in order to collect the the success/failure of the target call, it must be executed
|
|
* with trace enabled to track the emitted events.
|
|
* @param op the UserOperation to simulate
|
|
* @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult
|
|
* are set to the return from that call.
|
|
* @param targetCallData callData to pass to target address
|
|
*/
|
|
function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;
|
|
}
|
|
|