eth-infinitism / account-abstraction

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Improve validation failure checking

nebolax opened this issue · comments

I was doing some experiments with https://github.com/zerodevapp/kernel.

At some point I supplied an incorrect signature, but didn't notice it.

Due to this, Kernel's validateUserOp returned 1 as the validation data.

The user op execution does stop due to this, so there is no security issue. The problem is where it stops.

The part of the code that is responsible for validationData checking only reverts on failure, but doesn't revert if the returned validationData is incorrect.

try
                IAccount(sender).validateUserOp{
                    gas: mUserOp.verificationGasLimit
                }(op, opInfo.userOpHash, missingAccountFunds)
            returns (uint256 _validationData) {
                validationData = _validationData;
            } catch Error(string memory revertReason) {
                revert FailedOp(
                    opIndex,
                    string.concat("AA23 reverted: ", revertReason)
                );
            } catch {
                revert FailedOp(opIndex, "AA23 reverted (or OOG)");
            }

If there is a paymaster or there is enough deposit to cover the prefund, the execution reaches _validateAccountAndPaymasterValidationData and fails with "AA24 signature error", which is good!

However if there is no paymaster provided and the user doesn't have enough deposit in EntryPoint (which was my case), the user op fails with "AA21 didn't pay prefund", which is confusing because the actual problem is that validation did not succeed, not the prefund missing.

if (paymaster == address(0)) {
                DepositInfo storage senderInfo = deposits[sender];
                uint256 deposit = senderInfo.deposit;
                if (requiredPrefund > deposit) {
                    revert FailedOp(opIndex, "AA21 didn't pay prefund");
                }
                senderInfo.deposit = uint112(deposit - requiredPrefund);
            }

I am asking if it will make sense to adjust the code in the entry point for future updates or should it better be considered Kernel's fault because they used an anti-pattern or is it expected behavior and everything is fine here?

Simulation functions are not expected to be called directly by end-users, but by bundlers.
A user would execute eth_esimtateUserOperation and get the results.
The reason the method doesn't revert on signature failure, is exactly that: we want to be able to use these validation functions also for gas estimation, so that you could use it to estimate gas as accurately as possible without requiring the user to sign the request.