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
4 changes: 1 addition & 3 deletions src/account/AccountLoupe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ abstract contract AccountLoupe is IAccountLoupe {
config.plugin = _storage.selectorData[selector].plugin;
}

config.userOpValidationFunction = _storage.selectorData[selector].userOpValidation;

config.runtimeValidationFunction = _storage.selectorData[selector].runtimeValidation;
config.validationFunction = _storage.selectorData[selector].validation;
}

/// @inheritdoc IAccountLoupe
Expand Down
4 changes: 2 additions & 2 deletions src/account/AccountStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ struct SelectorData {
// The plugin that implements this execution function.
// If this is a native function, the address must remain address(0).
address plugin;
FunctionReference userOpValidation;
FunctionReference runtimeValidation;
// 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;
Expand Down
79 changes: 13 additions & 66 deletions src/account/PluginManagerInternals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ abstract contract PluginManagerInternals is IPluginManager {
error PluginInstallCallbackFailed(address plugin, bytes revertReason);
error PluginInterfaceNotSupported(address plugin);
error PluginNotInstalled(address plugin);
error RuntimeValidationFunctionAlreadySet(bytes4 selector, FunctionReference validationFunction);
error UserOpValidationFunctionAlreadySet(bytes4 selector, FunctionReference validationFunction);
error ValidationFunctionAlreadySet(bytes4 selector, FunctionReference validationFunction);

modifier notNullFunction(FunctionReference functionReference) {
if (functionReference.isEmpty()) {
Expand Down Expand Up @@ -76,48 +75,26 @@ abstract contract PluginManagerInternals is IPluginManager {
_selectorData.plugin = address(0);
}

function _addUserOpValidationFunction(bytes4 selector, FunctionReference validationFunction)
function _addValidationFunction(bytes4 selector, FunctionReference validationFunction)
internal
notNullFunction(validationFunction)
{
SelectorData storage _selectorData = getAccountStorage().selectorData[selector];

if (!_selectorData.userOpValidation.isEmpty()) {
revert UserOpValidationFunctionAlreadySet(selector, validationFunction);
if (!_selectorData.validation.isEmpty()) {
revert ValidationFunctionAlreadySet(selector, validationFunction);
}

_selectorData.userOpValidation = validationFunction;
_selectorData.validation = validationFunction;
}

function _removeUserOpValidationFunction(bytes4 selector, FunctionReference validationFunction)
function _removeValidationFunction(bytes4 selector, FunctionReference validationFunction)
internal
notNullFunction(validationFunction)
{
SelectorData storage _selectorData = getAccountStorage().selectorData[selector];

_selectorData.userOpValidation = FunctionReferenceLib._EMPTY_FUNCTION_REFERENCE;
}

function _addRuntimeValidationFunction(bytes4 selector, FunctionReference validationFunction)
internal
notNullFunction(validationFunction)
{
SelectorData storage _selectorData = getAccountStorage().selectorData[selector];

if (!_selectorData.runtimeValidation.isEmpty()) {
revert RuntimeValidationFunctionAlreadySet(selector, validationFunction);
}

_selectorData.runtimeValidation = validationFunction;
}

function _removeRuntimeValidationFunction(bytes4 selector, FunctionReference validationFunction)
internal
notNullFunction(validationFunction)
{
SelectorData storage _selectorData = getAccountStorage().selectorData[selector];

_selectorData.runtimeValidation = FunctionReferenceLib._EMPTY_FUNCTION_REFERENCE;
_selectorData.validation = FunctionReferenceLib._EMPTY_FUNCTION_REFERENCE;
}

function _addExecHooks(bytes4 selector, FunctionReference preExecHook, FunctionReference postExecHook)
Expand Down Expand Up @@ -319,25 +296,10 @@ abstract contract PluginManagerInternals is IPluginManager {
}
}

length = manifest.userOpValidationFunctions.length;
for (uint256 i = 0; i < length;) {
ManifestAssociatedFunction memory mv = manifest.userOpValidationFunctions[i];
_addUserOpValidationFunction(
mv.executionSelector,
_resolveManifestFunction(
mv.associatedFunction, plugin, dependencies, ManifestAssociatedFunctionType.NONE
)
);

unchecked {
++i;
}
}

length = manifest.runtimeValidationFunctions.length;
length = manifest.validationFunctions.length;
for (uint256 i = 0; i < length;) {
ManifestAssociatedFunction memory mv = manifest.runtimeValidationFunctions[i];
_addRuntimeValidationFunction(
ManifestAssociatedFunction memory mv = manifest.validationFunctions[i];
_addValidationFunction(
mv.executionSelector,
_resolveManifestFunction(
mv.associatedFunction,
Expand Down Expand Up @@ -521,10 +483,10 @@ abstract contract PluginManagerInternals is IPluginManager {
}
}

length = manifest.runtimeValidationFunctions.length;
length = manifest.validationFunctions.length;
for (uint256 i = 0; i < length;) {
ManifestAssociatedFunction memory mv = manifest.runtimeValidationFunctions[i];
_removeRuntimeValidationFunction(
ManifestAssociatedFunction memory mv = manifest.validationFunctions[i];
_removeValidationFunction(
mv.executionSelector,
_resolveManifestFunction(
mv.associatedFunction,
Expand All @@ -539,21 +501,6 @@ abstract contract PluginManagerInternals is IPluginManager {
}
}

length = manifest.userOpValidationFunctions.length;
for (uint256 i = 0; i < length;) {
ManifestAssociatedFunction memory mv = manifest.userOpValidationFunctions[i];
_removeUserOpValidationFunction(
mv.executionSelector,
_resolveManifestFunction(
mv.associatedFunction, plugin, dependencies, ManifestAssociatedFunctionType.NONE
)
);

unchecked {
++i;
}
}

// remove external call permissions

if (manifest.permitAnyExternalAddress) {
Expand Down
7 changes: 4 additions & 3 deletions src/account/UpgradeableModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ contract UpgradeableModularAccount is
}
bytes4 selector = bytes4(userOp.callData);

FunctionReference userOpValidationFunction = getAccountStorage().selectorData[selector].userOpValidation;
FunctionReference userOpValidationFunction = getAccountStorage().selectorData[selector].validation;

validationData = _doUserOpValidation(selector, userOpValidationFunction, userOp, userOpHash);
}
Expand Down Expand Up @@ -395,7 +395,8 @@ contract UpgradeableModularAccount is
validationData = currentValidationData;
}
} else {
// _RUNTIME_VALIDATION_ALWAYS_ALLOW and _PRE_HOOK_ALWAYS_DENY is not permitted here.
// _PRE_HOOK_ALWAYS_DENY is not permitted here.
// If this is _RUNTIME_VALIDATION_ALWAYS_ALLOW, the call should revert.
revert InvalidConfiguration();
}
}
Expand All @@ -405,7 +406,7 @@ contract UpgradeableModularAccount is
if (msg.sender == address(_ENTRY_POINT)) return;

AccountStorage storage _storage = getAccountStorage();
FunctionReference runtimeValidationFunction = _storage.selectorData[msg.sig].runtimeValidation;
FunctionReference runtimeValidationFunction = _storage.selectorData[msg.sig].validation;
// run all preRuntimeValidation hooks
EnumerableMap.Bytes32ToUintMap storage preRuntimeValidationHooks =
getAccountStorage().selectorData[msg.sig].preRuntimeValidationHooks;
Expand Down
3 changes: 1 addition & 2 deletions src/interfaces/IAccountLoupe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ interface IAccountLoupe {
/// @notice Config for an execution function, given a selector.
struct ExecutionFunctionConfig {
address plugin;
FunctionReference userOpValidationFunction;
FunctionReference runtimeValidationFunction;
FunctionReference validationFunction;
}

/// @notice Pre and post hooks for a given selector.
Expand Down
3 changes: 1 addition & 2 deletions src/interfaces/IPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ struct PluginManifest {
// plugin MUST still be able to spend up to the balance that it sends to the account in the same call.
bool canSpendNativeToken;
ManifestExternalCallPermission[] permittedExternalCalls;
ManifestAssociatedFunction[] userOpValidationFunctions;
ManifestAssociatedFunction[] runtimeValidationFunctions;
ManifestAssociatedFunction[] validationFunctions;
ManifestAssociatedFunction[] preUserOpValidationHooks;
ManifestAssociatedFunction[] preRuntimeValidationHooks;
ManifestExecutionHook[] executionHooks;
Expand Down
20 changes: 10 additions & 10 deletions src/plugins/TokenReceiverPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,27 @@ contract TokenReceiverPlugin is BasePlugin, IERC721Receiver, IERC777Recipient, I
manifest.executionFunctions[3] = this.onERC1155BatchReceived.selector;

// Only runtime validationFunction is needed since callbacks come from token contracts only
ManifestFunction memory alwaysAllowFunction = ManifestFunction({
ManifestFunction memory alwaysAllowRuntime = ManifestFunction({
functionType: ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW,
functionId: 0, // Unused.
dependencyIndex: 0 // Unused.
});
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](4);
manifest.runtimeValidationFunctions[0] = ManifestAssociatedFunction({
manifest.validationFunctions = new ManifestAssociatedFunction[](4);
manifest.validationFunctions[0] = ManifestAssociatedFunction({
executionSelector: this.tokensReceived.selector,
associatedFunction: alwaysAllowFunction
associatedFunction: alwaysAllowRuntime
});
manifest.runtimeValidationFunctions[1] = ManifestAssociatedFunction({
manifest.validationFunctions[1] = ManifestAssociatedFunction({
executionSelector: this.onERC721Received.selector,
associatedFunction: alwaysAllowFunction
associatedFunction: alwaysAllowRuntime
});
manifest.runtimeValidationFunctions[2] = ManifestAssociatedFunction({
manifest.validationFunctions[2] = ManifestAssociatedFunction({
executionSelector: this.onERC1155Received.selector,
associatedFunction: alwaysAllowFunction
associatedFunction: alwaysAllowRuntime
});
manifest.runtimeValidationFunctions[3] = ManifestAssociatedFunction({
manifest.validationFunctions[3] = ManifestAssociatedFunction({
executionSelector: this.onERC1155BatchReceived.selector,
associatedFunction: alwaysAllowFunction
associatedFunction: alwaysAllowRuntime
});

manifest.interfaceIds = new bytes4[](3);
Expand Down
3 changes: 1 addition & 2 deletions src/plugins/owner/ISingleOwnerPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {UserOperation} from "@eth-infinitism/account-abstraction/interfaces/User

interface ISingleOwnerPlugin {
enum FunctionId {
RUNTIME_VALIDATION_OWNER_OR_SELF,
USER_OP_VALIDATION_OWNER
VALIDATION_OWNER_OR_SELF
}

/// @notice This event is emitted when ownership of the account changes.
Expand Down
82 changes: 22 additions & 60 deletions src/plugins/owner/SingleOwnerPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ contract SingleOwnerPlugin is BasePlugin, ISingleOwnerPlugin, IERC1271 {
view
override
{
if (functionId == uint8(FunctionId.RUNTIME_VALIDATION_OWNER_OR_SELF)) {
if (functionId == uint8(FunctionId.VALIDATION_OWNER_OR_SELF)) {
// Validate that the sender is the owner of the account or self.
if (sender != _owners[msg.sender] && sender != msg.sender) {
revert NotAuthorized();
Expand All @@ -125,7 +125,7 @@ contract SingleOwnerPlugin is BasePlugin, ISingleOwnerPlugin, IERC1271 {
override
returns (uint256)
{
if (functionId == uint8(FunctionId.USER_OP_VALIDATION_OWNER)) {
if (functionId == uint8(FunctionId.VALIDATION_OWNER_OR_SELF)) {
// Validate the user op signature against the owner.
(address signer,) = (userOpHash.toEthSignedMessageHash()).tryRecover(userOp.signature);
if (signer == address(0) || signer != _owners[msg.sender]) {
Expand All @@ -145,87 +145,49 @@ contract SingleOwnerPlugin is BasePlugin, ISingleOwnerPlugin, IERC1271 {
manifest.executionFunctions[1] = this.isValidSignature.selector;
manifest.executionFunctions[2] = this.owner.selector;

ManifestFunction memory ownerUserOpValidationFunction = ManifestFunction({
ManifestFunction memory ownerValidationFunction = ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
functionId: uint8(FunctionId.USER_OP_VALIDATION_OWNER),
functionId: uint8(FunctionId.VALIDATION_OWNER_OR_SELF),
dependencyIndex: 0 // Unused.
});
manifest.userOpValidationFunctions = new ManifestAssociatedFunction[](7);
manifest.userOpValidationFunctions[0] = ManifestAssociatedFunction({
manifest.validationFunctions = new ManifestAssociatedFunction[](8);
manifest.validationFunctions[0] = ManifestAssociatedFunction({
executionSelector: this.transferOwnership.selector,
associatedFunction: ownerUserOpValidationFunction
associatedFunction: ownerValidationFunction
});
manifest.userOpValidationFunctions[1] = ManifestAssociatedFunction({
manifest.validationFunctions[1] = ManifestAssociatedFunction({
executionSelector: IStandardExecutor.execute.selector,
associatedFunction: ownerUserOpValidationFunction
associatedFunction: ownerValidationFunction
});
manifest.userOpValidationFunctions[2] = ManifestAssociatedFunction({
manifest.validationFunctions[2] = ManifestAssociatedFunction({
executionSelector: IStandardExecutor.executeBatch.selector,
associatedFunction: ownerUserOpValidationFunction
associatedFunction: ownerValidationFunction
});
manifest.userOpValidationFunctions[3] = ManifestAssociatedFunction({
manifest.validationFunctions[3] = ManifestAssociatedFunction({
executionSelector: IPluginManager.installPlugin.selector,
associatedFunction: ownerUserOpValidationFunction
associatedFunction: ownerValidationFunction
});
manifest.userOpValidationFunctions[4] = ManifestAssociatedFunction({
manifest.validationFunctions[4] = ManifestAssociatedFunction({
executionSelector: IPluginManager.uninstallPlugin.selector,
associatedFunction: ownerUserOpValidationFunction
associatedFunction: ownerValidationFunction
});
manifest.userOpValidationFunctions[5] = ManifestAssociatedFunction({
manifest.validationFunctions[5] = ManifestAssociatedFunction({
executionSelector: UUPSUpgradeable.upgradeTo.selector,
associatedFunction: ownerUserOpValidationFunction
associatedFunction: ownerValidationFunction
});
manifest.userOpValidationFunctions[6] = ManifestAssociatedFunction({
manifest.validationFunctions[6] = ManifestAssociatedFunction({
executionSelector: UUPSUpgradeable.upgradeToAndCall.selector,
associatedFunction: ownerUserOpValidationFunction
associatedFunction: ownerValidationFunction
});

ManifestFunction memory ownerOrSelfRuntimeValidationFunction = ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
functionId: uint8(FunctionId.RUNTIME_VALIDATION_OWNER_OR_SELF),
dependencyIndex: 0 // Unused.
});
ManifestFunction memory alwaysAllowFunction = ManifestFunction({
ManifestFunction memory alwaysAllowRuntime = ManifestFunction({
functionType: ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW,
functionId: 0, // Unused.
dependencyIndex: 0 // Unused.
});
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](9);
manifest.runtimeValidationFunctions[0] = ManifestAssociatedFunction({
executionSelector: this.transferOwnership.selector,
associatedFunction: ownerOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[1] = ManifestAssociatedFunction({
executionSelector: this.owner.selector,
associatedFunction: alwaysAllowFunction
});
manifest.runtimeValidationFunctions[2] = ManifestAssociatedFunction({
executionSelector: IStandardExecutor.execute.selector,
associatedFunction: ownerOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[3] = ManifestAssociatedFunction({
executionSelector: IStandardExecutor.executeBatch.selector,
associatedFunction: ownerOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[4] = ManifestAssociatedFunction({
executionSelector: IPluginManager.installPlugin.selector,
associatedFunction: ownerOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[5] = ManifestAssociatedFunction({
executionSelector: IPluginManager.uninstallPlugin.selector,
associatedFunction: ownerOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[6] = ManifestAssociatedFunction({
executionSelector: UUPSUpgradeable.upgradeTo.selector,
associatedFunction: ownerOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[7] = ManifestAssociatedFunction({
executionSelector: UUPSUpgradeable.upgradeToAndCall.selector,
associatedFunction: ownerOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[8] = ManifestAssociatedFunction({
manifest.validationFunctions[7] = ManifestAssociatedFunction({
executionSelector: this.isValidSignature.selector,
associatedFunction: alwaysAllowFunction
associatedFunction: alwaysAllowRuntime
});

return manifest;
Expand Down
Loading