-
Notifications
You must be signed in to change notification settings - Fork 681
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AA-521 EntryPoint support for eip-7702 #529
base: develop
Are you sure you want to change the base?
Conversation
overhead: 269 gas per userop (down to 144 on 11th userop) increased (330) with TokenPaymaster - not sure why
contracts/core/Eip7702Support.sol
Outdated
using UserOperationLib for PackedUserOperation; | ||
|
||
//get alternate InitCode (just for hashing) when using EIP-7702 | ||
function _getEip7702InitCodeOverride(PackedUserOperation calldata userOp) view returns (bytes32) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function returns a hash, this is not a correct name.
} | ||
|
||
|
||
function _isEip7702InitCode(bytes calldata initCode) pure returns (bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you write this function without the assembly tricks, how much more gas does it spend? This code is too elaborate for the task of "compare first three bytes".
// solhint-disable-next-line no-inline-assembly | ||
assembly ("memory-safe") { | ||
extcodecopy(sender, 0, 0, 32) | ||
senderCode := mload(0) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need any assembly, you can just do sender.code
. Also if the code is not exactly 23 bytes long it should revert.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- using assembly to avoid creating a dynamic bytes array (even with sender.code, we'd need assembly to grab just the address out of it, as there is no "slice" for memory..)
- No need to check it is 23 bytes: since eip-3541, no deployed contract can start with "0xEF", unless it is EOF. The "0xEF0100" prefix of eip-7702 is invalid as EOF, such checking the prefix implies the 23 bytes length...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even with sender.code, we'd need assembly to grab just the address out of it
I think Solidity now supports just converting bytes
to bytes32
to uint256
so as far as I can tell there should be no difference. I may be wrong though.
bytes memory b = sender.code;
uint256 senderCode = uint256(bytes32(b));
No need to check it is 23 bytes since EIP-3541
I am concerned some up-and-coming L2s may be a little less rigorous in their implementation of EIP-3541 and that would allow some kind of an attack down the line. It would be dirt-cheap to just double-check.
contracts/core/EntryPoint.sol
Outdated
@@ -441,6 +443,11 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuardT | |||
) internal { | |||
if (initCode.length != 0) { | |||
address sender = opInfo.mUserOp.sender; | |||
if ( _isEip7702InitCode(initCode) ) { | |||
//already validated it is an EIP-7702 delegate (and hence, already has code) | |||
senderCreator().initEip7702Sender(sender, initCode[20:]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was under impression that you wanted to call initEip7702Sender
only if initCode
contains some data in addition to 0xff0100
, but this code seems to call it every time.
@@ -192,7 +192,7 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations { | |||
|
|||
//slightly stricter gas limit than the real EntryPoint | |||
function _getVerificationGasLimit(uint256 verificationGasLimit) internal pure virtual override returns (uint256) { | |||
return verificationGasLimit - 300; | |||
return verificationGasLimit - 350; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magic number. As you need to change it, please extract a constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unrelated. we're going to remove "Simulation" from the critical path, and thus all this code will be removed.
contracts/core/UserOperationLib.sol
Outdated
) internal pure returns (bytes memory ret) { | ||
address sender = getSender(userOp); | ||
uint256 nonce = userOp.nonce; | ||
bytes32 hashInitCode = calldataKeccak(userOp.initCode); | ||
bytes32 hashInitCode = overrideInitCode==0 ? calldataKeccak(userOp.initCode) : overrideInitCode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just make a function _getEip7702InitCodeHash
and call it from here, maybe?
951ab2a
to
fb06bc3
Compare
Native support for EIP-7702 in EntryPoint.
Depends on EIP-7702 PR ethereum/EIPs#9248 (extcodehash to return the delegate)