From dfb252de3f552d3e600a6a646733b21110aace57 Mon Sep 17 00:00:00 2001 From: zeroknots Date: Tue, 20 Feb 2024 15:22:52 +0700 Subject: [PATCH] feat: implemented safe hook --- .gitignore | 2 +- accounts/safe7579/src/SafeERC7579.sol | 10 +--------- .../safe7579/src/core/ExecutionHelper.sol | 2 +- accounts/safe7579/src/core/HookManager.sol | 19 +++++++++++++++++-- accounts/safe7579/src/core/ModuleManager.sol | 3 ++- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 63d07405..f0620b6b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ out/ /broadcast/*/31337/ /broadcast/**/dry-run/ -gas_calculations/*.json +packages/modulekit/gas_calculations/*.json # Docs docs/ diff --git a/accounts/safe7579/src/SafeERC7579.sol b/accounts/safe7579/src/SafeERC7579.sol index 6cb3f374..d1f563e4 100644 --- a/accounts/safe7579/src/SafeERC7579.sol +++ b/accounts/safe7579/src/SafeERC7579.sol @@ -16,7 +16,6 @@ import { } from "erc7579/interfaces/IERC7579Module.sol"; import { AccessControl } from "./core/AccessControl.sol"; import { HookManager } from "./core/HookManager.sol"; -import { ExecutionHelper } from "./core/ExecutionHelper.sol"; import { ISafeOp, SAFE_OP_TYPEHASH } from "./interfaces/ISafeOp.sol"; import { ISafe } from "./interfaces/ISafe.sol"; import { @@ -33,14 +32,7 @@ import "forge-std/console2.sol"; * this contract creates full ERC7579 compliance to Safe accounts * @author zeroknots.eth | rhinestone.wtf */ -contract SafeERC7579 is - ISafeOp, - IERC7579Account, - AccessControl, - ExecutionHelper, - IMSA, - HookManager -{ +contract SafeERC7579 is ISafeOp, IERC7579Account, AccessControl, IMSA, HookManager { using UserOperationLib for PackedUserOperation; using ModeLib for ModeCode; using ExecutionLib for bytes; diff --git a/accounts/safe7579/src/core/ExecutionHelper.sol b/accounts/safe7579/src/core/ExecutionHelper.sol index 727f6a05..501b5873 100644 --- a/accounts/safe7579/src/core/ExecutionHelper.sol +++ b/accounts/safe7579/src/core/ExecutionHelper.sol @@ -21,7 +21,7 @@ contract ExecutionHelper { address safe, address target, uint256 value, - bytes calldata callData + bytes memory callData ) internal returns (bytes memory returnData) diff --git a/accounts/safe7579/src/core/HookManager.sol b/accounts/safe7579/src/core/HookManager.sol index 253001ac..c5c5eff2 100644 --- a/accounts/safe7579/src/core/HookManager.sol +++ b/accounts/safe7579/src/core/HookManager.sol @@ -29,9 +29,24 @@ abstract contract HookManager is ModuleManager { if (hook == address(0)) { _; } else { - bytes memory hookData = IHook(hook).preCheck(_msgSender(), msg.data); + bytes memory retData = _executeReturnData({ + safe: msg.sender, + target: hook, + value: 0, + callData: abi.encodeCall(IHook.preCheck, (_msgSender(), msg.data)) + }); + bytes memory hookPreContext = abi.decode(retData, (bytes)); + _; - if (!IHook(hook).postCheck(hookData)) revert HookPostCheckFailed(); + retData = _executeReturnData({ + safe: msg.sender, + target: hook, + value: 0, + callData: abi.encodeCall(IHook.postCheck, (hookPreContext)) + }); + bool success = abi.decode(retData, (bool)); + + if (!success) revert HookPostCheckFailed(); } } diff --git a/accounts/safe7579/src/core/ModuleManager.sol b/accounts/safe7579/src/core/ModuleManager.sol index 05084f77..b25047de 100644 --- a/accounts/safe7579/src/core/ModuleManager.sol +++ b/accounts/safe7579/src/core/ModuleManager.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.23; import { SentinelListLib, SENTINEL } from "sentinellist/SentinelList.sol"; import { IExecutor, IValidator, IFallback } from "erc7579/interfaces/IERC7579Module.sol"; +import { ExecutionHelper } from "./ExecutionHelper.sol"; import { Receiver } from "erc7579/core/Receiver.sol"; import { AccessControl } from "./AccessControl.sol"; import { ISafe } from "../interfaces/ISafe.sol"; @@ -27,7 +28,7 @@ bytes32 constant MODULEMANAGER_STORAGE_LOCATION = * Contract that implements ERC7579 Module compatibility for Safe accounts * @author zeroknots.eth | rhinestone.wtf */ -abstract contract ModuleManager is AccessControl, Receiver { +abstract contract ModuleManager is AccessControl, Receiver, ExecutionHelper { using SentinelListLib for SentinelListLib.SentinelList; using ValidatorStorageLib for SentinelListLib.SentinelList;