If the account does not yet exist and the initcode is empty, `_validateAccountPrepayment()` reverts without any specific error message
eunseong-theori opened this issue · 1 comments
Unlike _validateSenderAndPaymaster()
which explicitly reverts when initCode.length == 0 && sender.code.length == 0
, _createSenderIfNeeded()
does not. If the account does not yet exist and the initcode is empty, _validateAccountPrepayment()
reverts without any specific error message
function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {
if (initCode.length != 0) {
address sender = opInfo.mUserOp.sender;
if (sender.code.length != 0) revert FailedOp(opIndex, "AA10 sender already constructed");
address sender1 = senderCreator.createSender{gas: opInfo.mUserOp.verificationGasLimit}(initCode);
if (sender1 == address(0)) revert FailedOp(opIndex, "AA13 initCode failed or OOG");
if (sender1 != sender) revert FailedOp(opIndex, "AA14 initCode must return sender");
if (sender1.code.length == 0) revert FailedOp(opIndex, "AA15 initCode must create sender");
address factory = address(bytes20(initCode[0:20]));
emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);
}
}
This function should add a check condition for initCode.length == 0 && sender.code.length == 0
to give an explicit error message like "revert("AA20 account not deployed");"
That's true, but this is something that is very easy for a bundler to detect and reject during validation, without a modification on the EntryPoint
(e.g. just like minimal verification/call gas limits, which also could revert with no reason string)
In general, we try to reduce on-chain code for things that can easily be handled off-chain (and of course, that can't open a security breach by someone calling directly into the entrypoint)