Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: restructure and clean up #123

Merged
merged 1 commit into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/test/Auxiliary.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { IEntryPointSimulations } from
"@ERC4337/account-abstraction/contracts/interfaces/IEntryPointSimulations.sol";
import { etchRegistry } from "./predeploy/Registry.sol";
import { MockFactory } from "./predeploy/MockFactory.sol";
import { UserOpGasLog } from "./utils/UserOpGasLog.sol";
import { UserOpGasLog } from "./utils/gas/UserOpGasLog.sol";
import "./utils/Vm.sol";
import "./utils/Log.sol";

Expand Down
225 changes: 111 additions & 114 deletions src/test/ModuleKitHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,109 @@
pragma solidity ^0.8.23;

import { AccountInstance, UserOpData } from "./RhinestoneModuleKit.sol";
import { IEntryPoint } from "../external/ERC4337.sol";
import { ModuleKitUserOp } from "./ModuleKitUserOp.sol";
import { ERC4337Helpers } from "./utils/ERC4337Helpers.sol";
import { writeExpectRevert, writeGasIdentifier } from "./utils/Log.sol";
import "./utils/Vm.sol";
import { HelperBase } from "./helpers/HelperBase.sol";
import { Execution } from "../external/ERC7579.sol";

library ModuleKitHelpers {
using ModuleKitHelpers for AccountInstance;
using ModuleKitHelpers for UserOpData;

/*//////////////////////////////////////////////////////////////////////////
EXECUTIONS
//////////////////////////////////////////////////////////////////////////*/

function execUserOps(UserOpData memory userOpData) internal {
// send userOp to entrypoint
ERC4337Helpers.exec4337(userOpData.userOp, userOpData.entrypoint);
}

function signDefault(UserOpData memory userOpData) internal pure returns (UserOpData memory) {
userOpData.userOp.signature = "DEFAULT SIGNATURE";
return userOpData;
function getExecOps(
AccountInstance memory instance,
address target,
uint256 value,
bytes memory callData,
address txValidator
)
internal
returns (UserOpData memory userOpData)
{
bytes memory erc7579ExecCall =
HelperBase(instance.accountHelper).encode(target, value, callData);
(userOpData.userOp, userOpData.userOpHash) = HelperBase(instance.accountHelper).execUserOp({
instance: instance,
callData: erc7579ExecCall,
txValidator: txValidator
});
userOpData.entrypoint = instance.aux.entrypoint;
}

function getExecOps(
AccountInstance memory instance,
Execution[] memory executions,
address txValidator
)
internal
returns (UserOpData memory userOpData)
{
bytes memory erc7579ExecCall = HelperBase(instance.accountHelper).encode(executions);
(userOpData.userOp, userOpData.userOpHash) = HelperBase(instance.accountHelper).execUserOp({
instance: instance,
callData: erc7579ExecCall,
txValidator: txValidator
});
userOpData.entrypoint = instance.aux.entrypoint;
}

function exec(
AccountInstance memory instance,
address target,
uint256 value,
bytes memory callData
)
internal
returns (UserOpData memory userOpData)
{
userOpData =
instance.getExecOps(target, value, callData, address(instance.defaultValidator));
// sign userOp with default signature
userOpData = userOpData.signDefault();
userOpData.entrypoint = instance.aux.entrypoint;
// send userOp to entrypoint
userOpData.execUserOps();
}

function exec(
AccountInstance memory instance,
address target,
bytes memory callData
)
internal
returns (UserOpData memory userOpData)
{
return exec(instance, target, 0, callData);
}

function deployAccount(AccountInstance memory instance) internal {
if (instance.account.code.length == 0) {
if (instance.initCode.length == 0) {
revert("deployAccount: no initCode provided");
} else {
bytes memory initCode = instance.initCode;
assembly {
let factory := mload(add(initCode, 20))
let success := call(gas(), factory, 0, add(initCode, 52), mload(initCode), 0, 0)
if iszero(success) { revert(0, 0) }
}
}
}
}

/*//////////////////////////////////////////////////////////////////////////
MODULE CONFIG
//////////////////////////////////////////////////////////////////////////*/

function installModule(
AccountInstance memory instance,
uint256 moduleTypeId,
Expand Down Expand Up @@ -90,66 +171,6 @@ library ModuleKitHelpers {
);
}

function exec(
AccountInstance memory instance,
address target,
uint256 value,
bytes memory callData
)
internal
returns (UserOpData memory userOpData)
{
userOpData =
instance.getExecOps(target, value, callData, address(instance.defaultValidator));
// sign userOp with default signature
userOpData = userOpData.signDefault();
userOpData.entrypoint = instance.aux.entrypoint;
// send userOp to entrypoint
userOpData.execUserOps();
}

function exec(
AccountInstance memory instance,
address target,
bytes memory callData
)
internal
returns (UserOpData memory userOpData)
{
return exec(instance, target, 0, callData);
}

function deployAccount(AccountInstance memory instance) internal {
if (instance.account.code.length == 0) {
if (instance.initCode.length == 0) {
revert("deployAccount: no initCode provided");
} else {
bytes memory initCode = instance.initCode;
assembly {
let factory := mload(add(initCode, 20))
let success := call(gas(), factory, 0, add(initCode, 52), mload(initCode), 0, 0)
if iszero(success) { revert(0, 0) }
}
}
}
}

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

/**
* @dev Logs the gas used by an ERC-4337 transaction
* @dev needs to be called before an exec4337 call
* @dev the id needs to be unique across your tests, otherwise the gas calculations will
* overwrite each other
*
* @param id Identifier for the gas calculation, which will be used as the filename
*/
function log4337Gas(AccountInstance memory, /* instance */ string memory id) internal {
writeGasIdentifier(id);
}

function getInstallModuleData(
AccountInstance memory instance,
uint256 moduleTypeId,
Expand Down Expand Up @@ -226,56 +247,32 @@ library ModuleKitHelpers {
userOpData.entrypoint = instance.aux.entrypoint;
}

function getExecOps(
AccountInstance memory instance,
address target,
uint256 value,
bytes memory callData,
address txValidator
)
internal
returns (UserOpData memory userOpData)
{
bytes memory erc7579ExecCall =
HelperBase(instance.accountHelper).encode(target, value, callData);
(userOpData.userOp, userOpData.userOpHash) = HelperBase(instance.accountHelper).execUserOp({
instance: instance,
callData: erc7579ExecCall,
txValidator: txValidator
});
userOpData.entrypoint = instance.aux.entrypoint;
/*//////////////////////////////////////////////////////////////////////////
CONTROL FLOW
//////////////////////////////////////////////////////////////////////////*/

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

function getExecOps(
AccountInstance memory instance,
Execution[] memory executions,
address txValidator
)
internal
returns (UserOpData memory userOpData)
{
bytes memory erc7579ExecCall = HelperBase(instance.accountHelper).encode(executions);
(userOpData.userOp, userOpData.userOpHash) = HelperBase(instance.accountHelper).execUserOp({
instance: instance,
callData: erc7579ExecCall,
txValidator: txValidator
});
userOpData.entrypoint = instance.aux.entrypoint;
/**
* @dev Logs the gas used by an ERC-4337 transaction
* @dev needs to be called before an exec4337 call
* @dev the id needs to be unique across your tests, otherwise the gas calculations will
* overwrite each other
*
* @param id Identifier for the gas calculation, which will be used as the filename
*/
function log4337Gas(AccountInstance memory, /* instance */ string memory id) internal {
writeGasIdentifier(id);
}

// function getExecOps(
// AccountInstance memory instance,
// address[] memory targets,
// uint256[] memory values,
// bytes[] memory callDatas,
// address txValidator
// )
// internal
// view
// returns (UserOpData memory userOpData)
// {
// Execution[] memory executions =
// HelperBase(instance.accountHelper).toExecutions(targets, values, callDatas);
// return getExecOps(instance, executions, txValidator);
// }
/*//////////////////////////////////////////////////////////////////////////
UTILS
//////////////////////////////////////////////////////////////////////////*/

function signDefault(UserOpData memory userOpData) internal pure returns (UserOpData memory) {
userOpData.userOp.signature = "DEFAULT SIGNATURE";
return userOpData;
}
}
49 changes: 29 additions & 20 deletions src/test/RhinestoneModuleKit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ import { ERC7579Helpers } from "./helpers/ERC7579Helpers.sol";
import { SafeHelpers } from "./helpers/SafeHelpers.sol";
import { KernelHelpers } from "./helpers/KernelHelpers.sol";
import { Auxiliary, AuxiliaryFactory } from "./Auxiliary.sol";
import { PackedUserOperation, IStakeManager } from "../external/ERC4337.sol";
import { PackedUserOperation, IStakeManager, IEntryPoint } from "../external/ERC4337.sol";
import { ENTRYPOINT_ADDR } from "./predeploy/EntryPoint.sol";
import { IERC7579Validator } from "../external/ERC7579.sol";
import { MockValidator } from "../Mocks.sol";
import { IEntryPoint } from "../external/ERC4337.sol";

enum AccountType {
DEFAULT,
Expand Down Expand Up @@ -46,6 +45,10 @@ string constant KERNEL = "KERNEL";
string constant CUSTOM = "CUSTOM";

contract RhinestoneModuleKit is AuxiliaryFactory {
/*//////////////////////////////////////////////////////////////////////////
CONSTANTS & STORAGE
//////////////////////////////////////////////////////////////////////////*/

bool internal isInit;
MockValidator public _defaultValidator;

Expand All @@ -64,6 +67,10 @@ contract RhinestoneModuleKit is AuxiliaryFactory {

error InvalidAccountType();

/*//////////////////////////////////////////////////////////////////////////
SETUP
//////////////////////////////////////////////////////////////////////////*/

/**
* Initializes Auxiliary and /src/core
* This function will run before any accounts can be created
Expand Down Expand Up @@ -131,6 +138,10 @@ contract RhinestoneModuleKit is AuxiliaryFactory {
_;
}

/*//////////////////////////////////////////////////////////////////////////
MAKE INSTANCE
//////////////////////////////////////////////////////////////////////////*/

function makeAccountInstance(
bytes32 salt,
address account,
Expand All @@ -155,11 +166,6 @@ contract RhinestoneModuleKit is AuxiliaryFactory {
setAccountType(AccountType.CUSTOM);
}

/**
* create new AccountInstance with modulekit defaults
*
* @param salt account salt / name
*/
function makeAccountInstance(
bytes32 salt,
address account,
Expand All @@ -177,11 +183,6 @@ contract RhinestoneModuleKit is AuxiliaryFactory {
});
}

/**
* create new AccountInstance with modulekit defaults
*
* @param salt account salt / name
*/
function makeAccountInstance(bytes32 salt)
internal
initializeModuleKit
Expand Down Expand Up @@ -230,6 +231,22 @@ contract RhinestoneModuleKit is AuxiliaryFactory {
setAccountType(AccountType.CUSTOM);
}

/*//////////////////////////////////////////////////////////////////////////
ACCOUNT TYPE
//////////////////////////////////////////////////////////////////////////*/

function setAccountType(AccountType _env) public {
env = _env;
}

function getAccountType() public view returns (AccountType) {
return env;
}

/*//////////////////////////////////////////////////////////////////////////
INTERNAL
//////////////////////////////////////////////////////////////////////////*/

function _makeAccountInstance(
bytes32 salt,
address account,
Expand All @@ -251,12 +268,4 @@ contract RhinestoneModuleKit is AuxiliaryFactory {
initCode: initCode
});
}

function setAccountType(AccountType _env) public {
env = _env;
}

function getAccountType() public view returns (AccountType) {
return env;
}
}
Loading
Loading