Yoav Weiss, Dror Tirosh, Shahaf Nacson
https://github.com/eth-infinitism/account-abstraction
Note:
account: time-range (session keys)
pm: support token paymaster
agg: for rollups
RPC: simulation, estimation
Extras: For standarized bundler compatibility
n
UserOps into the mempool should cost O(n)
struct UserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
uint256 callGasLimit;
uint256 verificationGasLimit;
uint256 preVerificationGas;
uint256 maxFeePerGas;
uint256 maxPriorityFeePerGas;
bytes paymasterAndData;
bytes signature;
}
Note:
explain all entities
function validateUserOp(UserOperation userOp,
bytes32 userOpHash, uint256 missingAccountFunds)
external returns (uint256 validationData);
validAfter
, validUntil
Notes:
missingfunds - maxPossiblecost
function validateUserOp(UserOperation userOp,
bytes32 userOpHash, uint256 missingFunds)
external returns (uint256 validationData) {
require(msg.sender == address(entryPoint);
bytes32 hash = userOpHash.toEthSignedMessageHash();
bool sigFailed = owner != hash.recover(userOp.signature);
validationData = sigFailed ? 1 : 0;
require(nonce++ == userOp.nonce);
if (missingFunds != 0)
entryPoint.depositTo{value : missingFunds}(msg.sender);
}
function validatePaymasterUserOp(UserOperation userOp,
bytes32 userOpHash, uint256 maxCost)
returns (bytes context, uint256 validationData)
function postOp(PostOpMode mode, bytes context,
uint256 actualGasCost)
validationData
like in Account.UserOp.initCode
: address + calldatacontract SimpleAccountFactory {
function createAccount(address owner,bytes32 salt)
public returns (address) {
address addr = Create2.computeAddress(...);
uint codeSize = addr.code.length;
if (codeSize > 0) return addr;
ret = new Proxy{salt : salt} (
accountImplementation,
abi.encodeCall(
SimpleAccount.initialize, (owner))
);
}
}
n
UserOps into the mempool should cost O(n)
Note:
The EP protects the account: only execute after its validation
The separation of validation help the bundlers to validate userops fast.
The rules below protect the bundlers: prevent DoS attacks
account.getNonce()
)token.balanceOf(account)
)eth_sendUserOperation(userOp)
:
simulateValidation(userOp)
(first simulation). If simulation succeeds, add userOp to mempool.simulateValidation(userOp)
(second simulation)eth_sendUserOperation
eth_estimateUserOperationGas
eth_getUserOperationReceipt
eth_getUserOperationByHash
eth_supportedEntryPoints