Skip to content

Commit

Permalink
feat: implement
Browse files Browse the repository at this point in the history
  • Loading branch information
kopy-kat committed Aug 23, 2024
1 parent f37a40e commit e04c69c
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 13 deletions.
10 changes: 9 additions & 1 deletion src/test/ModuleKitHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,15 @@ library ModuleKitHelpers {
//////////////////////////////////////////////////////////////////////////*/

function expect4337Revert(AccountInstance memory) internal {
writeExpectRevert(1);
writeExpectRevert("");
}

function expect4337Revert(AccountInstance memory, bytes4 selector) internal {
writeExpectRevert(abi.encodePacked(selector));
}

function expect4337Revert(AccountInstance memory, bytes memory message) internal {
writeExpectRevert(message);
}

/**
Expand Down
36 changes: 32 additions & 4 deletions src/test/utils/ERC4337Helpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { GasParser } from "./gas/GasParser.sol";
import {
getSimulateUserOp,
getExpectRevert,
writeExpectRevert,
getExpectRevertMessage,
clearExpectRevert,
getGasIdentifier,
writeGasIdentifier,
writeInstalledModule,
Expand All @@ -25,12 +26,16 @@ import {
InstalledModule
} from "./Storage.sol";

import "forge-std/console2.sol";

library ERC4337Helpers {
using Simulator for PackedUserOperation;

error UserOperationReverted(
bytes32 userOpHash, address sender, uint256 nonce, bytes revertReason
);
error InvalidRevertMessage(bytes4 expected, bytes4 reason);
error InvalidRevertMessageBytes(bytes expected, bytes reason);

function exec4337(PackedUserOperation[] memory userOps, IEntryPoint onEntryPoint) internal {
uint256 isExpectRevert = getExpectRevert();
Expand All @@ -49,10 +54,12 @@ library ERC4337Helpers {
// Execute userOps
address payable beneficiary = payable(address(0x69));
bytes memory userOpCalldata = abi.encodeCall(IEntryPoint.handleOps, (userOps, beneficiary));
(bool success,) = address(onEntryPoint).call(userOpCalldata);
(bool success, bytes memory returnData) = address(onEntryPoint).call(userOpCalldata);

if (isExpectRevert == 0) {
require(success, "UserOperation execution failed");
} else if (isExpectRevert == 2 && !success) {
checkRevertMessage(returnData);
}

// Parse logs and determine if a revert happened
Expand All @@ -75,7 +82,10 @@ library ERC4337Helpers {
userOpHash, address(bytes20(logs[i].topics[2])), nonce, revertReason
);
} else {
writeExpectRevert(0);
if (isExpectRevert == 2) {
checkRevertMessage(getUserOpRevertReason(logs, bytes32(0)));
}
clearExpectRevert();
}
}
}
Expand Down Expand Up @@ -115,7 +125,7 @@ library ERC4337Helpers {
require(!success, "UserOperation execution did not fail as expected");
}
}
writeExpectRevert(0);
clearExpectRevert();

// Calculate gas for userOp
string memory gasIdentifier = getGasIdentifier();
Expand Down Expand Up @@ -156,6 +166,24 @@ library ERC4337Helpers {
}
}

function checkRevertMessage(bytes memory actualReason) internal view {
bytes memory revertMessage = getExpectRevertMessage();
console2.logBytes(revertMessage);
console2.logBytes(actualReason);

if (revertMessage.length == 4) {
bytes4 expected = bytes4(revertMessage);
bytes4 actual = bytes4(actualReason);
if (expected != actual) {
revert InvalidRevertMessage(expected, actual);
}
} else {
if (revertMessage.length != actualReason.length) {
revert InvalidRevertMessageBytes(revertMessage, actualReason);
}
}
}

function calculateGas(
PackedUserOperation[] memory userOps,
IEntryPoint onEntryPoint,
Expand Down
33 changes: 31 additions & 2 deletions src/test/utils/Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@ pragma solidity ^0.8.23;
EXPECT REVERT
//////////////////////////////////////////////////////////////*/

function writeExpectRevert(uint256 value) {
bytes32 slot = keccak256("ModuleKit.ExpectSlot");
function writeExpectRevert(bytes memory message) {
uint256 value = 1;
bytes32 slot = keccak256("ModuleKit.ExpectMessageSlot");

if (message.length > 0) {
value = 2;
assembly {
sstore(slot, message)
}
}

slot = keccak256("ModuleKit.ExpectSlot");
assembly {
sstore(slot, value)
}
Expand All @@ -19,6 +29,25 @@ function getExpectRevert() view returns (uint256 value) {
}
}

function getExpectRevertMessage() view returns (bytes memory data) {
bytes32 slot = keccak256("ModuleKit.ExpectMessageSlot");
assembly {
data := sload(slot)
}
}

function clearExpectRevert() {
bytes32 slot = keccak256("ModuleKit.ExpectSlot");
assembly {
sstore(slot, 0)
}

slot = keccak256("ModuleKit.ExpectMessageSlot");
assembly {
sstore(slot, 0)
}
}

/*//////////////////////////////////////////////////////////////
GAS IDENTIFIER
//////////////////////////////////////////////////////////////*/
Expand Down
23 changes: 17 additions & 6 deletions test/Diff.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,22 @@ contract ERC7579DifferentialModuleKitLibTest is BaseTest {
_revertWhen__ValidationFails("");

// Revert selector
_revertWhen__ValidationReverts(abi.encodePacked(bytes4(0x65c8fd4d)));

// Revert message
_revertWhen__ValidationReverts(
abi.encodeWithSignature(
"FailedOpWithRevert(uint256,string,bytes)", 0, "AA23 reverted", ""
)
);
}

function testexec__RevertWhen__ValidationReverts() public {
// No revert reason
_revertWhen__ValidationReverts("");

// Revert selector
_revertWhen__ValidationReverts(abi.encodePacked(bytes4(hex"ffffffff")));

// Revert message
}
Expand All @@ -125,8 +132,12 @@ contract ERC7579DifferentialModuleKitLibTest is BaseTest {
_revertWhen__UserOperationFails("");

// Revert selector
_revertWhen__UserOperationFails(abi.encodePacked(bytes4(0x08c379a0)));

// Revert message
_revertWhen__UserOperationFails(
abi.encodeWithSignature("Error(string)", "MockTarget: not authorized")
);
}

/*//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -595,9 +606,9 @@ contract ERC7579DifferentialModuleKitLibTest is BaseTest {
if (revertReason.length == 0) {
instance.expect4337Revert();
} else if (revertReason.length == 4) {
instance.expect4337Revert();
instance.expect4337Revert(bytes4(revertReason));
} else {
instance.expect4337Revert();
instance.expect4337Revert(revertReason);
}

// Create userOperation
Expand Down Expand Up @@ -630,9 +641,9 @@ contract ERC7579DifferentialModuleKitLibTest is BaseTest {
if (revertReason.length == 0) {
instance.expect4337Revert();
} else if (revertReason.length == 4) {
instance.expect4337Revert();
instance.expect4337Revert(bytes4(revertReason));
} else {
instance.expect4337Revert();
instance.expect4337Revert(revertReason);
}

// Create userOperation
Expand All @@ -652,9 +663,9 @@ contract ERC7579DifferentialModuleKitLibTest is BaseTest {
if (revertReason.length == 0) {
instance.expect4337Revert();
} else if (revertReason.length == 4) {
instance.expect4337Revert();
instance.expect4337Revert(bytes4(revertReason));
} else {
instance.expect4337Revert();
instance.expect4337Revert(revertReason);
}

// Create userOperation
Expand Down

0 comments on commit e04c69c

Please sign in to comment.