Structural Error
In this page, we explore vulnerabilities caused by incorrect structural error.
Version Mismatch of Reference Implementation
There are cases where the Paymaster implements the v0.6 interface but references an EntryPoint from v0.7.
In the eth-infinitism project, when the account-abstraction was upgraded from version 0.6 to 0.7, there were some changes.
// https://github.com/eth-infinitism/account-abstraction/blob/releases/v0.6/contracts/core/EntryPoint.sol
// Entrypoint v0.6
function _validatePaymasterPrepayment(
uint256 opIndex,
UserOperation calldata op,
UserOpInfo memory opInfo,
uint256 requiredPreFund,
uint256 gasUsedByValidateAccountPrepayment
)
internal returns (bytes memory context, uint256 validationData) {
...
...
try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(
op,
opInfo.userOpHash,
requiredPreFund
) returns (bytes memory _context, uint256 _validationData)
...
// https://github.com/eth-infinitism/account-abstraction/blob/releases/v0.7/contracts/core/EntryPoint.sol
// Entrypoint v0.7
function _validatePaymasterPrepayment(
uint256 opIndex,
PackedUserOperation calldata op,
UserOpInfo memory opInfo,
uint256 requiredPreFund
) internal returns (bytes memory context, uint256 validationData) {
...
...
try
IPaymaster(paymaster).validatePaymasterUserOp{gas: pmVerificationGasLimit}(
op,
opInfo.userOpHash,
requiredPreFund
) returns (bytes memory _context, uint256 _validationData) {
The code above shows where validatePaymasterUserOp
is called to validate the paymaster for a UserOp in Entrypoint versions 0.6 and 0.7.
Looking at the parameters in each code snippet shows that the parameter on line 6 is different. Version 0.6 uses the UserOperation struct, while version 0.7 uses the PackedUserOperation struct.
// UserOperation.sol v0.6
struct UserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
uint256 callGasLimit;
uint256 verificationGasLimit;
uint256 preVerificationGas;
uint256 maxFeePerGas;
uint256 maxPriorityFeePerGas;
bytes paymasterAndData;
bytes signature;
}
// PackedUserOperation.sol v0.7
struct PackedUserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
bytes32 accountGasLimits;
uint256 preVerificationGas;
bytes32 gasFees;
bytes paymasterAndData;
bytes signature;
}
The code above shows the UserOperation struct used in account-abstraction version 0.6 and the PackedUserOperation struct used in version 0.7. Although there are only small structural changes between them, using the wrong struct type as a parameter can lead to a revert.
Mitigation: Implement the paymaster according to version 0.7, or reference Entrypoint version 0.6 to maintain version consistency.
Improper Handling of Invalid paymasterAndData Format During Validation
If a UserOp with an improperly formatted UserOperation.paymasterAndData
is submitted and the paymaster's validation function fails to correctly identify and revert the invalid format, it could lead to unexpected results.
Mitigation : During the validation process, parse paymasterAndData and revert if the format is incorrect
Last updated