Skip to content
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
11 changes: 3 additions & 8 deletions src/account/AccountLoupe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,10 @@ abstract contract AccountLoupe is IAccountLoupe {
function getPreValidationHooks(bytes4 selector)
external
view
returns (
FunctionReference[] memory preUserOpValidationHooks,
FunctionReference[] memory preRuntimeValidationHooks
)
returns (FunctionReference[] memory preValidationHooks)
{
preUserOpValidationHooks =
toFunctionReferenceArray(getAccountStorage().selectorData[selector].preUserOpValidationHooks);
preRuntimeValidationHooks =
toFunctionReferenceArray(getAccountStorage().selectorData[selector].preRuntimeValidationHooks);
preValidationHooks =
toFunctionReferenceArray(getAccountStorage().selectorData[selector].preValidationHooks);
}

/// @inheritdoc IAccountLoupe
Expand Down
3 changes: 1 addition & 2 deletions src/account/AccountStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ struct SelectorData {
// User operation validation and runtime validation share a function reference.
FunctionReference validation;
// The pre validation hooks for this function selector.
EnumerableMap.Bytes32ToUintMap preUserOpValidationHooks;
EnumerableMap.Bytes32ToUintMap preRuntimeValidationHooks;
EnumerableMap.Bytes32ToUintMap preValidationHooks;
// The execution hooks for this function selector.
EnumerableMap.Bytes32ToUintMap preHooks;
// bytes21 key = pre hook function reference
Expand Down
75 changes: 12 additions & 63 deletions src/account/PluginManagerInternals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -137,45 +137,22 @@ abstract contract PluginManagerInternals is IPluginManager {
}
}

function _addPreUserOpValidationHook(bytes4 selector, FunctionReference preUserOpValidationHook)
function _addPreValidationHook(bytes4 selector, FunctionReference preValidationHook)
internal
notNullFunction(preUserOpValidationHook)
notNullFunction(preValidationHook)
{
_addOrIncrement(
getAccountStorage().selectorData[selector].preUserOpValidationHooks,
_toSetValue(preUserOpValidationHook)
getAccountStorage().selectorData[selector].preValidationHooks, _toSetValue(preValidationHook)
);
}

function _removePreUserOpValidationHook(bytes4 selector, FunctionReference preUserOpValidationHook)
function _removePreValidationHook(bytes4 selector, FunctionReference preValidationHook)
internal
notNullFunction(preUserOpValidationHook)
notNullFunction(preValidationHook)
{
// May ignore return value, as the manifest hash is validated to ensure that the hook exists.
_removeOrDecrement(
getAccountStorage().selectorData[selector].preUserOpValidationHooks,
_toSetValue(preUserOpValidationHook)
);
}

function _addPreRuntimeValidationHook(bytes4 selector, FunctionReference preRuntimeValidationHook)
internal
notNullFunction(preRuntimeValidationHook)
{
_addOrIncrement(
getAccountStorage().selectorData[selector].preRuntimeValidationHooks,
_toSetValue(preRuntimeValidationHook)
);
}

function _removePreRuntimeValidationHook(bytes4 selector, FunctionReference preRuntimeValidationHook)
internal
notNullFunction(preRuntimeValidationHook)
{
// May ignore return value, as the manifest hash is validated to ensure that the hook exists.
_removeOrDecrement(
getAccountStorage().selectorData[selector].preRuntimeValidationHooks,
_toSetValue(preRuntimeValidationHook)
getAccountStorage().selectorData[selector].preValidationHooks, _toSetValue(preValidationHook)
);
}

Expand Down Expand Up @@ -293,24 +270,10 @@ abstract contract PluginManagerInternals is IPluginManager {
// Hooks are not allowed to be provided as dependencies, so we use an empty array for resolving them.
FunctionReference[] memory emptyDependencies;

length = manifest.preUserOpValidationHooks.length;
length = manifest.preValidationHooks.length;
for (uint256 i = 0; i < length; ++i) {
ManifestAssociatedFunction memory mh = manifest.preUserOpValidationHooks[i];
_addPreUserOpValidationHook(
mh.executionSelector,
_resolveManifestFunction(
mh.associatedFunction,
plugin,
emptyDependencies,
ManifestAssociatedFunctionType.PRE_HOOK_ALWAYS_DENY
)
);
}

length = manifest.preRuntimeValidationHooks.length;
for (uint256 i = 0; i < length; ++i) {
ManifestAssociatedFunction memory mh = manifest.preRuntimeValidationHooks[i];
_addPreRuntimeValidationHook(
ManifestAssociatedFunction memory mh = manifest.preValidationHooks[i];
_addPreValidationHook(
mh.executionSelector,
_resolveManifestFunction(
mh.associatedFunction,
Expand Down Expand Up @@ -401,24 +364,10 @@ abstract contract PluginManagerInternals is IPluginManager {
);
}

length = manifest.preRuntimeValidationHooks.length;
for (uint256 i = 0; i < length; ++i) {
ManifestAssociatedFunction memory mh = manifest.preRuntimeValidationHooks[i];
_removePreRuntimeValidationHook(
mh.executionSelector,
_resolveManifestFunction(
mh.associatedFunction,
plugin,
emptyDependencies,
ManifestAssociatedFunctionType.PRE_HOOK_ALWAYS_DENY
)
);
}

length = manifest.preUserOpValidationHooks.length;
length = manifest.preValidationHooks.length;
for (uint256 i = 0; i < length; ++i) {
ManifestAssociatedFunction memory mh = manifest.preUserOpValidationHooks[i];
_removePreUserOpValidationHook(
ManifestAssociatedFunction memory mh = manifest.preValidationHooks[i];
_removePreValidationHook(
mh.executionSelector,
_resolveManifestFunction(
mh.associatedFunction,
Expand Down
4 changes: 2 additions & 2 deletions src/account/UpgradeableModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ contract UpgradeableModularAccount is

// Do preUserOpValidation hooks
EnumerableMap.Bytes32ToUintMap storage preUserOpValidationHooks =
getAccountStorage().selectorData[selector].preUserOpValidationHooks;
getAccountStorage().selectorData[selector].preValidationHooks;

uint256 preUserOpValidationHooksLength = preUserOpValidationHooks.length();
for (uint256 i = 0; i < preUserOpValidationHooksLength; ++i) {
Expand Down Expand Up @@ -397,7 +397,7 @@ contract UpgradeableModularAccount is
FunctionReference runtimeValidationFunction = _storage.selectorData[msg.sig].validation;
// run all preRuntimeValidation hooks
EnumerableMap.Bytes32ToUintMap storage preRuntimeValidationHooks =
getAccountStorage().selectorData[msg.sig].preRuntimeValidationHooks;
getAccountStorage().selectorData[msg.sig].preValidationHooks;

uint256 preRuntimeValidationHooksLength = preRuntimeValidationHooks.length();
for (uint256 i = 0; i < preRuntimeValidationHooksLength; ++i) {
Expand Down
8 changes: 2 additions & 6 deletions src/interfaces/IAccountLoupe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,11 @@ interface IAccountLoupe {

/// @notice Get the pre user op and runtime validation hooks associated with a selector.
/// @param selector The selector to get the hooks for.
/// @return preUserOpValidationHooks The pre user op validation hooks for this selector.
/// @return preRuntimeValidationHooks The pre runtime validation hooks for this selector.
/// @return preValidationHooks The pre validation hooks for this selector.
function getPreValidationHooks(bytes4 selector)
external
view
returns (
FunctionReference[] memory preUserOpValidationHooks,
FunctionReference[] memory preRuntimeValidationHooks
);
returns (FunctionReference[] memory preValidationHooks);

/// @notice Get an array of all installed plugins.
/// @return The addresses of all installed plugins.
Expand Down
3 changes: 1 addition & 2 deletions src/interfaces/IPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ struct PluginManifest {
bool canSpendNativeToken;
ManifestExternalCallPermission[] permittedExternalCalls;
ManifestAssociatedFunction[] validationFunctions;
ManifestAssociatedFunction[] preUserOpValidationHooks;
ManifestAssociatedFunction[] preRuntimeValidationHooks;
ManifestAssociatedFunction[] preValidationHooks;
ManifestExecutionHook[] executionHooks;
}

Expand Down
11 changes: 3 additions & 8 deletions standard/ERCs/erc-6900.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,15 +238,11 @@ interface IAccountLoupe {

/// @notice Get the pre user op and runtime validation hooks associated with a selector.
/// @param selector The selector to get the hooks for.
/// @return preUserOpValidationHooks The pre user op validation hooks for this selector.
/// @return preRuntimeValidationHooks The pre runtime validation hooks for this selector.
/// @return preValidationHooks The pre validation hooks for this selector.
function getPreValidationHooks(bytes4 selector)
external
view
returns (
FunctionReference[] memory preUserOpValidationHooks,
FunctionReference[] memory preRuntimeValidationHooks
);
returns (FunctionReference[] memory preValidationHooks);

/// @notice Get an array of all installed plugins.
/// @return The addresses of all installed plugins.
Expand Down Expand Up @@ -423,8 +419,7 @@ struct PluginManifest {
bool canSpendNativeToken;
ManifestExternalCallPermission[] permittedExternalCalls;
ManifestAssociatedFunction[] validationFunctions;
ManifestAssociatedFunction[] preUserOpValidationHooks;
ManifestAssociatedFunction[] preRuntimeValidationHooks;
ManifestAssociatedFunction[] preValidationHooks;
ManifestExecutionHook[] executionHooks;
}

Expand Down
34 changes: 4 additions & 30 deletions test/account/AccountLoupe.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -185,49 +185,23 @@ contract AccountLoupeTest is AccountTestBase {
);
}

function test_pluginLoupe_getPreUserOpValidationHooks() public {
(FunctionReference[] memory hooks,) = account1.getPreValidationHooks(comprehensivePlugin.foo.selector);
function test_pluginLoupe_getValidationHooks() public {
FunctionReference[] memory hooks = account1.getPreValidationHooks(comprehensivePlugin.foo.selector);

assertEq(hooks.length, 2);
assertEq(
FunctionReference.unwrap(hooks[0]),
FunctionReference.unwrap(
FunctionReferenceLib.pack(
address(comprehensivePlugin),
uint8(ComprehensivePlugin.FunctionId.PRE_USER_OP_VALIDATION_HOOK_1)
address(comprehensivePlugin), uint8(ComprehensivePlugin.FunctionId.PRE_VALIDATION_HOOK_1)
)
)
);
assertEq(
FunctionReference.unwrap(hooks[1]),
FunctionReference.unwrap(
FunctionReferenceLib.pack(
address(comprehensivePlugin),
uint8(ComprehensivePlugin.FunctionId.PRE_USER_OP_VALIDATION_HOOK_2)
)
)
);
}

function test_pluginLoupe_getPreRuntimeValidationHooks() public {
(, FunctionReference[] memory hooks) = account1.getPreValidationHooks(comprehensivePlugin.foo.selector);

assertEq(hooks.length, 2);
assertEq(
FunctionReference.unwrap(hooks[0]),
FunctionReference.unwrap(
FunctionReferenceLib.pack(
address(comprehensivePlugin),
uint8(ComprehensivePlugin.FunctionId.PRE_RUNTIME_VALIDATION_HOOK_1)
)
)
);
assertEq(
FunctionReference.unwrap(hooks[1]),
FunctionReference.unwrap(
FunctionReferenceLib.pack(
address(comprehensivePlugin),
uint8(ComprehensivePlugin.FunctionId.PRE_RUNTIME_VALIDATION_HOOK_2)
address(comprehensivePlugin), uint8(ComprehensivePlugin.FunctionId.PRE_VALIDATION_HOOK_2)
)
)
);
Expand Down
26 changes: 4 additions & 22 deletions test/account/ManifestValidity.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {PluginManagerInternals} from "../../src/account/PluginManagerInternals.s
import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol";

import {
BadValidationMagicValue_PreRuntimeValidationHook_Plugin,
BadValidationMagicValue_PreUserOpValidationHook_Plugin,
BadValidationMagicValue_PreValidationHook_Plugin,
BadValidationMagicValue_PreExecHook_Plugin,
BadValidationMagicValue_PostExecHook_Plugin,
BadHookMagicValue_UserOpValidationFunction_Plugin,
Expand All @@ -22,26 +21,9 @@ contract ManifestValidityTest is AccountTestBase {

// Tests that the plugin manager rejects a plugin with a pre-runtime validation hook set to "validation always
// allow"
function test_ManifestValidity_invalid_ValidationAlwaysAllow_PreRuntimeValidationHook() public {
BadValidationMagicValue_PreRuntimeValidationHook_Plugin plugin =
new BadValidationMagicValue_PreRuntimeValidationHook_Plugin();

bytes32 manifestHash = keccak256(abi.encode(plugin.pluginManifest()));

vm.expectRevert(abi.encodeWithSelector(PluginManagerInternals.InvalidPluginManifest.selector));
account1.installPlugin({
plugin: address(plugin),
manifestHash: manifestHash,
pluginInstallData: "",
dependencies: new FunctionReference[](0)
});
}

// Tests that the plugin manager rejects a plugin with a pre-user op validation hook set to "validation always
// allow"
function test_ManifestValidity_invalid_ValidationAlwaysAllow_PreUserOpValidationHook() public {
BadValidationMagicValue_PreUserOpValidationHook_Plugin plugin =
new BadValidationMagicValue_PreUserOpValidationHook_Plugin();
function test_ManifestValidity_invalid_ValidationAlwaysAllow_PreValidationHook() public {
BadValidationMagicValue_PreValidationHook_Plugin plugin =
new BadValidationMagicValue_PreValidationHook_Plugin();

bytes32 manifestHash = keccak256(abi.encode(plugin.pluginManifest()));

Expand Down
2 changes: 1 addition & 1 deletion test/account/ValidationIntersection.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ contract ValidationIntersectionTest is AccountTestBase {
abi.encodeWithSelector(
UpgradeableModularAccount.UnexpectedAggregator.selector,
address(oneHookPlugin),
MockBaseUserOpValidationPlugin.FunctionId.PRE_USER_OP_VALIDATION_HOOK_1,
MockBaseUserOpValidationPlugin.FunctionId.PRE_VALIDATION_HOOK_1,
badAuthorizer
)
);
Expand Down
Loading