Skip to content

Commit

Permalink
Merge pull request #293 from leekt/develop
Browse files Browse the repository at this point in the history
fix EntryPoint revert if 'postOp' reverts with short revert reason
  • Loading branch information
forshtat authored Jun 25, 2023
2 parents 10f0502 + 8116f81 commit 74a3c37
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 15 deletions.
7 changes: 5 additions & 2 deletions contracts/core/EntryPoint.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard
} catch {
bytes32 innerRevertCode;
assembly {
returndatacopy(0, 0, 32)
innerRevertCode := mload(0)
let len := returndatasize()
if eq(32,len) {
returndatacopy(0, 0, 32)
innerRevertCode := mload(0)
}
}
// handleOps was called with gas limit too low. abort entire bundle.
if (innerRevertCode == INNER_OUT_OF_GAS) {
Expand Down
30 changes: 30 additions & 0 deletions contracts/test/TestPaymasterRevertCustomError.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.12;

import "../core/BasePaymaster.sol";

/**
* test postOp revert with custom error
*/
error CustomError();

contract TestPaymasterRevertCustomError is BasePaymaster {
// solhint-disable no-empty-blocks
constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint)
{}

function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32, uint256)
internal virtual override view
returns (bytes memory context, uint256 validationData) {
validationData = 0;
context = abi.encodePacked(userOp.sender);
}

function _postOp(PostOpMode mode, bytes calldata, uint256) internal override {
if(mode == PostOpMode.postOpReverted) {
return;
}

revert CustomError();
}
}
24 changes: 12 additions & 12 deletions reports/gas-checker.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,28 @@
║ │ │ │ (delta for │ (compared to ║
║ │ │ │ one UserOp) │ account.exec()) ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple │ 1 │ 81913 │ │ ║
║ simple │ 1 │ 81921 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple - diff from previous │ 2 │ │ 4420015186
║ simple - diff from previous │ 2 │ │ 4420815194
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple │ 10 │ 479770 │ │ ║
║ simple │ 10 │ 479922 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple - diff from previous │ 11 │ │ 4427215258
║ simple - diff from previous │ 11 │ │ 4424415230
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster │ 1 │ 88196 │ │ ║
║ simple paymaster │ 1 │ 88192 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster with diff │ 2 │ │ 4318914175
║ simple paymaster with diff │ 2 │ │ 4319714183
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster │ 10 │ 477078 │ │ ║
║ simple paymaster │ 10 │ 477170 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ simple paymaster with diff │ 11 │ │ 4320014186
║ simple paymaster with diff │ 11 │ │ 4322014206
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx 5k │ 1 │ 182970 │ │ ║
║ big tx 5k │ 1 │ 182978 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx - diff from previous │ 2 │ │ 14471119451
║ big tx - diff from previous │ 2 │ │ 14468319423
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx 5k │ 10 │ 1485498 │ │ ║
║ big tx 5k │ 10 │ 1485506 │ │ ║
╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
║ big tx - diff from previous │ 11 │ │ 14474819488
║ big tx - diff from previous │ 11 │ │ 14474419484
╚════════════════════════════════╧═══════╧═══════════════╧════════════════╧═════════════════════╝

21 changes: 20 additions & 1 deletion test/entrypoint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import {
TestSignatureAggregator,
TestSignatureAggregator__factory,
MaliciousAccount__factory,
TestWarmColdAccount__factory
TestWarmColdAccount__factory,
TestPaymasterRevertCustomError__factory
} from '../typechain'
import {
AddressZero,
Expand Down Expand Up @@ -1171,6 +1172,24 @@ describe('EntryPoint', function () {
await expect(entryPoint.handleOps([op], beneficiaryAddress)).to.revertedWith('"AA31 paymaster deposit too low"')
})

it('should not revert when paymaster reverts with custom error on postOp', async function () {
const account3Owner = createAccountOwner()
const errorPostOp = await new TestPaymasterRevertCustomError__factory(ethersSigner).deploy(entryPoint.address)
await errorPostOp.addStake(globalUnstakeDelaySec, { value: paymasterStake })
await errorPostOp.deposit({ value: ONE_ETH })

const op = await fillAndSign({
paymasterAndData: errorPostOp.address,
callData: accountExecFromEntryPoint.data,
initCode: getAccountInitCode(account3Owner.address, simpleAccountFactory),

verificationGasLimit: 3e6,
callGasLimit: 1e6
}, account3Owner, entryPoint)
const beneficiaryAddress = createAddress()
await entryPoint.handleOps([op], beneficiaryAddress)
})

it('paymaster should pay for tx', async function () {
await paymaster.deposit({ value: ONE_ETH })
const op = await fillAndSign({
Expand Down

0 comments on commit 74a3c37

Please sign in to comment.