bundler v1.0.0
abstractjs v1.0.13
abstractjs (via viem and account-abstraction) formats outgoing requests to the bundler, encoding any numeric literals to hex strings. The bundler, on receiving a request, does not reverse the formatting, instead passing the user op unchecked to the request method handler. This can cause valid userOps to be misinterpreted by the application.
An example of this problem is when sending a transaction with a custom paymaster configured in abstractjs' createSmartAccountClient. The gas limits - numeric literals - returned by the paymaster's getPaymasterData method get converted to hex-strings before being sent to the bundler to estimate user operation gas. In the bundler, the gas estimator constructs the packed user op and in the process incorrectly converts the hex-string limits to ascii - huge numbers that cause gas estimation to incorrectly report insufficient funds.
Fortunately, custom paymasters have the option of returning pre-encoded paymasterAndData so this specific example can be worked around.
Detailed example:
Consider the following paymaster client and bundler log...
class PaymasterConfig {
paymasterAddress: string;
constructor(paymasterAddress: string) {
this.paymasterAddress = paymasterAddress;
this.getPaymasterData = this.getPaymasterData.bind(this);
this.getPaymasterStubData = this.getPaymasterStubData.bind(this);
}
async getPaymasterData(params: GetPaymasterDataParameters): Promise<GetPaymasterDataReturnType> {
return {
paymaster: this.paymasterAddress,
paymasterData: abiEncode(["address"], [this.paymasterAddress]),
paymasterVerificationGasLimit: 500_000,
paymasterPostOpGasLimit: 1_500_000,
}
}
async getPaymasterStubData(): Promise<GetPaymasterDataReturnType> {
return "0x";
}
}
[10:33:52.110] INFO (54): EP v7 estimateUserOperationGas called, entryPointAddress: 0x0000000071727De22E5E9d8BAf0edAc6f37da032
module: "api/v3/eth_estimateUserOperationGas/handler.ts"
chainId: "137"
requestId: 4
apiKey: "my_apikey"
[10:33:52.111] INFO (54): userOp received: {"callData":"0xe9ae5c53000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000034f5715961c550fc497832063a98ea34673ad7c8160000000000000000000000000000000000000000000000000000000000000001000000000000000000000000","factory":"0xf0C1dab676AE40CFA72C85A4805B0E711A29827F","factoryData":"0xea6d13ac000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000bd4c9e797a8dbbfdde9c77bc5a5b21acf611db8f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020441bede0300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000142DcC3C0c49Bf7c0b095F7B7cd7cef30e2c9279050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","nonce":"0xc2f1500000000000000000000000000000000000000000000000000000000000","paymaster":"0x1870F688591aD27Cb5506A3F1a6675294649668d","paymasterData":"0x0000000000000000000000001870f688591ad27cb5506a3f1a6675294649668d","paymasterPostOpGasLimit":"0x16e360","paymasterVerificationGasLimit":"0x7a120","sender":"0x5F38eB7AeC00C43Adc5ACb64EB417a9d192aE013","signature":"0x81d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b"} on chainId: 137
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.111] INFO (54): userOp to be used for estimation: {"callData":"0xe9ae5c53000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000034f5715961c550fc497832063a98ea34673ad7c8160000000000000000000000000000000000000000000000000000000000000001000000000000000000000000","factory":"0xf0C1dab676AE40CFA72C85A4805B0E711A29827F","factoryData":"0xea6d13ac000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000bd4c9e797a8dbbfdde9c77bc5a5b21acf611db8f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020441bede0300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000142DcC3C0c49Bf7c0b095F7B7cd7cef30e2c9279050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","nonce":"0xc2f1500000000000000000000000000000000000000000000000000000000000","paymaster":"0x1870F688591aD27Cb5506A3F1a6675294649668d","paymasterData":"0x0000000000000000000000001870f688591ad27cb5506a3f1a6675294649668d","paymasterPostOpGasLimit":"0x16e360","paymasterVerificationGasLimit":"0x7a120","sender":"0x5F38eB7AeC00C43Adc5ACb64EB417a9d192aE013","signature":"0x81d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b","maxFeePerGas":"1","callGasLimit":"5000000","verificationGasLimit":"5000000","preVerificationGas":"5000000","maxPriorityFeePerGas":"1"} on chainId: 137
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.111] INFO (54): config:
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.111] INFO (54): getting baseFeePerGas from gasPriceService
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.111] INFO (54): GasPriceService.getBaseFeePerGas
chainId: 137
key: "BaseFeePerGas_137"
[10:33:52.111] INFO (54): RedisCacheService.get()
module: "common/cache/redis/RedisCacheService.ts"
key: "BaseFeePerGas_137"
[10:33:52.113] INFO (54): calling estimateUserOperationGas (v7) from entry-point-gas-estimations package
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.113] INFO (54): testing console.log 2
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.113] INFO (54): Estimating gas for user operation (v7)...
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.113] INFO (54): calling simulateHandleOp
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.114] INFO (54): Simulating handleOp...
module: "src/common/simulation/BundlerSimulationService.v7.ts"
[10:33:52.114] INFO (54): Packed User Operation: {"sender":"0x5F38eB7AeC00C43Adc5ACb64EB417a9d192aE013","nonce":"0xc2f1500000000000000000000000000000000000000000000000000000000000","initCode":"0xf0C1dab676AE40CFA72C85A4805B0E711A29827Fea6d13ac000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000bd4c9e797a8dbbfdde9c77bc5a5b21acf611db8f0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020441bede0300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000142DcC3C0c49Bf7c0b095F7B7cd7cef30e2c9279050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","callData":"0xe9ae5c53000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000034f5715961c550fc497832063a98ea34673ad7c8160000000000000000000000000000000000000000000000000000000000000001000000000000000000000000","accountGasLimits":"0x000000000000000000000000004c4b40000000000000000000000000004c4b40","preVerificationGas":"5000000","gasFees":"0x0000000000000000000000000000000100000000000000000000000000000001","paymasterAndData":"0x1870F688591aD27Cb5506A3F1a6675294649668d00000000000000000030783761313230000000000000000030783136653336300000000000000000000000001870f688591ad27cb5506a3f1a6675294649668d","signature":"0x81d4b4981670cb18f99f0b4a66446df1bf5b204d24cfcb659bf38ba27a4359b5711649ec2423c5e1247245eba2964679b6a1dbb85c992ae40b9b00c6935b02ff1b"}
module: "src/common/simulation/BundlerSimulationService.v7.ts"
The two paymaster gas limits in the 'userOp received' are 0x16e360 (1.5M) and 0x7a120 (500k). The 'Packed User Operation' contains:
"paymasterAndData":"0x1870F688591aD27Cb5506A3F1a6675294649668d00000000000000000030783761313230000000000000000030783136653336300000000000000000000000001870f688591ad27cb5506a3f1a6675294649668d"
with encoded limits of: 30783761313230 and 3078313665333630.
The encoded limits are in fact the ascii representations of the strings 0x7a120 and 0x16e360 respectively.
Cause:
The v3 handler, passes the userOp to the simulator unchecked. The simulator (BundlerSimulationServiceV07) expects the userOp to be type constrained, with the limits expected to be of BigInt type, not hex strings. The simulator uses a gas estimator from the entry-point-gas-estimations library, which packs the user operation using helper functions from it's utils. These helper functions treat all strings as text and convert the limits to ascii.
bundler v1.0.0
abstractjs v1.0.13
abstractjs (via viem and account-abstraction) formats outgoing requests to the bundler, encoding any numeric literals to hex strings. The bundler, on receiving a request, does not reverse the formatting, instead passing the user op unchecked to the request method handler. This can cause valid userOps to be misinterpreted by the application.
An example of this problem is when sending a transaction with a custom paymaster configured in abstractjs'
createSmartAccountClient. The gas limits - numeric literals - returned by the paymaster'sgetPaymasterDatamethod get converted to hex-strings before being sent to the bundler to estimate user operation gas. In the bundler, the gas estimator constructs the packed user op and in the process incorrectly converts the hex-string limits to ascii - huge numbers that cause gas estimation to incorrectly report insufficient funds.Fortunately, custom paymasters have the option of returning pre-encoded
paymasterAndDataso this specific example can be worked around.Detailed example:
Consider the following paymaster client and bundler log...
The two paymaster gas limits in the 'userOp received' are
0x16e360(1.5M) and0x7a120(500k). The 'Packed User Operation' contains:"paymasterAndData":"0x1870F688591aD27Cb5506A3F1a6675294649668d00000000000000000030783761313230000000000000000030783136653336300000000000000000000000001870f688591ad27cb5506a3f1a6675294649668d"with encoded limits of:
30783761313230and3078313665333630.The encoded limits are in fact the ascii representations of the strings
0x7a120and0x16e360respectively.Cause:
The
v3 handler, passes the userOp to the simulator unchecked. The simulator (BundlerSimulationServiceV07) expects the userOp to be type constrained, with the limits expected to be of BigInt type, not hex strings. The simulator uses a gas estimator from theentry-point-gas-estimationslibrary, which packs the user operation using helper functions from it's utils. These helper functions treat all strings as text and convert the limits to ascii.