Skip to content

Commit

Permalink
refactor: move FunctionReference to IPluginManager
Browse files Browse the repository at this point in the history
  • Loading branch information
jaypaik committed Jan 23, 2024
1 parent c5e9fb3 commit 7aa1170
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 50 deletions.
5 changes: 2 additions & 3 deletions src/account/AccountLoupe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeab
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {AccountStorage, getAccountStorage, HookGroup, toFunctionReferenceArray} from "./AccountStorage.sol";
import {FunctionReference} from "../helpers/FunctionReferenceLib.sol";
import {IAccountLoupe} from "../interfaces/IAccountLoupe.sol";
import {IPluginManager} from "../interfaces/IPluginManager.sol";
import {FunctionReference, IPluginManager} from "../interfaces/IPluginManager.sol";
import {IStandardExecutor} from "../interfaces/IStandardExecutor.sol";
import {AccountStorage, getAccountStorage, HookGroup, toFunctionReferenceArray} from "./AccountStorage.sol";

abstract contract AccountLoupe is IAccountLoupe {
using EnumerableMap for EnumerableMap.Bytes32ToUintMap;
Expand Down
2 changes: 1 addition & 1 deletion src/account/AccountStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pragma solidity ^0.8.19;
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {FunctionReference} from "../helpers/FunctionReferenceLib.sol";
import {IPlugin} from "../interfaces/IPlugin.sol";
import {FunctionReference} from "../interfaces/IPluginManager.sol";

// bytes = keccak256("ERC6900.UpgradeableModularAccount.Storage")
bytes32 constant _ACCOUNT_STORAGE_SLOT = 0x9f09680beaa4e5c9f38841db2460c401499164f368baef687948c315d9073e40;
Expand Down
23 changes: 12 additions & 11 deletions src/account/PluginManagerInternals.sol
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.19;

import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";

import {
AccountStorage,
getAccountStorage,
SelectorData,
getPermittedCallKey,
HookGroup,
PermittedExternalCallData
} from "./AccountStorage.sol";
import {FunctionReference, FunctionReferenceLib} from "../helpers/FunctionReferenceLib.sol";
import {IPluginManager} from "../interfaces/IPluginManager.sol";
import {FunctionReferenceLib} from "../helpers/FunctionReferenceLib.sol";
import {
IPlugin,
ManifestExecutionHook,
Expand All @@ -24,10 +15,20 @@ import {
ManifestExternalCallPermission,
PluginManifest
} from "../interfaces/IPlugin.sol";
import {FunctionReference, IPluginManager} from "../interfaces/IPluginManager.sol";
import {
AccountStorage,
getAccountStorage,
SelectorData,
getPermittedCallKey,
HookGroup,
PermittedExternalCallData
} from "./AccountStorage.sol";

abstract contract PluginManagerInternals is IPluginManager {
using EnumerableMap for EnumerableMap.Bytes32ToUintMap;
using EnumerableSet for EnumerableSet.AddressSet;
using FunctionReferenceLib for FunctionReference;

error ArrayLengthMismatch();
error ExecutionFunctionAlreadySet(bytes4 selector);
Expand Down
23 changes: 12 additions & 11 deletions src/account/UpgradeableModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
pragma solidity ^0.8.19;

import {BaseAccount} from "@eth-infinitism/account-abstraction/core/BaseAccount.sol";
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {UserOperation} from "@eth-infinitism/account-abstraction/interfaces/UserOperation.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {FunctionReferenceLib} from "../helpers/FunctionReferenceLib.sol";
import {_coalescePreValidation, _coalesceValidation} from "../helpers/ValidationDataHelpers.sol";
import {IPlugin, PluginManifest} from "../interfaces/IPlugin.sol";
import {IPluginExecutor} from "../interfaces/IPluginExecutor.sol";
import {FunctionReference, IPluginManager} from "../interfaces/IPluginManager.sol";
import {IStandardExecutor, Call} from "../interfaces/IStandardExecutor.sol";
import {AccountExecutor} from "./AccountExecutor.sol";
import {AccountLoupe} from "./AccountLoupe.sol";
import {AccountStorage, HookGroup, getAccountStorage, getPermittedCallKey} from "./AccountStorage.sol";
import {AccountStorageInitializable} from "./AccountStorageInitializable.sol";
import {FunctionReference, FunctionReferenceLib} from "../helpers/FunctionReferenceLib.sol";
import {IPlugin, PluginManifest} from "../interfaces/IPlugin.sol";
import {IPluginExecutor} from "../interfaces/IPluginExecutor.sol";
import {IPluginManager} from "../interfaces/IPluginManager.sol";
import {IStandardExecutor, Call} from "../interfaces/IStandardExecutor.sol";
import {PluginManagerInternals} from "./PluginManagerInternals.sol";
import {_coalescePreValidation, _coalesceValidation} from "../helpers/ValidationDataHelpers.sol";

contract UpgradeableModularAccount is
AccountExecutor,
Expand All @@ -34,6 +34,7 @@ contract UpgradeableModularAccount is
{
using EnumerableMap for EnumerableMap.Bytes32ToUintMap;
using EnumerableSet for EnumerableSet.Bytes32Set;
using FunctionReferenceLib for FunctionReference;

struct PostExecToRun {
bytes preExecHookReturnData;
Expand Down Expand Up @@ -437,7 +438,7 @@ contract UpgradeableModularAccount is
++i;
}
} else {
if (preRuntimeValidationHook == FunctionReferenceLib._PRE_HOOK_ALWAYS_DENY) {
if (preRuntimeValidationHook.eq(FunctionReferenceLib._PRE_HOOK_ALWAYS_DENY)) {
revert AlwaysDenyRule();
}
// Function reference cannot be 0 or _RUNTIME_VALIDATION_ALWAYS_ALLOW.
Expand All @@ -457,7 +458,7 @@ contract UpgradeableModularAccount is
} else {
if (runtimeValidationFunction.isEmpty()) {
revert RuntimeValidationFunctionMissing(msg.sig);
} else if (runtimeValidationFunction == FunctionReferenceLib._PRE_HOOK_ALWAYS_DENY) {
} else if (runtimeValidationFunction.eq(FunctionReferenceLib._PRE_HOOK_ALWAYS_DENY)) {
revert InvalidConfiguration();
}
// If _RUNTIME_VALIDATION_ALWAYS_ALLOW, just let the function finish.
Expand Down
19 changes: 8 additions & 11 deletions src/helpers/FunctionReferenceLib.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.19;

type FunctionReference is bytes21;

using {eq as ==, notEq as !=} for FunctionReference global;
using FunctionReferenceLib for FunctionReference global;
import {FunctionReference} from "../interfaces/IPluginManager.sol";

library FunctionReferenceLib {
// Empty or unset function reference.
Expand All @@ -26,18 +23,18 @@ library FunctionReferenceLib {
}

function isEmpty(FunctionReference fr) internal pure returns (bool) {
return fr == _EMPTY_FUNCTION_REFERENCE;
return FunctionReference.unwrap(fr) == bytes21(0);
}

function isEmptyOrMagicValue(FunctionReference fr) internal pure returns (bool) {
return FunctionReference.unwrap(fr) <= bytes21(uint168(2));
}
}

function eq(FunctionReference a, FunctionReference b) pure returns (bool) {
return FunctionReference.unwrap(a) == FunctionReference.unwrap(b);
}
function eq(FunctionReference a, FunctionReference b) internal pure returns (bool) {
return FunctionReference.unwrap(a) == FunctionReference.unwrap(b);
}

function notEq(FunctionReference a, FunctionReference b) pure returns (bool) {
return FunctionReference.unwrap(a) != FunctionReference.unwrap(b);
function notEq(FunctionReference a, FunctionReference b) internal pure returns (bool) {
return FunctionReference.unwrap(a) != FunctionReference.unwrap(b);
}
}
2 changes: 1 addition & 1 deletion src/interfaces/IAccountLoupe.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.19;

import {FunctionReference} from "../helpers/FunctionReferenceLib.sol";
import {FunctionReference} from "../interfaces/IPluginManager.sol";

interface IAccountLoupe {
/// @notice Config for an execution function, given a selector.
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IPluginManager.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.19;

import {FunctionReference} from "../helpers/FunctionReferenceLib.sol";
type FunctionReference is bytes21;

interface IPluginManager {
event PluginInstalled(address indexed plugin, bytes32 manifestHash, FunctionReference[] dependencies);
Expand Down
25 changes: 14 additions & 11 deletions test/libraries/FunctionReferenceLib.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ pragma solidity ^0.8.19;

import {Test} from "forge-std/Test.sol";

import {FunctionReference, FunctionReferenceLib} from "../../src/helpers/FunctionReferenceLib.sol";
import {FunctionReferenceLib} from "../../src/helpers/FunctionReferenceLib.sol";
import {FunctionReference} from "../../src/interfaces/IPluginManager.sol";

contract FunctionReferenceLibTest is Test {
using FunctionReferenceLib for FunctionReference;

function testFuzz_functionReference_packing(address addr, uint8 functionId) public {
// console.log("addr: ", addr);
// console.log("functionId: ", vm.toString(functionId));
Expand All @@ -19,19 +22,19 @@ contract FunctionReferenceLibTest is Test {
}

function testFuzz_functionReference_operators(FunctionReference a, FunctionReference b) public {
assertTrue(a == a);
assertTrue(b == b);
assertTrue(a.eq(a));
assertTrue(b.eq(b));

if (FunctionReference.unwrap(a) == FunctionReference.unwrap(b)) {
assertTrue(a == b);
assertTrue(b == a);
assertFalse(a != b);
assertFalse(b != a);
assertTrue(a.eq(b));
assertTrue(b.eq(a));
assertFalse(a.notEq(b));
assertFalse(b.notEq(a));
} else {
assertTrue(a != b);
assertTrue(b != a);
assertFalse(a == b);
assertFalse(b == a);
assertTrue(a.notEq(b));
assertTrue(b.notEq(a));
assertFalse(a.eq(b));
assertFalse(b.eq(a));
}
}
}

0 comments on commit 7aa1170

Please sign in to comment.