From 7846d38251c6e0c243f62acb7562aff57e210f44 Mon Sep 17 00:00:00 2001 From: adam-alchemy <127769144+adam-alchemy@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:11:52 -0800 Subject: [PATCH] feat: [v0.7.0] Cut permitted call hooks & injection (#20) --- src/account/AccountLoupe.sol | 18 +- src/account/AccountStorage.sol | 17 +- src/account/PluginManagerInternals.sol | 197 +- src/account/UpgradeableModularAccount.sol | 45 +- src/interfaces/IAccountLoupe.sol | 9 - src/interfaces/IPlugin.sol | 25 - src/interfaces/IPluginManager.sol | 38 +- src/plugins/BasePlugin.sol | 27 - standard/ERCs/ERC6900Diagrams.excalidraw | 1694 +++++++---------- standard/ERCs/erc-6900.md | 81 +- .../assets/eip-6900/Plugin_Execution_Flow.svg | 8 +- test/account/AccountExecHooks.t.sol | 29 +- test/account/AccountLoupe.t.sol | 76 +- test/account/AccountPermittedCallHooks.t.sol | 406 ---- test/account/AccountReturnData.t.sol | 7 +- .../ExecuteFromPluginPermissions.t.sol | 72 +- test/account/ManifestValidity.t.sol | 26 +- test/account/UpgradeableModularAccount.t.sol | 240 +-- test/account/ValidationIntersection.t.sol | 10 +- test/mocks/plugins/ComprehensivePlugin.sol | 15 - .../ExecFromPluginPermissionsMocks.sol | 127 -- test/plugin/TokenReceiverPlugin.t.sol | 5 +- 22 files changed, 770 insertions(+), 2402 deletions(-) delete mode 100644 test/account/AccountPermittedCallHooks.t.sol diff --git a/src/account/AccountLoupe.sol b/src/account/AccountLoupe.sol index 6a841a88..55b1566c 100644 --- a/src/account/AccountLoupe.sol +++ b/src/account/AccountLoupe.sol @@ -5,13 +5,7 @@ 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, - getPermittedCallKey, - HookGroup, - toFunctionReferenceArray -} from "./AccountStorage.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"; @@ -53,16 +47,6 @@ abstract contract AccountLoupe is IAccountLoupe { execHooks = _getHooks(getAccountStorage().selectorData[selector].executionHooks); } - /// @inheritdoc IAccountLoupe - function getPermittedCallHooks(address callingPlugin, bytes4 selector) - external - view - returns (ExecutionHooks[] memory execHooks) - { - bytes24 key = getPermittedCallKey(callingPlugin, selector); - execHooks = _getHooks(getAccountStorage().permittedCalls[key].permittedCallHooks); - } - /// @inheritdoc IAccountLoupe function getPreValidationHooks(bytes4 selector) external diff --git a/src/account/AccountStorage.sol b/src/account/AccountStorage.sol index 5988cfd6..c67d6f5e 100644 --- a/src/account/AccountStorage.sol +++ b/src/account/AccountStorage.sol @@ -19,27 +19,12 @@ struct PluginData { FunctionReference[] dependencies; // Tracks the number of times this plugin has been used as a dependency function uint256 dependentCount; - StoredInjectedHook[] injectedHooks; -} - -// A version of IPluginManager.InjectedHook used to track injected hooks in storage. -// Omits the hookApplyData field, which is not needed for storage, and flattens the struct. -struct StoredInjectedHook { - // The plugin that provides the hook - address providingPlugin; - // Either a plugin-defined execution function, or the native function executeFromPluginExternal - bytes4 selector; - // Contents of the InjectedHooksInfo struct - uint8 preExecHookFunctionId; - bool isPostHookUsed; - uint8 postExecHookFunctionId; } // Represents data associated with a plugin's permission to use `executeFromPlugin` // to interact with another plugin installed on the account. struct PermittedCallData { bool callPermitted; - HookGroup permittedCallHooks; } // Represents data associated with a plugin's permission to use `executeFromPluginExternal` @@ -52,7 +37,7 @@ struct PermittedExternalCallData { mapping(bytes4 => bool) permittedSelectors; } -// Represets a set of pre- and post- hooks. Used to store both execution hooks and permitted call hooks. +// Represets a set of pre- and post- hooks. struct HookGroup { EnumerableMap.Bytes32ToUintMap preHooks; // bytes21 key = pre hook function reference diff --git a/src/account/PluginManagerInternals.sol b/src/account/PluginManagerInternals.sol index b4bada9e..e2a10863 100644 --- a/src/account/PluginManagerInternals.sol +++ b/src/account/PluginManagerInternals.sol @@ -9,11 +9,9 @@ import { AccountStorage, getAccountStorage, SelectorData, - PermittedCallData, getPermittedCallKey, HookGroup, - PermittedExternalCallData, - StoredInjectedHook + PermittedExternalCallData } from "./AccountStorage.sol"; import {FunctionReference, FunctionReferenceLib} from "../helpers/FunctionReferenceLib.sol"; import {IPluginManager} from "../interfaces/IPluginManager.sol"; @@ -45,8 +43,6 @@ abstract contract PluginManagerInternals is IPluginManager { error PluginNotInstalled(address plugin); error RuntimeValidationFunctionAlreadySet(bytes4 selector, FunctionReference validationFunction); error UserOpValidationFunctionAlreadySet(bytes4 selector, FunctionReference validationFunction); - error PluginApplyHookCallbackFailed(address providingPlugin, bytes revertReason); - error PluginUnapplyHookCallbackFailed(address providingPlugin, bytes revertReason); modifier notNullFunction(FunctionReference functionReference) { if (functionReference.isEmpty()) { @@ -157,30 +153,6 @@ abstract contract PluginManagerInternals is IPluginManager { accountStorage.permittedCalls[key].callPermitted = false; } - function _addPermittedCallHooks( - bytes4 selector, - address plugin, - FunctionReference preExecHook, - FunctionReference postExecHook - ) internal notNullPlugin(plugin) { - bytes24 permittedCallKey = getPermittedCallKey(plugin, selector); - PermittedCallData storage _permittedCalldata = getAccountStorage().permittedCalls[permittedCallKey]; - - _addHooks(_permittedCalldata.permittedCallHooks, preExecHook, postExecHook); - } - - function _removePermittedCallHooks( - bytes4 selector, - address plugin, - FunctionReference preExecHook, - FunctionReference postExecHook - ) internal notNullPlugin(plugin) { - bytes24 permittedCallKey = getPermittedCallKey(plugin, selector); - PermittedCallData storage _permittedCallData = getAccountStorage().permittedCalls[permittedCallKey]; - - _removeHooks(_permittedCallData.permittedCallHooks, preExecHook, postExecHook); - } - function _addHooks(HookGroup storage hooks, FunctionReference preExecHook, FunctionReference postExecHook) internal { @@ -263,8 +235,7 @@ abstract contract PluginManagerInternals is IPluginManager { address plugin, bytes32 manifestHash, bytes memory pluginInitData, - FunctionReference[] memory dependencies, - InjectedHook[] memory injectedHooks + FunctionReference[] memory dependencies ) internal { AccountStorage storage _storage = getAccountStorage(); @@ -376,44 +347,6 @@ abstract contract PluginManagerInternals is IPluginManager { } } - length = injectedHooks.length; - // manually set arr length - StoredInjectedHook[] storage optionalHooksLengthArr = _storage.pluginData[plugin].injectedHooks; - assembly ("memory-safe") { - sstore(optionalHooksLengthArr.slot, length) - } - - for (uint256 i = 0; i < length;) { - InjectedHook memory hook = injectedHooks[i]; - _storage.pluginData[plugin].injectedHooks[i] = StoredInjectedHook({ - providingPlugin: hook.providingPlugin, - selector: hook.selector, - preExecHookFunctionId: hook.injectedHooksInfo.preExecHookFunctionId, - isPostHookUsed: hook.injectedHooksInfo.isPostHookUsed, - postExecHookFunctionId: hook.injectedHooksInfo.postExecHookFunctionId - }); - - // Increment the dependent count for the plugin providing the hook. - _storage.pluginData[hook.providingPlugin].dependentCount += 1; - - if (!_storage.plugins.contains(hook.providingPlugin)) { - revert MissingPluginDependency(hook.providingPlugin); - } - - _addPermittedCallHooks( - hook.selector, - plugin, - FunctionReferenceLib.pack(hook.providingPlugin, hook.injectedHooksInfo.preExecHookFunctionId), - hook.injectedHooksInfo.isPostHookUsed - ? FunctionReferenceLib.pack(hook.providingPlugin, hook.injectedHooksInfo.postExecHookFunctionId) - : FunctionReferenceLib._EMPTY_FUNCTION_REFERENCE - ); - - unchecked { - ++i; - } - } - length = manifest.userOpValidationFunctions.length; for (uint256 i = 0; i < length;) { ManifestAssociatedFunction memory mv = manifest.userOpValidationFunctions[i]; @@ -500,30 +433,6 @@ abstract contract PluginManagerInternals is IPluginManager { } } - length = manifest.permittedCallHooks.length; - for (uint256 i = 0; i < length;) { - _addPermittedCallHooks( - manifest.permittedCallHooks[i].executionSelector, - plugin, - _resolveManifestFunction( - manifest.permittedCallHooks[i].preExecHook, - plugin, - dependencies, - ManifestAssociatedFunctionType.PRE_HOOK_ALWAYS_DENY - ), - _resolveManifestFunction( - manifest.permittedCallHooks[i].postExecHook, - plugin, - dependencies, - ManifestAssociatedFunctionType.NONE - ) - ); - - unchecked { - ++i; - } - } - length = manifest.interfaceIds.length; for (uint256 i = 0; i < length;) { _storage.supportedIfaces[manifest.interfaceIds[i]] += 1; @@ -532,24 +441,6 @@ abstract contract PluginManagerInternals is IPluginManager { } } - // call onHookApply after all setup, but before calling plugin onInstall - length = injectedHooks.length; - - for (uint256 i = 0; i < length;) { - InjectedHook memory hook = injectedHooks[i]; - // not inlined in function call to avoid stack too deep error - bytes memory onHookApplyData = injectedHooks[i].hookApplyData; - /* solhint-disable no-empty-blocks */ - try IPlugin(hook.providingPlugin).onHookApply(plugin, hook.injectedHooksInfo, onHookApplyData) {} - catch (bytes memory revertReason) { - revert PluginApplyHookCallbackFailed(hook.providingPlugin, revertReason); - } - /* solhint-enable no-empty-blocks */ - unchecked { - ++i; - } - } - // Initialize the plugin storage for the account. // solhint-disable-next-line no-empty-blocks try IPlugin(plugin).onInstall(pluginInitData) {} @@ -557,15 +448,12 @@ abstract contract PluginManagerInternals is IPluginManager { revert PluginInstallCallbackFailed(plugin, revertReason); } - emit PluginInstalled(plugin, manifestHash, dependencies, injectedHooks); + emit PluginInstalled(plugin, manifestHash, dependencies); } - function _uninstallPlugin( - address plugin, - PluginManifest memory manifest, - bytes memory uninstallData, - bytes[] calldata hookUnapplyData - ) internal { + function _uninstallPlugin(address plugin, PluginManifest memory manifest, bytes memory uninstallData) + internal + { AccountStorage storage _storage = getAccountStorage(); // Check if the plugin exists. @@ -602,30 +490,6 @@ abstract contract PluginManagerInternals is IPluginManager { // Remove components according to the manifest, in reverse order (by component type) of their installation. // If any expected components are missing, revert. - length = manifest.permittedCallHooks.length; - for (uint256 i = 0; i < length;) { - _removePermittedCallHooks( - manifest.permittedCallHooks[i].executionSelector, - plugin, - _resolveManifestFunction( - manifest.permittedCallHooks[i].preExecHook, - plugin, - dependencies, - ManifestAssociatedFunctionType.PRE_HOOK_ALWAYS_DENY - ), - _resolveManifestFunction( - manifest.permittedCallHooks[i].postExecHook, - plugin, - dependencies, - ManifestAssociatedFunctionType.NONE - ) - ); - - unchecked { - ++i; - } - } - length = manifest.executionHooks.length; for (uint256 i = 0; i < length;) { ManifestExecutionHook memory mh = manifest.executionHooks[i]; @@ -749,27 +613,6 @@ abstract contract PluginManagerInternals is IPluginManager { } } - length = _storage.pluginData[plugin].injectedHooks.length; - for (uint256 i = 0; i < length;) { - StoredInjectedHook memory hook = _storage.pluginData[plugin].injectedHooks[i]; - - // Decrement the dependent count for the plugin providing the hook. - _storage.pluginData[hook.providingPlugin].dependentCount -= 1; - - _removePermittedCallHooks( - hook.selector, - plugin, - FunctionReferenceLib.pack(hook.providingPlugin, hook.preExecHookFunctionId), - hook.isPostHookUsed - ? FunctionReferenceLib.pack(hook.providingPlugin, hook.postExecHookFunctionId) - : FunctionReferenceLib._EMPTY_FUNCTION_REFERENCE - ); - - unchecked { - ++i; - } - } - length = manifest.permittedExecutionSelectors.length; for (uint256 i = 0; i < length;) { _disableExecFromPlugin(manifest.permittedExecutionSelectors[i], plugin, _storage); @@ -796,34 +639,6 @@ abstract contract PluginManagerInternals is IPluginManager { } } - length = _storage.pluginData[plugin].injectedHooks.length; - bool hasUnapplyHookData = hookUnapplyData.length != 0; - if (hasUnapplyHookData && hookUnapplyData.length != length) { - revert ArrayLengthMismatch(); - } - - for (uint256 i = 0; i < length;) { - StoredInjectedHook memory hook = _storage.pluginData[plugin].injectedHooks[i]; - - /* solhint-disable no-empty-blocks */ - try IPlugin(hook.providingPlugin).onHookUnapply( - plugin, - InjectedHooksInfo({ - preExecHookFunctionId: hook.preExecHookFunctionId, - isPostHookUsed: hook.isPostHookUsed, - postExecHookFunctionId: hook.postExecHookFunctionId - }), - hasUnapplyHookData ? hookUnapplyData[i] : bytes("") - ) {} catch (bytes memory revertReason) { - revert PluginUnapplyHookCallbackFailed(hook.providingPlugin, revertReason); - } - /* solhint-enable no-empty-blocks */ - - unchecked { - ++i; - } - } - // Remove the plugin metadata from the account. delete _storage.pluginData[plugin]; diff --git a/src/account/UpgradeableModularAccount.sol b/src/account/UpgradeableModularAccount.sol index 11b820ab..cb447eb2 100644 --- a/src/account/UpgradeableModularAccount.sol +++ b/src/account/UpgradeableModularAccount.sol @@ -99,12 +99,9 @@ contract UpgradeableModularAccount is } FunctionReference[] memory emptyDependencies = new FunctionReference[](0); - IPluginManager.InjectedHook[] memory emptyInjectedHooks = new IPluginManager.InjectedHook[](0); for (uint256 i = 0; i < length;) { - _installPlugin( - plugins[i], manifestHashes[i], pluginInstallDatas[i], emptyDependencies, emptyInjectedHooks - ); + _installPlugin(plugins[i], manifestHashes[i], pluginInstallDatas[i], emptyDependencies); unchecked { ++i; @@ -190,9 +187,6 @@ contract UpgradeableModularAccount is revert ExecFromPluginNotPermitted(callingPlugin, selector); } - PostExecToRun[] memory postPermittedCallHooks = - _doPrePermittedCallHooks(getPermittedCallKey(callingPlugin, selector), data); - address execFunctionPlugin = _storage.selectorData[selector].plugin; if (execFunctionPlugin == address(0)) { @@ -210,7 +204,6 @@ contract UpgradeableModularAccount is } _doCachedPostExecHooks(postExecHooks); - _doCachedPostExecHooks(postPermittedCallHooks); return returnData; } @@ -251,12 +244,6 @@ contract UpgradeableModularAccount is revert ExecFromPluginExternalNotPermitted(msg.sender, target, value, data); } - // Run any pre plugin exec specific to this caller and the `executeFromPluginExternal` selector - - PostExecToRun[] memory postPermittedCallHooks = _doPrePermittedCallHooks( - getPermittedCallKey(msg.sender, IPluginExecutor.executeFromPluginExternal.selector), msg.data - ); - // Run any pre exec hooks for this selector PostExecToRun[] memory postExecHooks = _doPreExecHooks(IPluginExecutor.executeFromPluginExternal.selector, msg.data); @@ -267,9 +254,6 @@ contract UpgradeableModularAccount is // Run any post exec hooks for this selector _doCachedPostExecHooks(postExecHooks); - // Run any post exec hooks specific to this caller and the `executeFromPluginExternal` selector - _doCachedPostExecHooks(postPermittedCallHooks); - return returnData; } @@ -278,19 +262,17 @@ contract UpgradeableModularAccount is address plugin, bytes32 manifestHash, bytes calldata pluginInitData, - FunctionReference[] calldata dependencies, - InjectedHook[] calldata injectedHooks + FunctionReference[] calldata dependencies ) external override wrapNativeFunction { - _installPlugin(plugin, manifestHash, pluginInitData, dependencies, injectedHooks); + _installPlugin(plugin, manifestHash, pluginInitData, dependencies); } /// @inheritdoc IPluginManager - function uninstallPlugin( - address plugin, - bytes calldata config, - bytes calldata pluginUninstallData, - bytes[] calldata hookUnapplyData - ) external override wrapNativeFunction { + function uninstallPlugin(address plugin, bytes calldata config, bytes calldata pluginUninstallData) + external + override + wrapNativeFunction + { PluginManifest memory manifest; if (config.length > 0) { @@ -299,7 +281,7 @@ contract UpgradeableModularAccount is manifest = IPlugin(plugin).pluginManifest(); } - _uninstallPlugin(plugin, manifest, pluginUninstallData, hookUnapplyData); + _uninstallPlugin(plugin, manifest, pluginUninstallData); } /// @notice ERC165 introspection @@ -492,15 +474,6 @@ contract UpgradeableModularAccount is return _doPreHooks(hooks, data); } - function _doPrePermittedCallHooks(bytes24 permittedCallKey, bytes calldata data) - internal - returns (PostExecToRun[] memory postHooksToRun) - { - HookGroup storage hooks = getAccountStorage().permittedCalls[permittedCallKey].permittedCallHooks; - - return _doPreHooks(hooks, data); - } - function _doPreHooks(HookGroup storage hooks, bytes calldata data) internal returns (PostExecToRun[] memory postHooksToRun) diff --git a/src/interfaces/IAccountLoupe.sol b/src/interfaces/IAccountLoupe.sol index 7cc05afc..267f8e36 100644 --- a/src/interfaces/IAccountLoupe.sol +++ b/src/interfaces/IAccountLoupe.sol @@ -29,15 +29,6 @@ interface IAccountLoupe { /// @return The pre and post execution hooks for this selector function getExecutionHooks(bytes4 selector) external view returns (ExecutionHooks[] memory); - /// @notice Gets the pre and post permitted call hooks applied for a plugin calling this selector - /// @param callingPlugin The plugin that is calling the selector - /// @param selector The selector the plugin is calling - /// @return The pre and post permitted call hooks for this selector - function getPermittedCallHooks(address callingPlugin, bytes4 selector) - external - view - returns (ExecutionHooks[] memory); - /// @notice Gets 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 diff --git a/src/interfaces/IPlugin.sol b/src/interfaces/IPlugin.sol index 654b91b1..c02bc207 100644 --- a/src/interfaces/IPlugin.sol +++ b/src/interfaces/IPlugin.sol @@ -3,8 +3,6 @@ pragma solidity ^0.8.19; import {UserOperation} from "@eth-infinitism/account-abstraction/interfaces/UserOperation.sol"; -import {IPluginManager} from "./IPluginManager.sol"; - // Forge formatter will displace the first comment for the enum field out of the enum itself, // so annotating here to prevent that. // forgefmt: disable-start @@ -95,7 +93,6 @@ struct PluginManifest { ManifestAssociatedFunction[] preUserOpValidationHooks; ManifestAssociatedFunction[] preRuntimeValidationHooks; ManifestExecutionHook[] executionHooks; - ManifestExecutionHook[] permittedCallHooks; } interface IPlugin { @@ -171,28 +168,6 @@ interface IPlugin { /// @param preExecHookData The context returned by its associated pre execution hook. function postExecutionHook(uint8 functionId, bytes calldata preExecHookData) external; - /// @notice A hook that runs when a hook this plugin owns is installed onto another plugin - /// @dev Optional, use to implement any required setup logic - /// @param pluginAppliedOn The plugin that the hook is being applied on - /// @param injectedHooksInfo Contains pre/post exec hook information - /// @param data Any optional data for setup - function onHookApply( - address pluginAppliedOn, - IPluginManager.InjectedHooksInfo calldata injectedHooksInfo, - bytes calldata data - ) external; - - /// @notice A hook that runs when a hook this plugin owns is unapplied from another plugin - /// @dev Optional, use to implement any required unapplied logic - /// @param pluginAppliedOn The plugin that the hook was applied on - /// @param injectedHooksInfo Contains pre/post exec hook information - /// @param data Any optional data for the unapplied call - function onHookUnapply( - address pluginAppliedOn, - IPluginManager.InjectedHooksInfo calldata injectedHooksInfo, - bytes calldata data - ) external; - /// @notice Describe the contents and intended configuration of the plugin. /// @dev This manifest MUST stay constant over time. /// @return A manifest describing the contents and intended configuration of the plugin. diff --git a/src/interfaces/IPluginManager.sol b/src/interfaces/IPluginManager.sol index f2e36f30..100e24bd 100644 --- a/src/interfaces/IPluginManager.sol +++ b/src/interfaces/IPluginManager.sol @@ -5,30 +5,7 @@ import {FunctionReference} from "../helpers/FunctionReferenceLib.sol"; /// @title Plugin Manager Interface interface IPluginManager { - /// @dev Pre/post exec hooks added by the user to limit the scope of a plugin. These hooks are injected at - /// plugin install time - struct InjectedHook { - // The plugin that provides the hook - address providingPlugin; - // Either a plugin-defined execution function, or the native function executeFromPluginExternal - bytes4 selector; - InjectedHooksInfo injectedHooksInfo; - bytes hookApplyData; - } - - struct InjectedHooksInfo { - uint8 preExecHookFunctionId; - bool isPostHookUsed; - uint8 postExecHookFunctionId; - } - - /// @dev Note that we strip hookApplyData from InjectedHooks in this event for gas savings - event PluginInstalled( - address indexed plugin, - bytes32 manifestHash, - FunctionReference[] dependencies, - InjectedHook[] injectedHooks - ); + event PluginInstalled(address indexed plugin, bytes32 manifestHash, FunctionReference[] dependencies); event PluginUninstalled(address indexed plugin, bool indexed callbacksSucceeded); @@ -38,13 +15,11 @@ interface IPluginManager { /// @param pluginInitData Optional data to be decoded and used by the plugin to setup initial plugin data for /// the modular account. /// @param dependencies The dependencies of the plugin, as described in the manifest. - /// @param injectedHooks Optional hooks to be injected over permitted calls this plugin may make. function installPlugin( address plugin, bytes32 manifestHash, bytes calldata pluginInitData, - FunctionReference[] calldata dependencies, - InjectedHook[] calldata injectedHooks + FunctionReference[] calldata dependencies ) external; /// @notice Uninstall a plugin from the modular account. @@ -54,12 +29,5 @@ interface IPluginManager { /// guarantees. /// @param pluginUninstallData Optional data to be decoded and used by the plugin to clear plugin data for the /// modular account. - /// @param hookUnapplyData Optional data to be decoded and used by the plugin to clear injected hooks for the - /// modular account. - function uninstallPlugin( - address plugin, - bytes calldata config, - bytes calldata pluginUninstallData, - bytes[] calldata hookUnapplyData - ) external; + function uninstallPlugin(address plugin, bytes calldata config, bytes calldata pluginUninstallData) external; } diff --git a/src/plugins/BasePlugin.sol b/src/plugins/BasePlugin.sol index a8d610c1..5dbcb2b3 100644 --- a/src/plugins/BasePlugin.sol +++ b/src/plugins/BasePlugin.sol @@ -5,7 +5,6 @@ import {UserOperation} from "@eth-infinitism/account-abstraction/interfaces/User import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {IPlugin, PluginManifest, PluginMetadata} from "../interfaces/IPlugin.sol"; -import {IPluginManager} from "../interfaces/IPluginManager.sol"; /// @title Base contract for plugins /// @dev Implements ERC-165 to support IPlugin's interface, which is a requirement @@ -120,32 +119,6 @@ abstract contract BasePlugin is ERC165, IPlugin { revert NotImplemented(); } - /// @notice A hook that runs when a hook this plugin owns is installed onto another plugin - /// @dev Optional, use to implement any required setup logic - /// @param pluginAppliedOn The plugin that the hook is being applied on - /// @param injectedHooksInfo Contains pre/post exec hook information - /// @param data Any optional data for setup - function onHookApply( - address pluginAppliedOn, - IPluginManager.InjectedHooksInfo calldata injectedHooksInfo, - bytes calldata data - ) external virtual { - (pluginAppliedOn, injectedHooksInfo, data); - } - - /// @notice A hook that runs when a hook this plugin owns is unapplied from another plugin - /// @dev Optional, use to implement any required unapplied logic - /// @param pluginAppliedOn The plugin that the hook was applied on - /// @param injectedHooksInfo Contains pre/post exec hook information - /// @param data Any optional data for the unapplied call - function onHookUnapply( - address pluginAppliedOn, - IPluginManager.InjectedHooksInfo calldata injectedHooksInfo, - bytes calldata data - ) external virtual { - (pluginAppliedOn, injectedHooksInfo, data); - } - /// @notice Describe the contents and intended configuration of the plugin. /// @dev This manifest MUST stay constant over time. /// @return A manifest describing the contents and intended configuration of the plugin. diff --git a/standard/ERCs/ERC6900Diagrams.excalidraw b/standard/ERCs/ERC6900Diagrams.excalidraw index 7e61f29c..aeef2f91 100644 --- a/standard/ERCs/ERC6900Diagrams.excalidraw +++ b/standard/ERCs/ERC6900Diagrams.excalidraw @@ -5,8 +5,8 @@ "elements": [ { "type": "arrow", - "version": 1876, - "versionNonce": 1167256438, + "version": 1879, + "versionNonce": 1917972333, "isDeleted": false, "id": "_ytCEee9buCieGOzh8hfG", "fillStyle": "hachure", @@ -33,7 +33,7 @@ "id": "-WCpVTJBv7vdWdzFT-G7U" } ], - "updated": 1696019192175, + "updated": 1702675727479, "link": null, "locked": false, "startBinding": { @@ -66,8 +66,8 @@ }, { "type": "text", - "version": 111, - "versionNonce": 916481706, + "version": 114, + "versionNonce": 127453667, "isDeleted": false, "id": "-WCpVTJBv7vdWdzFT-G7U", "fillStyle": "hachure", @@ -87,7 +87,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696019192057, + "updated": 1702675727479, "link": null, "locked": false, "fontSize": 20, @@ -102,8 +102,8 @@ }, { "type": "arrow", - "version": 229, - "versionNonce": 988228347, + "version": 232, + "versionNonce": 1922791885, "isDeleted": false, "id": "Z9xv0RDcG3SHnGRBdpQw6", "fillStyle": "hachure", @@ -130,7 +130,7 @@ "id": "QwCpSDg080eu_j-t4hRoB" } ], - "updated": 1696008069399, + "updated": 1702675727480, "link": null, "locked": false, "startBinding": { @@ -159,8 +159,8 @@ }, { "type": "text", - "version": 44, - "versionNonce": 697816277, + "version": 47, + "versionNonce": 843814275, "isDeleted": false, "id": "QwCpSDg080eu_j-t4hRoB", "fillStyle": "hachure", @@ -180,7 +180,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 20, @@ -195,8 +195,8 @@ }, { "type": "arrow", - "version": 5377, - "versionNonce": 1008746491, + "version": 5380, + "versionNonce": 436516909, "isDeleted": false, "id": "D7JyIk96xQktX2XhRN908", "fillStyle": "solid", @@ -225,7 +225,7 @@ "id": "ya9u4mXrA7eXUX_Eb3rwn" } ], - "updated": 1696008069476, + "updated": 1702675727480, "link": null, "locked": false, "startBinding": null, @@ -254,8 +254,8 @@ }, { "type": "text", - "version": 566, - "versionNonce": 933852091, + "version": 569, + "versionNonce": 2145643811, "isDeleted": false, "id": "ya9u4mXrA7eXUX_Eb3rwn", "fillStyle": "solid", @@ -277,7 +277,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 20, @@ -292,8 +292,8 @@ }, { "type": "rectangle", - "version": 2270, - "versionNonce": 2069447771, + "version": 2273, + "versionNonce": 1383541389, "isDeleted": false, "id": "Uo4F0ksGr6qnKqL9MtT-T", "fillStyle": "hachure", @@ -322,14 +322,14 @@ "id": "LfE2aNgSqNhkxG-o0GI0Q" } ], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 998, - "versionNonce": 637927675, + "version": 1001, + "versionNonce": 332419267, "isDeleted": false, "id": "LfE2aNgSqNhkxG-o0GI0Q", "fillStyle": "solid", @@ -351,7 +351,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 28, @@ -366,8 +366,8 @@ }, { "type": "rectangle", - "version": 2645, - "versionNonce": 556935579, + "version": 2648, + "versionNonce": 212619501, "isDeleted": false, "id": "p9kwliQIjDq9rfGPPEdu9", "fillStyle": "solid", @@ -396,14 +396,14 @@ "id": "p-QWheGGfxJTXrDMSdhMg" } ], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 1557, - "versionNonce": 34618939, + "version": 1560, + "versionNonce": 531578979, "isDeleted": false, "id": "p-QWheGGfxJTXrDMSdhMg", "fillStyle": "hachure", @@ -425,7 +425,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 20, @@ -440,8 +440,8 @@ }, { "type": "rectangle", - "version": 4322, - "versionNonce": 327335643, + "version": 4325, + "versionNonce": 1714269005, "isDeleted": false, "id": "kqgAZPqs2y19ugzESaXJh", "fillStyle": "solid", @@ -470,14 +470,14 @@ "id": "t9lZCRl_PPloku6MkbqCy" } ], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 4903, - "versionNonce": 538717051, + "version": 4906, + "versionNonce": 491731971, "isDeleted": false, "id": "t9lZCRl_PPloku6MkbqCy", "fillStyle": "hachure", @@ -499,7 +499,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -514,8 +514,8 @@ }, { "type": "rectangle", - "version": 4342, - "versionNonce": 2082407451, + "version": 4345, + "versionNonce": 257210797, "isDeleted": false, "id": "gf8lqcWfb-bMzahntXjJe", "fillStyle": "solid", @@ -544,14 +544,14 @@ "id": "pjA1kD5KMaeWkavMc9HnO" } ], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 4955, - "versionNonce": 1333643451, + "version": 4958, + "versionNonce": 1219412899, "isDeleted": false, "id": "pjA1kD5KMaeWkavMc9HnO", "fillStyle": "hachure", @@ -573,7 +573,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -588,8 +588,8 @@ }, { "type": "rectangle", - "version": 4640, - "versionNonce": 534444379, + "version": 4643, + "versionNonce": 1900739597, "isDeleted": false, "id": "urIDcg6VICuK9YB8-UK1j", "fillStyle": "solid", @@ -622,14 +622,14 @@ "id": "dVXrKNxRiiJJQInKrp_oQ" } ], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 5498, - "versionNonce": 445191675, + "version": 5501, + "versionNonce": 1509709635, "isDeleted": false, "id": "dVXrKNxRiiJJQInKrp_oQ", "fillStyle": "hachure", @@ -651,7 +651,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.68325562404122, @@ -666,8 +666,8 @@ }, { "type": "rectangle", - "version": 4654, - "versionNonce": 512401051, + "version": 4657, + "versionNonce": 336196205, "isDeleted": false, "id": "FSqrJM9FRySWN10YDIFuH", "fillStyle": "solid", @@ -700,14 +700,14 @@ "id": "RypVZ8-UIGHpFLDqfG5ON" } ], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 5597, - "versionNonce": 110236475, + "version": 5600, + "versionNonce": 2140567267, "isDeleted": false, "id": "RypVZ8-UIGHpFLDqfG5ON", "fillStyle": "hachure", @@ -729,7 +729,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -744,8 +744,8 @@ }, { "type": "rectangle", - "version": 4689, - "versionNonce": 855765979, + "version": 4692, + "versionNonce": 1146821837, "isDeleted": false, "id": "cOXfUgNZg_tHcrz5YL1EK", "fillStyle": "solid", @@ -782,14 +782,14 @@ "id": "UrGJgKGXlIrK1OkLxFW6v" } ], - "updated": 1696008069398, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 5505, - "versionNonce": 1038949819, + "version": 5508, + "versionNonce": 403415683, "isDeleted": false, "id": "UrGJgKGXlIrK1OkLxFW6v", "fillStyle": "hachure", @@ -811,7 +811,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069399, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -826,8 +826,8 @@ }, { "type": "rectangle", - "version": 4294, - "versionNonce": 261598811, + "version": 4297, + "versionNonce": 2044197677, "isDeleted": false, "id": "sZ5VJ5Tm9qLm-Pn9dqDTK", "fillStyle": "hachure", @@ -860,14 +860,14 @@ "id": "h08KPjl9stiOWsPtBIAvr" } ], - "updated": 1696008069399, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 4883, - "versionNonce": 341709723, + "version": 4886, + "versionNonce": 739924515, "isDeleted": false, "id": "h08KPjl9stiOWsPtBIAvr", "fillStyle": "hachure", @@ -889,7 +889,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069400, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -904,8 +904,8 @@ }, { "type": "rectangle", - "version": 4479, - "versionNonce": 1009707067, + "version": 4482, + "versionNonce": 2095713677, "isDeleted": false, "id": "CZ0nwwMN5aoejq59nwYw6", "fillStyle": "hachure", @@ -938,14 +938,14 @@ "id": "hIw2rpP781D77jPLHbyeh" } ], - "updated": 1696008069400, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 5096, - "versionNonce": 1847088507, + "version": 5099, + "versionNonce": 682696131, "isDeleted": false, "id": "hIw2rpP781D77jPLHbyeh", "fillStyle": "hachure", @@ -967,7 +967,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069400, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -982,8 +982,8 @@ }, { "type": "rectangle", - "version": 4367, - "versionNonce": 1292234267, + "version": 4370, + "versionNonce": 1288360941, "isDeleted": false, "id": "Q9dxVc2yraAy0WGA6wtaz", "fillStyle": "solid", @@ -1012,14 +1012,14 @@ "id": "zlTt6bEJ1dNCRBW8oAsdm" } ], - "updated": 1696008069400, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 4983, - "versionNonce": 2012705467, + "version": 4986, + "versionNonce": 1492020579, "isDeleted": false, "id": "zlTt6bEJ1dNCRBW8oAsdm", "fillStyle": "hachure", @@ -1041,7 +1041,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696008069400, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -1056,8 +1056,8 @@ }, { "type": "text", - "version": 226, - "versionNonce": 134232234, + "version": 229, + "versionNonce": 1166265933, "isDeleted": false, "id": "JKbCOE70bA213nULDB-qI", "fillStyle": "solid", @@ -1077,7 +1077,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696012606657, + "updated": 1702675727480, "link": null, "locked": false, "fontSize": 36, @@ -1092,8 +1092,8 @@ }, { "type": "rectangle", - "version": 4867, - "versionNonce": 1690885461, + "version": 5258, + "versionNonce": 478889475, "isDeleted": false, "id": "wrrX0S6-WHJuuOEbJjmdP", "fillStyle": "hachure", @@ -1102,12 +1102,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 3366.456289178628, - "y": 3685.9976832067396, + "x": 3365.996744269759, + "y": 3588.539784995326, "strokeColor": "#1e1e1e", "backgroundColor": "#e9ecef", "width": 276.4419252303366, - "height": 214.21699003088816, + "height": 143.8195503473653, "seed": 1194351317, "groupIds": [ "hnO05DfsJlkB60d2pGzHd", @@ -1125,16 +1125,20 @@ { "type": "text", "id": "ZL19zZgx6g046_V-nbKSx" + }, + { + "id": "v5N3WGcMDaxH5Lz01mJP-", + "type": "arrow" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 5594, - "versionNonce": 1321078395, + "version": 5986, + "versionNonce": 639025379, "isDeleted": false, "id": "ZL19zZgx6g046_V-nbKSx", "fillStyle": "hachure", @@ -1143,8 +1147,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 3382.497388817723, - "y": 3762.999515438086, + "x": 3382.037843908853, + "y": 3630.3428973849113, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 244.35972595214844, @@ -1157,7 +1161,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 26.179706768780477, @@ -1172,8 +1176,8 @@ }, { "type": "rectangle", - "version": 2646, - "versionNonce": 248277685, + "version": 2813, + "versionNonce": 1542630531, "isDeleted": false, "id": "7LtAndnEnv9Y1vpVuVsSR", "fillStyle": "hachure", @@ -1182,12 +1186,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1453.6232929618145, - "y": 3229.0283643682487, + "x": 1453.1637480529453, + "y": 3228.487826785627, "strokeColor": "#1e1e1e", "backgroundColor": "#e9ecef", - "width": 1875.0498046875, - "height": 974, + "width": 1875.0498046874998, + "height": 713.4012029084053, "seed": 964520341, "groupIds": [ "eRSax_tSxeY7Hbq0r54lZ", @@ -1198,14 +1202,14 @@ "type": 3 }, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "rectangle", - "version": 3122, - "versionNonce": 1653376795, + "version": 3328, + "versionNonce": 848307235, "isDeleted": false, "id": "V64RYeLbqd8REancwGi30", "fillStyle": "solid", @@ -1214,12 +1218,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2095.033278089182, - "y": 3253.591505810884, + "x": 2094.573733180313, + "y": 3253.0509682282623, "strokeColor": "#868e96", "backgroundColor": "transparent", "width": 561, - "height": 906, + "height": 637.6446497323419, "seed": 765816565, "groupIds": [ "eRSax_tSxeY7Hbq0r54lZ", @@ -1235,14 +1239,14 @@ "id": "dvGqDtIPx5yZNBHbqUwk8" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 1978, - "versionNonce": 1068977173, + "version": 2010, + "versionNonce": 836609987, "isDeleted": false, "id": "dvGqDtIPx5yZNBHbqUwk8", "fillStyle": "hachure", @@ -1251,8 +1255,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2100.033278089182, - "y": 3258.591505810884, + "x": 2099.573733180313, + "y": 3258.0509682282623, "strokeColor": "#868e96", "backgroundColor": "#e9ecef", "width": 222.65625, @@ -1265,7 +1269,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 20, @@ -1278,51 +1282,10 @@ "lineHeight": 1.2, "baseline": 44 }, - { - "type": "rectangle", - "version": 4993, - "versionNonce": 860023739, - "isDeleted": false, - "id": "CkRbBjs4ahiUVi_DbYV1N", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2120.2109840925677, - "y": 4038.9008761907335, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ebfbee", - "width": 504, - "height": 80, - "seed": 1519646133, - "groupIds": [ - "eRSax_tSxeY7Hbq0r54lZ", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "id": "e5u53tZAP8Du5kPmcWSmz", - "type": "arrow" - }, - { - "type": "text", - "id": "HEW1j_al4fCcxSP3YI9c6" - } - ], - "updated": 1696007898769, - "link": null, - "locked": false - }, { "type": "arrow", - "version": 566, - "versionNonce": 1199505781, + "version": 769, + "versionNonce": 1408020557, "isDeleted": false, "id": "e5u53tZAP8Du5kPmcWSmz", "fillStyle": "hachure", @@ -1331,12 +1294,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2368.7499793414227, - "y": 3256.262832231389, + "x": 2368.2904344325534, + "y": 3255.974880391298, "strokeColor": "#1e1e1e", "backgroundColor": "#343a40", - "width": 0.988320437009861, - "height": 780.0891207610471, + "width": 0, + "height": 499.44015419001653, "seed": 1616213781, "groupIds": [ "9voySmdOp5IZjzr4mw00T" @@ -1346,14 +1309,14 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844832, "link": null, "locked": false, "startBinding": null, "endBinding": { - "focus": -0.00959639433094592, - "gap": 2.548923198297416, - "elementId": "CkRbBjs4ahiUVi_DbYV1N" + "elementId": "g1tnP-RQMvBRecLO4hrec", + "focus": -0.028223809043847782, + "gap": 6.432768797520566 }, "lastCommittedPoint": null, "startArrowhead": null, @@ -1364,54 +1327,15 @@ 0 ], [ - 0.988320437009861, - 780.0891207610471 + 0, + 499.44015419001653 ] ] }, - { - "type": "text", - "version": 5574, - "versionNonce": 889437275, - "isDeleted": false, - "id": "HEW1j_al4fCcxSP3YI9c6", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2213.9285133894427, - "y": 4064.1438786627855, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffd43b", - "width": 316.56494140625, - "height": 29.51399505589567, - "seed": 689949813, - "groupIds": [ - "eRSax_tSxeY7Hbq0r54lZ", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": null, - "boundElements": [], - "updated": 1696007898769, - "link": null, - "locked": false, - "fontSize": 25.664343526865803, - "fontFamily": 2, - "text": "Post Permitted Call Hook(s)", - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "CkRbBjs4ahiUVi_DbYV1N", - "originalText": "Post Permitted Call Hook(s)", - "lineHeight": 1.15, - "baseline": 24 - }, { "type": "rectangle", - "version": 5088, - "versionNonce": 1533610709, + "version": 5187, + "versionNonce": 2066928387, "isDeleted": false, "id": "6AVIvQAFtS5k06SNL7pQN", "fillStyle": "solid", @@ -1420,8 +1344,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2122.902189477476, - "y": 3611.484856805133, + "x": 2122.4426445686067, + "y": 3474.9128848938717, "strokeColor": "#1e1e1e", "backgroundColor": "#ebfbee", "width": 499.87207031250006, @@ -1441,14 +1365,14 @@ "id": "Vguao3AXFlUB5QfEcI4GB" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 5910, - "versionNonce": 866220283, + "version": 6009, + "versionNonce": 1946647203, "isDeleted": false, "id": "Vguao3AXFlUB5QfEcI4GB", "fillStyle": "hachure", @@ -1457,8 +1381,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2244.3881361327494, - "y": 3637.216984821309, + "x": 2243.92859122388, + "y": 3500.6450129100476, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 256.9001770019531, @@ -1471,7 +1395,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 25.68325562404122, @@ -1486,8 +1410,8 @@ }, { "type": "rectangle", - "version": 4866, - "versionNonce": 1812654133, + "version": 4898, + "versionNonce": 656813635, "isDeleted": false, "id": "wBFdRyQG4wrtwbKkyNsa-", "fillStyle": "solid", @@ -1496,8 +1420,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2121.60532366476, - "y": 3328.944206621559, + "x": 2121.1457787558907, + "y": 3328.403669038937, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd8a8", "width": 504, @@ -1517,90 +1441,14 @@ "id": "eh7M474ZHtIVFsP1wiCe9" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "rectangle", - "version": 4791, - "versionNonce": 1553899931, - "isDeleted": false, - "id": "EdxUs4l-3OdZ0q4fgDfZ-", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2121.0654762800677, - "y": 3469.478614923086, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ebfbee", - "width": 504, - "height": 80, - "seed": 868182517, - "groupIds": [ - "eRSax_tSxeY7Hbq0r54lZ", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "WHmIhMXhNEJOG1zd_BaCS" - } - ], - "updated": 1696007898769, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 5394, - "versionNonce": 994711957, - "isDeleted": false, - "id": "WHmIhMXhNEJOG1zd_BaCS", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2220.490097862099, - "y": 3494.721617395138, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffd43b", - "width": 305.1507568359375, - "height": 29.51399505589567, - "seed": 612918101, - "groupIds": [ - "eRSax_tSxeY7Hbq0r54lZ", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": null, - "boundElements": [], - "updated": 1696007898769, - "link": null, - "locked": false, - "fontSize": 25.664343526865803, - "fontFamily": 2, - "text": "Pre Permitted Call Hook(s)", - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "EdxUs4l-3OdZ0q4fgDfZ-", - "originalText": "Pre Permitted Call Hook(s)", - "lineHeight": 1.15, - "baseline": 24 - }, - { - "type": "rectangle", - "version": 5106, - "versionNonce": 153990715, + "version": 5251, + "versionNonce": 1466789347, "isDeleted": false, "id": "3HJCra6w4bVr0zNxhwPIg", "fillStyle": "solid", @@ -1609,8 +1457,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2121.3384838876646, - "y": 3754.9127132857566, + "x": 2120.8789389787953, + "y": 3610.3111080981516, "strokeColor": "#1e1e1e", "backgroundColor": "#e7f5ff", "width": 502.37402343750006, @@ -1630,14 +1478,14 @@ "id": "ZERJbT6aFkj2lpgyJg_py" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 6129, - "versionNonce": 844898037, + "version": 6274, + "versionNonce": 1743501699, "isDeleted": false, "id": "ZERJbT6aFkj2lpgyJg_py", "fillStyle": "hachure", @@ -1646,8 +1494,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2165.7108288583677, - "y": 3780.155715757809, + "x": 2165.2512839494984, + "y": 3635.554110570204, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 413.62933349609375, @@ -1660,7 +1508,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -1675,8 +1523,8 @@ }, { "type": "rectangle", - "version": 5175, - "versionNonce": 1211184859, + "version": 5276, + "versionNonce": 1440715043, "isDeleted": false, "id": "g1tnP-RQMvBRecLO4hrec", "fillStyle": "solid", @@ -1685,8 +1533,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2123.4775596448544, - "y": 3898.4197752900964, + "x": 2123.018014735985, + "y": 3761.847803378835, "strokeColor": "#1e1e1e", "backgroundColor": "#ebfbee", "width": 504.7919921875, @@ -1704,16 +1552,20 @@ { "type": "text", "id": "KSw_CachnmtI50RnLF8T8" + }, + { + "id": "e5u53tZAP8Du5kPmcWSmz", + "type": "arrow" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 5956, - "versionNonce": 2009495637, + "version": 6056, + "versionNonce": 1578230883, "isDeleted": false, "id": "KSw_CachnmtI50RnLF8T8", "fillStyle": "hachure", @@ -1722,8 +1574,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2241.8164573499325, - "y": 3923.662777762149, + "x": 2241.3569124410633, + "y": 3787.0908058508876, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 268.11419677734375, @@ -1736,7 +1588,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -1751,8 +1603,8 @@ }, { "type": "rectangle", - "version": 5252, - "versionNonce": 674997115, + "version": 5284, + "versionNonce": 1069375491, "isDeleted": false, "id": "owBW-NHsmLmREuOjDCv06", "fillStyle": "hachure", @@ -1761,8 +1613,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1919.827396768305, - "y": 2995.8900323464095, + "x": 1919.3678518594359, + "y": 2995.349494763788, "strokeColor": "#1e1e1e", "backgroundColor": "#e9ecef", "width": 1027, @@ -1794,14 +1646,14 @@ "id": "0wUf5TLcOxtybCA5sGvgk" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 5831, - "versionNonce": 1163830709, + "version": 5863, + "versionNonce": 1346881155, "isDeleted": false, "id": "0wUf5TLcOxtybCA5sGvgk", "fillStyle": "hachure", @@ -1810,8 +1662,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2391.2477916657663, - "y": 3021.133034818462, + "x": 2390.788246756897, + "y": 3020.5924972358403, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 84.15921020507812, @@ -1824,7 +1676,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -1839,8 +1691,8 @@ }, { "type": "text", - "version": 5422, - "versionNonce": 1099922459, + "version": 5454, + "versionNonce": 1362230819, "isDeleted": false, "id": "eh7M474ZHtIVFsP1wiCe9", "fillStyle": "hachure", @@ -1849,8 +1701,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2230.9907301589005, - "y": 3354.187209093611, + "x": 2230.5311852500313, + "y": 3353.646671510989, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 285.22918701171875, @@ -1863,7 +1715,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -1878,8 +1730,8 @@ }, { "type": "rectangle", - "version": 3033, - "versionNonce": 2118788885, + "version": 3187, + "versionNonce": 322191811, "isDeleted": false, "id": "dgC4KV1DfhkMlJgqA9-10", "fillStyle": "solid", @@ -1888,12 +1740,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2744.583071580675, - "y": 3243.3177450636776, + "x": 2744.123526671806, + "y": 3243.0297932235867, "strokeColor": "#868e96", "backgroundColor": "transparent", "width": 561, - "height": 906, + "height": 644.5399890942264, "seed": 2065694293, "groupIds": [ "l6R1mFx1IR2gS1u3XMhzL", @@ -1909,14 +1761,14 @@ "id": "X2mj6aKozkky2AGb-AjvT" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 1828, - "versionNonce": 2048187, + "version": 1859, + "versionNonce": 1332547939, "isDeleted": false, "id": "X2mj6aKozkky2AGb-AjvT", "fillStyle": "hachure", @@ -1925,8 +1777,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2749.583071580675, - "y": 3248.3177450636776, + "x": 2749.123526671806, + "y": 3248.0297932235867, "strokeColor": "#868e96", "backgroundColor": "#e9ecef", "width": 316.40625, @@ -1939,7 +1791,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 20, @@ -1954,8 +1806,8 @@ }, { "type": "rectangle", - "version": 5360, - "versionNonce": 83786869, + "version": 5511, + "versionNonce": 388689155, "isDeleted": false, "id": "j7kk61t1I6enSnhuaVZHW", "fillStyle": "solid", @@ -1964,8 +1816,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1496.4190315589342, - "y": 3810.04597266397, + "x": 1495.959486650065, + "y": 3600.1200024504683, "strokeColor": "#1e1e1e", "backgroundColor": "#e7f5ff", "width": 502.37402343750006, @@ -1989,14 +1841,14 @@ "id": "I0BVjvvcb0pq9eafacYOF" } ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 6300, - "versionNonce": 764244315, + "version": 6451, + "versionNonce": 1667221571, "isDeleted": false, "id": "I0BVjvvcb0pq9eafacYOF", "fillStyle": "solid", @@ -2005,8 +1857,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1590.7143196448717, - "y": 3835.2889751360226, + "x": 1590.2547747360024, + "y": 3625.3630049225208, "strokeColor": "#1e1e1e", "backgroundColor": "#e7f5ff", "width": 313.783447265625, @@ -2019,7 +1871,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -2034,8 +1886,8 @@ }, { "type": "arrow", - "version": 1425, - "versionNonce": 1363224021, + "version": 1643, + "versionNonce": 1691140365, "isDeleted": false, "id": "71sd7fDDpQnB-DSlvQqP_", "fillStyle": "hachure", @@ -2044,12 +1896,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1722.4532592099322, - "y": 3804.62605078897, + "x": 1724.2633095662522, + "y": 3594.7000805754683, "strokeColor": "#1e1e1e", "backgroundColor": "transparent", - "width": 449.82764524312324, - "height": 726.4846428651681, + "width": 447.6105712521353, + "height": 517.099210234288, "seed": 279423957, "groupIds": [ "9voySmdOp5IZjzr4mw00T" @@ -2064,18 +1916,18 @@ "id": "vQMow0hQOsdSd58w6eSt-" } ], - "updated": 1696007898769, + "updated": 1702675844832, "link": null, "locked": false, "startBinding": { - "focus": -0.11072774136403482, - "gap": 5.419921875, - "elementId": "j7kk61t1I6enSnhuaVZHW" + "elementId": "j7kk61t1I6enSnhuaVZHW", + "focus": -0.11072774136403453, + "gap": 5.419921875 }, "endBinding": { - "focus": 0.35896729616463313, - "gap": 2.251375577392537, - "elementId": "owBW-NHsmLmREuOjDCv06" + "elementId": "owBW-NHsmLmREuOjDCv06", + "focus": 0.35896729616463297, + "gap": 2.251375577392537 }, "lastCommittedPoint": null, "startArrowhead": null, @@ -2086,19 +1938,19 @@ 0 ], [ - 26.897437384903583, - -414.40030104611196 + 24.627842119714273, + -204.76228267270108 ], [ - 449.82764524312324, - -726.4846428651681 + 447.6105712521353, + -517.099210234288 ] ] }, { "type": "text", - "version": 204, - "versionNonce": 992775675, + "version": 235, + "versionNonce": 1107743619, "isDeleted": false, "id": "vQMow0hQOsdSd58w6eSt-", "fillStyle": "hachure", @@ -2107,8 +1959,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1688.7598762823357, - "y": 3378.725749742858, + "x": 1688.3003313734664, + "y": 3378.437797902767, "strokeColor": "#1e1e1e", "backgroundColor": "transparent", "width": 121.181640625, @@ -2120,7 +1972,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 20, @@ -2135,8 +1987,8 @@ }, { "type": "arrow", - "version": 1259, - "versionNonce": 1177002805, + "version": 1324, + "versionNonce": 487266157, "isDeleted": false, "id": "fA1p68GcpvI-X1krxkJ29", "fillStyle": "hachure", @@ -2145,12 +1997,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2430.1310099468965, - "y": 3077.29693489325, + "x": 2429.71300854141, + "y": 3076.7563973106285, "strokeColor": "#1e1e1e", "backgroundColor": "transparent", - "width": 60.28525289520667, - "height": 177.455836279526, + "width": 60.32679639858952, + "height": 177.70842202205677, "seed": 1477737109, "groupIds": [ "9voySmdOp5IZjzr4mw00T" @@ -2165,13 +2017,13 @@ "id": "eewkGSTDR5u-o_Ui2-P-d" } ], - "updated": 1696007898769, + "updated": 1702675844832, "link": null, "locked": false, "startBinding": { + "elementId": "owBW-NHsmLmREuOjDCv06", "focus": -0.032304772972895926, - "gap": 1.4069025468406835, - "elementId": "owBW-NHsmLmREuOjDCv06" + "gap": 1.4069025468406835 }, "endBinding": null, "lastCommittedPoint": null, @@ -2183,19 +2035,19 @@ 0 ], [ - -39.41983456597109, - 79.92541158565018 + -39.46137806935394, + 80.17799732818094 ], [ - -60.28525289520667, - 177.455836279526 + -60.32679639858952, + 177.70842202205677 ] ] }, { "type": "arrow", - "version": 1416, - "versionNonce": 1275008667, + "version": 1481, + "versionNonce": 1005560269, "isDeleted": false, "id": "W_TcvUOGvsHsXmj31qq0O", "fillStyle": "hachure", @@ -2204,12 +2056,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2661.3253819245097, - "y": 3080.7677615344887, + "x": 2660.660737232135, + "y": 3080.227223951867, "strokeColor": "#1e1e1e", "backgroundColor": "transparent", - "width": 371.3985041865133, - "height": 163.39931175436095, + "width": 371.6036039700187, + "height": 163.6518974968917, "seed": 1764909045, "groupIds": [ "9voySmdOp5IZjzr4mw00T" @@ -2224,13 +2076,13 @@ "id": "4M3fZK70sA3Wdmq1hTmo0" } ], - "updated": 1696007898769, + "updated": 1702675844832, "link": null, "locked": false, "startBinding": { - "focus": -0.23212330297233025, - "gap": 4.877729188079229, - "elementId": "owBW-NHsmLmREuOjDCv06" + "elementId": "owBW-NHsmLmREuOjDCv06", + "focus": -0.23212330297233047, + "gap": 4.877729188079229 }, "endBinding": null, "lastCommittedPoint": null, @@ -2242,19 +2094,19 @@ 0 ], [ - 159.8575034577692, - 79.57808287590842 + 160.0626032412746, + 79.83066861843918 ], [ - 371.3985041865133, - 163.39931175436095 + 371.6036039700187, + 163.6518974968917 ] ] }, { "type": "text", - "version": 561, - "versionNonce": 1209496725, + "version": 592, + "versionNonce": 17514083, "isDeleted": false, "id": "4M3fZK70sA3Wdmq1hTmo0", "fillStyle": "hachure", @@ -2263,8 +2115,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2731.4084269694795, - "y": 3106.911762379147, + "x": 2730.9488820606102, + "y": 3106.623810539056, "strokeColor": "#1e1e1e", "backgroundColor": "transparent", "width": 256.787109375, @@ -2276,7 +2128,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 20, @@ -2291,8 +2143,8 @@ }, { "type": "arrow", - "version": 527, - "versionNonce": 2125957947, + "version": 689, + "versionNonce": 1989402669, "isDeleted": false, "id": "brL7qkGMQvs0CrXMWPV6k", "fillStyle": "solid", @@ -2301,12 +2153,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 3031.5167602061947, - "y": 3245.178330892555, + "x": 3031.0572152973255, + "y": 3244.890379052464, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd8a8", - "width": 2.5472789260270474, - "height": 355.5718025708193, + "width": 2.39808863242979, + "height": 227.61343428810414, "seed": 1515759285, "groupIds": [ "9voySmdOp5IZjzr4mw00T" @@ -2316,14 +2168,14 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844832, "link": null, "locked": false, "startBinding": null, "endBinding": { - "focus": 0.022713880443849654, - "gap": 4.350211855694397, - "elementId": "emDobd4D91UDt1c8oZ0Iu" + "elementId": "emDobd4D91UDt1c8oZ0Iu", + "focus": 0.020886241126229374, + "gap": 4.638163695785352 }, "lastCommittedPoint": null, "startArrowhead": null, @@ -2334,15 +2186,15 @@ 0 ], [ - 2.5472789260270474, - 355.5718025708193 + 2.39808863242979, + 227.61343428810414 ] ] }, { "type": "rectangle", - "version": 4889, - "versionNonce": 314972661, + "version": 4920, + "versionNonce": 631456163, "isDeleted": false, "id": "K34YWjpoqir9H5g1FHSe1", "fillStyle": "solid", @@ -2351,8 +2203,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2772.5234965885907, - "y": 3325.638571674309, + "x": 2772.0639516797214, + "y": 3325.350619834218, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd8a8", "width": 504, @@ -2372,182 +2224,14 @@ "id": "iY-Kdrzz6BF_q5ejZNeWb" } ], - "updated": 1696007898769, - "link": null, - "locked": false - }, - { - "type": "rectangle", - "version": 4822, - "versionNonce": 2008574939, - "isDeleted": false, - "id": "jnxxAJDXEH-AEqCNLfv8t", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2772.412746435112, - "y": 3466.6020772070488, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ebfbee", - "width": 504, - "height": 80, - "seed": 304889205, - "groupIds": [ - "kaCvsneYFck2hOgZrlIGd", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "id": "v5N3WGcMDaxH5Lz01mJP-", - "type": "arrow" - }, - { - "id": "brL7qkGMQvs0CrXMWPV6k", - "type": "arrow" - }, - { - "type": "text", - "id": "Hchc8eIysHRmRuzzLfkuf" - } - ], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false }, { "type": "text", - "version": 5353, - "versionNonce": 1329140565, - "isDeleted": false, - "id": "Hchc8eIysHRmRuzzLfkuf", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2871.837368017143, - "y": 3491.845079679101, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffd43b", - "width": 305.1507568359375, - "height": 29.51399505589567, - "seed": 1427031765, - "groupIds": [ - "kaCvsneYFck2hOgZrlIGd", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": null, - "boundElements": [], - "updated": 1696007898769, - "link": null, - "locked": false, - "fontSize": 25.664343526865803, - "fontFamily": 2, - "text": "Pre Permitted Call Hook(s)", - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "jnxxAJDXEH-AEqCNLfv8t", - "originalText": "Pre Permitted Call Hook(s)", - "lineHeight": 1.15, - "baseline": 24 - }, - { - "type": "rectangle", - "version": 5019, - "versionNonce": 722745467, - "isDeleted": false, - "id": "6WyOgBFugtRt9YYUywk5J", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2771.558254247612, - "y": 4036.0243384746964, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ebfbee", - "width": 504, - "height": 80, - "seed": 563684405, - "groupIds": [ - "kaCvsneYFck2hOgZrlIGd", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "id": "pgbChbCUk0d8sxpAwWrQV", - "type": "arrow" - }, - { - "id": "PRZnICG4U35EUUAZ8urqU", - "type": "arrow" - }, - { - "type": "text", - "id": "lCXzKp_5V6jxaf-mJdx6H" - } - ], - "updated": 1696007898769, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 5534, - "versionNonce": 1774575797, - "isDeleted": false, - "id": "lCXzKp_5V6jxaf-mJdx6H", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 2865.275783544487, - "y": 4061.267340946749, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffd43b", - "width": 316.56494140625, - "height": 29.51399505589567, - "seed": 464573845, - "groupIds": [ - "kaCvsneYFck2hOgZrlIGd", - "9voySmdOp5IZjzr4mw00T" - ], - "frameId": null, - "roundness": null, - "boundElements": [], - "updated": 1696007898769, - "link": null, - "locked": false, - "fontSize": 25.664343526865803, - "fontFamily": 2, - "text": "Post Permitted Call Hook(s)", - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "6WyOgBFugtRt9YYUywk5J", - "originalText": "Post Permitted Call Hook(s)", - "lineHeight": 1.15, - "baseline": 24 - }, - { - "type": "text", - "version": 5377, - "versionNonce": 1720545563, + "version": 5408, + "versionNonce": 1605440835, "isDeleted": false, "id": "iY-Kdrzz6BF_q5ejZNeWb", "fillStyle": "hachure", @@ -2556,8 +2240,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2881.9089030827313, - "y": 3350.8815741463613, + "x": 2881.449358173862, + "y": 3350.5936223062704, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 285.22918701171875, @@ -2570,7 +2254,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -2585,8 +2269,8 @@ }, { "type": "text", - "version": 230, - "versionNonce": 672268821, + "version": 322, + "versionNonce": 1805516899, "isDeleted": false, "id": "wU8WIRfY4Asoodz_lbew8", "fillStyle": "hachure", @@ -2595,8 +2279,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 1494.4717568712122, - "y": 4138.6020016101365, + "x": 1494.012211962343, + "y": 3889.0283071622434, "strokeColor": "#1e1e1e", "backgroundColor": "#343a40", "width": 210.109375, @@ -2608,7 +2292,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675848664, "link": null, "locked": false, "fontSize": 28, @@ -2623,8 +2307,8 @@ }, { "type": "rectangle", - "version": 4381, - "versionNonce": 462853563, + "version": 4384, + "versionNonce": 109050733, "isDeleted": false, "id": "dyY5wNJLDMfWA1ZQCf44b", "fillStyle": "solid", @@ -2653,14 +2337,14 @@ "id": "NEImrhAOddEnqYBljj7im" } ], - "updated": 1696007898769, + "updated": 1702675727480, "link": null, "locked": false }, { "type": "text", - "version": 4975, - "versionNonce": 2131949429, + "version": 4978, + "versionNonce": 505511395, "isDeleted": false, "id": "NEImrhAOddEnqYBljj7im", "fillStyle": "solid", @@ -2682,7 +2366,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -2697,8 +2381,8 @@ }, { "type": "arrow", - "version": 443, - "versionNonce": 1766991451, + "version": 1584, + "versionNonce": 496072941, "isDeleted": false, "id": "v5N3WGcMDaxH5Lz01mJP-", "fillStyle": "solid", @@ -2707,12 +2391,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 3282.088938411237, - "y": 3648.760134488094, + "x": 3290.390288661388, + "y": 3510.778462643316, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd8a8", - "width": 228.9119397354293, - "height": 39.14048180382633, + "width": 205.90515124426474, + "height": 66.16512271080455, "seed": 565164149, "groupIds": [ "9voySmdOp5IZjzr4mw00T" @@ -2722,15 +2406,19 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844832, "link": null, "locked": false, "startBinding": { - "focus": -0.482554883836202, - "gap": 3.451169305937583, - "elementId": "emDobd4D91UDt1c8oZ0Iu" + "elementId": "emDobd4D91UDt1c8oZ0Iu", + "focus": -0.7528434000218625, + "gap": 11.752519556088373 + }, + "endBinding": { + "elementId": "wrrX0S6-WHJuuOEbJjmdP", + "focus": 0.6959808177843592, + "gap": 11.596199641205658 }, - "endBinding": null, "lastCommittedPoint": null, "startArrowhead": null, "endArrowhead": "arrow", @@ -2740,15 +2428,15 @@ 0 ], [ - 228.9119397354293, - 39.14048180382633 + 205.90515124426474, + 66.16512271080455 ] ] }, { "type": "arrow", - "version": 581, - "versionNonce": 688799957, + "version": 1737, + "versionNonce": 923787693, "isDeleted": false, "id": "pgbChbCUk0d8sxpAwWrQV", "fillStyle": "solid", @@ -2757,12 +2445,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 3515.757938830631, - "y": 3904.0694438577184, + "x": 3503.727374698949, + "y": 3744.1126314114044, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd8a8", - "width": 235.1886548189318, - "height": 37.04331561419167, + "width": 223.61763559611836, + "height": 59.40003118220102, "seed": 1013637589, "groupIds": [ "9voySmdOp5IZjzr4mw00T" @@ -2772,18 +2460,18 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844833, "link": null, "locked": false, "startBinding": { - "focus": -0.8745301738225584, - "gap": 3.854770620090676, - "elementId": "wrrX0S6-WHJuuOEbJjmdP" + "elementId": "wrrX0S6-WHJuuOEbJjmdP", + "focus": -0.7689968318604968, + "gap": 11.753296068713098 }, "endBinding": { - "focus": 0.5042849385793888, - "gap": 3.6668664688995705, - "elementId": "Hx9p9aaBWogvW3Z9zujgf" + "elementId": "Hx9p9aaBWogvW3Z9zujgf", + "focus": 0.5431586683722335, + "gap": 3.2073215600312324 }, "lastCommittedPoint": null, "startArrowhead": null, @@ -2794,15 +2482,15 @@ 0 ], [ - -235.1886548189318, - 37.04331561419167 + -223.61763559611836, + 59.40003118220102 ] ] }, { "type": "text", - "version": 448, - "versionNonce": 1442753590, + "version": 451, + "versionNonce": 723502125, "isDeleted": false, "id": "Buf50ccc5LPIs29hfE5LR", "fillStyle": "hachure", @@ -2824,7 +2512,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696012858593, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 36, @@ -2839,8 +2527,8 @@ }, { "type": "text", - "version": 358, - "versionNonce": 2073648693, + "version": 389, + "versionNonce": 655809475, "isDeleted": false, "id": "eewkGSTDR5u-o_Ui2-P-d", "fillStyle": "hachure", @@ -2849,8 +2537,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 2306.0273374903004, - "y": 3098.7660476507754, + "x": 2305.567792581431, + "y": 3098.4780958106844, "strokeColor": "#1e1e1e", "backgroundColor": "transparent", "width": 209.00390625, @@ -2862,7 +2550,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675844745, "link": null, "locked": false, "fontSize": 20, @@ -2877,8 +2565,8 @@ }, { "type": "rectangle", - "version": 5156, - "versionNonce": 735742875, + "version": 5285, + "versionNonce": 609269389, "isDeleted": false, "id": "emDobd4D91UDt1c8oZ0Iu", "fillStyle": "solid", @@ -2888,7 +2576,7 @@ "opacity": 100, "angle": 0, "x": 2778.7656987927994, - "y": 3605.1003453190688, + "y": 3477.1419770363536, "strokeColor": "#1e1e1e", "backgroundColor": "#ebfbee", "width": 499.87207031250006, @@ -2914,16 +2602,20 @@ { "type": "text", "id": "Z8bAiQ8lU0EOMD_k6zJ3s" + }, + { + "id": "PRZnICG4U35EUUAZ8urqU", + "type": "arrow" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 5978, - "versionNonce": 2107232149, + "version": 6105, + "versionNonce": 254117059, "isDeleted": false, "id": "Z8bAiQ8lU0EOMD_k6zJ3s", "fillStyle": "hachure", @@ -2933,7 +2625,7 @@ "opacity": 100, "angle": 0, "x": 2798.9172796033463, - "y": 3630.832473335245, + "y": 3502.87410505253, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 459.56890869140625, @@ -2946,7 +2638,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.68325562404122, @@ -2961,8 +2653,8 @@ }, { "type": "rectangle", - "version": 5248, - "versionNonce": 492593211, + "version": 5375, + "versionNonce": 57957613, "isDeleted": false, "id": "Hx9p9aaBWogvW3Z9zujgf", "fillStyle": "solid", @@ -2972,7 +2664,7 @@ "opacity": 100, "angle": 0, "x": 2772.1104253552994, - "y": 3901.2253453190688, + "y": 3773.2669770363536, "strokeColor": "#1e1e1e", "backgroundColor": "#ebfbee", "width": 504.7919921875, @@ -3000,14 +2692,14 @@ "id": "0m-5Bs8ZQb_5ZWYWgNUul" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 6029, - "versionNonce": 1027937525, + "version": 6156, + "versionNonce": 1648227427, "isDeleted": false, "id": "0m-5Bs8ZQb_5ZWYWgNUul", "fillStyle": "hachure", @@ -3017,7 +2709,7 @@ "opacity": 100, "angle": 0, "x": 2789.1938909314713, - "y": 3926.468347791121, + "y": 3798.5099795084056, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd43b", "width": 470.62506103515625, @@ -3030,7 +2722,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -3045,8 +2737,8 @@ }, { "type": "arrow", - "version": 716, - "versionNonce": 1962582235, + "version": 1397, + "versionNonce": 1611937613, "isDeleted": false, "id": "PRZnICG4U35EUUAZ8urqU", "fillStyle": "solid", @@ -3055,12 +2747,12 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 3028.1453685683714, - "y": 3982.225345319069, + "x": 3033.6299590709195, + "y": 3567.5503510089366, "strokeColor": "#1e1e1e", "backgroundColor": "#ffd8a8", - "width": 0.482639412246499, - "height": 50.79679758967268, + "width": 0, + "height": 192.96307475981394, "seed": 700986229, "groupIds": [ "VmstKptzrPS8VJQe6Z3cM" @@ -3070,18 +2762,18 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { - "focus": -0.0159290699387213, - "gap": 1, - "elementId": "Hx9p9aaBWogvW3Z9zujgf" + "elementId": "emDobd4D91UDt1c8oZ0Iu", + "focus": -0.019717945508694646, + "gap": 9.408373972582922 }, "endBinding": { - "focus": 0.014644164062751281, - "gap": 3.002195565954935, - "elementId": "6WyOgBFugtRt9YYUywk5J" + "elementId": "Hx9p9aaBWogvW3Z9zujgf", + "focus": 0.0361477113863616, + "gap": 12.753551267603143 }, "lastCommittedPoint": null, "startArrowhead": null, @@ -3092,15 +2784,15 @@ 0 ], [ - -0.482639412246499, - 50.79679758967268 + 0, + 192.96307475981394 ] ] }, { "type": "arrow", - "version": 894, - "versionNonce": 32300859, + "version": 897, + "versionNonce": 65499139, "isDeleted": false, "id": "ah8XaJ-YZM10wtm0Z3KuC", "fillStyle": "solid", @@ -3129,7 +2821,7 @@ "id": "FNzFMI0_cw0nr7l8SinUe" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { @@ -3162,8 +2854,8 @@ }, { "type": "text", - "version": 252, - "versionNonce": 121636341, + "version": 255, + "versionNonce": 613008813, "isDeleted": false, "id": "FNzFMI0_cw0nr7l8SinUe", "fillStyle": "solid", @@ -3185,7 +2877,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -3200,8 +2892,8 @@ }, { "type": "arrow", - "version": 549, - "versionNonce": 287522779, + "version": 552, + "versionNonce": 371226531, "isDeleted": false, "id": "k7GLtNrW1DSO03Fl65QJN", "fillStyle": "solid", @@ -3230,7 +2922,7 @@ "id": "nLyXrenK8pvS5s5Pv8zZ8" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": null, @@ -3259,8 +2951,8 @@ }, { "type": "text", - "version": 204, - "versionNonce": 1972731733, + "version": 207, + "versionNonce": 872318989, "isDeleted": false, "id": "nLyXrenK8pvS5s5Pv8zZ8", "fillStyle": "solid", @@ -3282,7 +2974,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -3297,8 +2989,8 @@ }, { "type": "rectangle", - "version": 1427, - "versionNonce": 2013564027, + "version": 1430, + "versionNonce": 1998031683, "isDeleted": false, "id": "-edmlpZAuePulqlGh4jnr", "fillStyle": "hachure", @@ -3327,14 +3019,14 @@ "id": "zadXh4YBV3ANf3BmEhKA9" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 236, - "versionNonce": 1639238837, + "version": 239, + "versionNonce": 1349254765, "isDeleted": false, "id": "zadXh4YBV3ANf3BmEhKA9", "fillStyle": "solid", @@ -3356,7 +3048,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 28, @@ -3371,8 +3063,8 @@ }, { "type": "arrow", - "version": 3097, - "versionNonce": 1515406619, + "version": 3100, + "versionNonce": 992684771, "isDeleted": false, "id": "l9URJp0GwUxs5exP1C_ho", "fillStyle": "solid", @@ -3401,7 +3093,7 @@ "id": "hLjR7_xjylWA6hSwV7a2J" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { @@ -3434,8 +3126,8 @@ }, { "type": "text", - "version": 241, - "versionNonce": 457403925, + "version": 244, + "versionNonce": 1083943117, "isDeleted": false, "id": "hLjR7_xjylWA6hSwV7a2J", "fillStyle": "solid", @@ -3457,7 +3149,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -3472,8 +3164,8 @@ }, { "type": "arrow", - "version": 1058, - "versionNonce": 1065478587, + "version": 1061, + "versionNonce": 1726600835, "isDeleted": false, "id": "-zv2IduSFsqYlNW_-LZ7d", "fillStyle": "hachure", @@ -3502,7 +3194,7 @@ "id": "FN92GLjgfjpxzUdMpaqKm" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { @@ -3531,8 +3223,8 @@ }, { "type": "text", - "version": 223, - "versionNonce": 1630987125, + "version": 226, + "versionNonce": 908527405, "isDeleted": false, "id": "FN92GLjgfjpxzUdMpaqKm", "fillStyle": "solid", @@ -3554,7 +3246,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -3569,8 +3261,8 @@ }, { "type": "rectangle", - "version": 1770, - "versionNonce": 481491547, + "version": 1773, + "versionNonce": 1762790947, "isDeleted": false, "id": "2JLeKLisTh-Vc4SuDVk5b", "fillStyle": "solid", @@ -3599,14 +3291,14 @@ "id": "c4Jb6ictpID4bGcWLcQPx" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 567, - "versionNonce": 2010426581, + "version": 570, + "versionNonce": 1937217933, "isDeleted": false, "id": "c4Jb6ictpID4bGcWLcQPx", "fillStyle": "hachure", @@ -3628,7 +3320,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -3643,8 +3335,8 @@ }, { "type": "rectangle", - "version": 3695, - "versionNonce": 515438331, + "version": 3698, + "versionNonce": 1418875331, "isDeleted": false, "id": "DJhtc3DcLbjMlVyEg7Qk5", "fillStyle": "solid", @@ -3681,14 +3373,14 @@ "id": "gskOWCVwhub3Vut1SFRC8" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4183, - "versionNonce": 2125613621, + "version": 4186, + "versionNonce": 835117037, "isDeleted": false, "id": "gskOWCVwhub3Vut1SFRC8", "fillStyle": "hachure", @@ -3710,7 +3402,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -3725,8 +3417,8 @@ }, { "type": "rectangle", - "version": 3719, - "versionNonce": 873881499, + "version": 3722, + "versionNonce": 1518936419, "isDeleted": false, "id": "waOPxDikvY4nY1xIrkbnY", "fillStyle": "solid", @@ -3759,14 +3451,14 @@ "id": "3kdmtQlZw2sOV-9T3cjGX" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4237, - "versionNonce": 112540565, + "version": 4240, + "versionNonce": 1193171533, "isDeleted": false, "id": "3kdmtQlZw2sOV-9T3cjGX", "fillStyle": "hachure", @@ -3788,7 +3480,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -3803,8 +3495,8 @@ }, { "type": "rectangle", - "version": 3580, - "versionNonce": 1459467323, + "version": 3583, + "versionNonce": 71630083, "isDeleted": false, "id": "FbaoDg0655t05Jdog4zJX", "fillStyle": "solid", @@ -3837,14 +3529,14 @@ "id": "OqUcx-peApViPeKnceQ1y" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4096, - "versionNonce": 1746075893, + "version": 4099, + "versionNonce": 207063213, "isDeleted": false, "id": "OqUcx-peApViPeKnceQ1y", "fillStyle": "hachure", @@ -3866,7 +3558,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -3881,8 +3573,8 @@ }, { "type": "rectangle", - "version": 3924, - "versionNonce": 391214299, + "version": 3927, + "versionNonce": 759456931, "isDeleted": false, "id": "S16C34EtVoZeiYU2mTGYY", "fillStyle": "solid", @@ -3915,14 +3607,14 @@ "id": "eig76WKRoBs08EH9wnTIb" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4692, - "versionNonce": 1481710165, + "version": 4695, + "versionNonce": 52161293, "isDeleted": false, "id": "eig76WKRoBs08EH9wnTIb", "fillStyle": "hachure", @@ -3944,7 +3636,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.68325562404122, @@ -3959,8 +3651,8 @@ }, { "type": "rectangle", - "version": 3746, - "versionNonce": 1688478075, + "version": 3749, + "versionNonce": 1026938947, "isDeleted": false, "id": "uJ0egPTKleB3Aut1HFd2K", "fillStyle": "solid", @@ -3989,14 +3681,14 @@ "id": "Cabcxm3csmoJBvk6rnHEM" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4271, - "versionNonce": 1078265781, + "version": 4274, + "versionNonce": 1004863853, "isDeleted": false, "id": "Cabcxm3csmoJBvk6rnHEM", "fillStyle": "hachure", @@ -4018,7 +3710,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -4033,8 +3725,8 @@ }, { "type": "rectangle", - "version": 3947, - "versionNonce": 406338075, + "version": 3950, + "versionNonce": 569890787, "isDeleted": false, "id": "7Klv-GWoFcKLlBdaExqzT", "fillStyle": "solid", @@ -4067,14 +3759,14 @@ "id": "2mupRG_w95Ad-ICE9xAVE" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4469, - "versionNonce": 1377061141, + "version": 4472, + "versionNonce": 2080132045, "isDeleted": false, "id": "2mupRG_w95Ad-ICE9xAVE", "fillStyle": "hachure", @@ -4096,7 +3788,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -4111,8 +3803,8 @@ }, { "type": "rectangle", - "version": 3945, - "versionNonce": 1056980667, + "version": 3948, + "versionNonce": 161014659, "isDeleted": false, "id": "MgeqVqxIgZLMAtpiB7PXy", "fillStyle": "solid", @@ -4141,14 +3833,14 @@ "id": "_3cmYpf7ZVQUfBjr1cZ5K" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4688, - "versionNonce": 1597267573, + "version": 4691, + "versionNonce": 595282477, "isDeleted": false, "id": "_3cmYpf7ZVQUfBjr1cZ5K", "fillStyle": "hachure", @@ -4170,7 +3862,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -4185,8 +3877,8 @@ }, { "type": "rectangle", - "version": 3942, - "versionNonce": 597602139, + "version": 3945, + "versionNonce": 1549237027, "isDeleted": false, "id": "B5cv9o7mrXd1fXSklT5cE", "fillStyle": "solid", @@ -4223,14 +3915,14 @@ "id": "ZUzVqTJF9WXc5zwtUAGvj" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4681, - "versionNonce": 1852491733, + "version": 4684, + "versionNonce": 1397456013, "isDeleted": false, "id": "ZUzVqTJF9WXc5zwtUAGvj", "fillStyle": "hachure", @@ -4252,7 +3944,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -4267,8 +3959,8 @@ }, { "type": "rectangle", - "version": 3572, - "versionNonce": 409340923, + "version": 3575, + "versionNonce": 1990336195, "isDeleted": false, "id": "HB5dn5VYa-neHknsvZ4Ol", "fillStyle": "hachure", @@ -4305,14 +3997,14 @@ "id": "6pjjnM-U63zx1hYGjs7BU" } ], - "updated": 1696007898769, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4093, - "versionNonce": 298648885, + "version": 4096, + "versionNonce": 1395024621, "isDeleted": false, "id": "6pjjnM-U63zx1hYGjs7BU", "fillStyle": "hachure", @@ -4334,7 +4026,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -4349,8 +4041,8 @@ }, { "type": "rectangle", - "version": 3781, - "versionNonce": 22598811, + "version": 3784, + "versionNonce": 588729955, "isDeleted": false, "id": "edvKEEv-k4BvviRgPKwsm", "fillStyle": "hachure", @@ -4383,14 +4075,14 @@ "id": "RvZu-T5Ja9YEGXEbx6kHc" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4309, - "versionNonce": 2092996245, + "version": 4312, + "versionNonce": 932543821, "isDeleted": false, "id": "RvZu-T5Ja9YEGXEbx6kHc", "fillStyle": "hachure", @@ -4412,7 +4104,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -4427,8 +4119,8 @@ }, { "type": "rectangle", - "version": 3794, - "versionNonce": 506038587, + "version": 3797, + "versionNonce": 1418037763, "isDeleted": false, "id": "qLT39tSOFDyxvMCmG5W1h", "fillStyle": "hachure", @@ -4457,14 +4149,14 @@ "id": "0dHwYcUvJ3Q_ePvIskX-5" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4321, - "versionNonce": 1509620725, + "version": 4324, + "versionNonce": 1207061421, "isDeleted": false, "id": "0dHwYcUvJ3Q_ePvIskX-5", "fillStyle": "hachure", @@ -4486,7 +4178,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -4501,8 +4193,8 @@ }, { "type": "arrow", - "version": 499, - "versionNonce": 339388891, + "version": 502, + "versionNonce": 535515555, "isDeleted": false, "id": "-NzlYGG66X7oQO2XqQg7f", "fillStyle": "solid", @@ -4526,7 +4218,7 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { @@ -4555,8 +4247,8 @@ }, { "type": "arrow", - "version": 1009, - "versionNonce": 1635890517, + "version": 1012, + "versionNonce": 610684429, "isDeleted": false, "id": "sIEaXz7X0HH_XKMtk71oD", "fillStyle": "solid", @@ -4585,7 +4277,7 @@ "id": "uVRbiGUSu8a2UUW-wkzxx" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { @@ -4618,8 +4310,8 @@ }, { "type": "text", - "version": 294, - "versionNonce": 949925499, + "version": 297, + "versionNonce": 1987519811, "isDeleted": false, "id": "uVRbiGUSu8a2UUW-wkzxx", "fillStyle": "solid", @@ -4641,7 +4333,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -4656,8 +4348,8 @@ }, { "type": "arrow", - "version": 625, - "versionNonce": 782910133, + "version": 628, + "versionNonce": 736822381, "isDeleted": false, "id": "I0Ccg7Wsxj6_GqOmEu1Qc", "fillStyle": "solid", @@ -4686,7 +4378,7 @@ "id": "FMZrMZEPVJGahIyiYFMJp" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": null, @@ -4715,8 +4407,8 @@ }, { "type": "text", - "version": 249, - "versionNonce": 437792539, + "version": 252, + "versionNonce": 528975075, "isDeleted": false, "id": "FMZrMZEPVJGahIyiYFMJp", "fillStyle": "solid", @@ -4738,7 +4430,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -4753,8 +4445,8 @@ }, { "type": "rectangle", - "version": 1462, - "versionNonce": 1444553749, + "version": 1465, + "versionNonce": 575270605, "isDeleted": false, "id": "T2b9hWMIm83e2qE2Snv-K", "fillStyle": "hachure", @@ -4783,14 +4475,14 @@ "id": "CDvDV_-pPxW5pzo8rF05D" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 269, - "versionNonce": 1259967419, + "version": 272, + "versionNonce": 1923805315, "isDeleted": false, "id": "CDvDV_-pPxW5pzo8rF05D", "fillStyle": "solid", @@ -4812,7 +4504,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 28, @@ -4827,8 +4519,8 @@ }, { "type": "arrow", - "version": 3951, - "versionNonce": 1002887541, + "version": 3954, + "versionNonce": 370969901, "isDeleted": false, "id": "hcuAjvJD_cPXzv_R-AyiQ", "fillStyle": "solid", @@ -4857,7 +4549,7 @@ "id": "G_5orqWAUTGNwzRQ06Wrl" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { @@ -4890,8 +4582,8 @@ }, { "type": "text", - "version": 275, - "versionNonce": 1808098395, + "version": 278, + "versionNonce": 1369434147, "isDeleted": false, "id": "G_5orqWAUTGNwzRQ06Wrl", "fillStyle": "solid", @@ -4913,7 +4605,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -4928,8 +4620,8 @@ }, { "type": "arrow", - "version": 1173, - "versionNonce": 687203029, + "version": 1176, + "versionNonce": 114057101, "isDeleted": false, "id": "FHPm9dVVa2yBOxWG18hU0", "fillStyle": "hachure", @@ -4958,7 +4650,7 @@ "id": "uJ3JqkFXcJ7qY1WUA6SEj" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "startBinding": { @@ -4987,8 +4679,8 @@ }, { "type": "text", - "version": 257, - "versionNonce": 1944985851, + "version": 260, + "versionNonce": 1649732547, "isDeleted": false, "id": "uJ3JqkFXcJ7qY1WUA6SEj", "fillStyle": "solid", @@ -5010,7 +4702,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -5025,8 +4717,8 @@ }, { "type": "rectangle", - "version": 1805, - "versionNonce": 574406709, + "version": 1808, + "versionNonce": 1251141101, "isDeleted": false, "id": "h4-dGWuBPeBT6vEznfNUa", "fillStyle": "solid", @@ -5055,14 +4747,14 @@ "id": "xPapOAgJdVbp3KPBjp72W" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 576, - "versionNonce": 1024870811, + "version": 579, + "versionNonce": 149453667, "isDeleted": false, "id": "xPapOAgJdVbp3KPBjp72W", "fillStyle": "hachure", @@ -5084,7 +4776,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 20, @@ -5099,8 +4791,8 @@ }, { "type": "rectangle", - "version": 3730, - "versionNonce": 2105602453, + "version": 3733, + "versionNonce": 880386125, "isDeleted": false, "id": "o5hOmM7TAHOCcjcQjmxT0", "fillStyle": "solid", @@ -5137,14 +4829,14 @@ "id": "k4tu8MUi99dHXdDT7IqoO" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4218, - "versionNonce": 1282432571, + "version": 4221, + "versionNonce": 564729603, "isDeleted": false, "id": "k4tu8MUi99dHXdDT7IqoO", "fillStyle": "hachure", @@ -5166,7 +4858,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5181,8 +4873,8 @@ }, { "type": "rectangle", - "version": 3754, - "versionNonce": 938997493, + "version": 3757, + "versionNonce": 2052722349, "isDeleted": false, "id": "NIkgQJ6gbFBmrMnTcKvT7", "fillStyle": "solid", @@ -5215,14 +4907,14 @@ "id": "q74BsXiYYSqL64DaoH_3S" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4272, - "versionNonce": 1558109915, + "version": 4275, + "versionNonce": 2064989859, "isDeleted": false, "id": "q74BsXiYYSqL64DaoH_3S", "fillStyle": "hachure", @@ -5244,7 +4936,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5259,8 +4951,8 @@ }, { "type": "rectangle", - "version": 3615, - "versionNonce": 203903061, + "version": 3618, + "versionNonce": 1524478221, "isDeleted": false, "id": "6OoAPkiyTgQUDfn6tkniN", "fillStyle": "solid", @@ -5293,14 +4985,14 @@ "id": "_mweY2D1YGvT2NMZ4TA2D" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4131, - "versionNonce": 687098747, + "version": 4134, + "versionNonce": 266039875, "isDeleted": false, "id": "_mweY2D1YGvT2NMZ4TA2D", "fillStyle": "hachure", @@ -5322,7 +5014,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5337,8 +5029,8 @@ }, { "type": "rectangle", - "version": 3959, - "versionNonce": 1206156725, + "version": 3962, + "versionNonce": 58591085, "isDeleted": false, "id": "hLAYChCJ7cbUGCO6OmYuo", "fillStyle": "solid", @@ -5371,14 +5063,14 @@ "id": "C3rirnXV1IvE-1uHnRMqf" } ], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false }, { "type": "text", - "version": 4727, - "versionNonce": 1962091547, + "version": 4730, + "versionNonce": 14299619, "isDeleted": false, "id": "C3rirnXV1IvE-1uHnRMqf", "fillStyle": "hachure", @@ -5400,7 +5092,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727481, "link": null, "locked": false, "fontSize": 25.68325562404122, @@ -5415,8 +5107,8 @@ }, { "type": "rectangle", - "version": 3780, - "versionNonce": 1649737493, + "version": 3783, + "versionNonce": 914657741, "isDeleted": false, "id": "2tiy_HH9LYxsFnORyo1QN", "fillStyle": "solid", @@ -5445,14 +5137,14 @@ "id": "vaV8yoVMVsaZhdkOPyCf0" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4304, - "versionNonce": 1489889467, + "version": 4307, + "versionNonce": 1327496579, "isDeleted": false, "id": "vaV8yoVMVsaZhdkOPyCf0", "fillStyle": "hachure", @@ -5474,7 +5166,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5489,8 +5181,8 @@ }, { "type": "rectangle", - "version": 3982, - "versionNonce": 1374573685, + "version": 3985, + "versionNonce": 822792237, "isDeleted": false, "id": "T7fYn-6m0AnnYUsZ7Vu-6", "fillStyle": "solid", @@ -5523,14 +5215,14 @@ "id": "qnJpizQgl8MhtDXqKrw3P" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4504, - "versionNonce": 1244076379, + "version": 4507, + "versionNonce": 1441486115, "isDeleted": false, "id": "qnJpizQgl8MhtDXqKrw3P", "fillStyle": "hachure", @@ -5552,7 +5244,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5567,8 +5259,8 @@ }, { "type": "rectangle", - "version": 3980, - "versionNonce": 578158037, + "version": 3983, + "versionNonce": 1358578317, "isDeleted": false, "id": "Sj8y2LMf6pefmYIQqny_R", "fillStyle": "solid", @@ -5597,14 +5289,14 @@ "id": "03Fmfd8QZvQY4bhg1BiML" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4763, - "versionNonce": 1716598267, + "version": 4766, + "versionNonce": 78297283, "isDeleted": false, "id": "03Fmfd8QZvQY4bhg1BiML", "fillStyle": "hachure", @@ -5626,7 +5318,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5641,8 +5333,8 @@ }, { "type": "rectangle", - "version": 3977, - "versionNonce": 1258388277, + "version": 3980, + "versionNonce": 2064410861, "isDeleted": false, "id": "60Bg_Unnxatm5Ly-ec3vC", "fillStyle": "solid", @@ -5679,14 +5371,14 @@ "id": "_X8LFfztzp-bigggpmj_4" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4716, - "versionNonce": 2085535387, + "version": 4719, + "versionNonce": 1492953187, "isDeleted": false, "id": "_X8LFfztzp-bigggpmj_4", "fillStyle": "hachure", @@ -5708,7 +5400,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5723,8 +5415,8 @@ }, { "type": "rectangle", - "version": 3610, - "versionNonce": 1140214933, + "version": 3613, + "versionNonce": 1087030093, "isDeleted": false, "id": "wOPRhb271x7_3GHMLCQLT", "fillStyle": "hachure", @@ -5761,14 +5453,14 @@ "id": "PWxqbOaXygGZ1-S4Pxi6K" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4128, - "versionNonce": 1456616251, + "version": 4131, + "versionNonce": 414163971, "isDeleted": false, "id": "PWxqbOaXygGZ1-S4Pxi6K", "fillStyle": "hachure", @@ -5790,7 +5482,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5805,8 +5497,8 @@ }, { "type": "rectangle", - "version": 3817, - "versionNonce": 1560932853, + "version": 3820, + "versionNonce": 1183764909, "isDeleted": false, "id": "K_A6UfauIPuac0Oj9KHlp", "fillStyle": "hachure", @@ -5839,14 +5531,14 @@ "id": "xUEb7MT7QxHrLB-6Zd9XY" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4344, - "versionNonce": 1178473435, + "version": 4347, + "versionNonce": 1271016355, "isDeleted": false, "id": "xUEb7MT7QxHrLB-6Zd9XY", "fillStyle": "hachure", @@ -5868,7 +5560,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5883,8 +5575,8 @@ }, { "type": "rectangle", - "version": 3830, - "versionNonce": 1396829013, + "version": 3833, + "versionNonce": 1770132493, "isDeleted": false, "id": "UIOBlFmO5FdF3hqajkL-P", "fillStyle": "hachure", @@ -5913,14 +5605,14 @@ "id": "2ZogVDPYseeLDZUUs4Jeo" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4356, - "versionNonce": 1789190267, + "version": 4359, + "versionNonce": 1986182979, "isDeleted": false, "id": "2ZogVDPYseeLDZUUs4Jeo", "fillStyle": "hachure", @@ -5942,7 +5634,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -5957,8 +5649,8 @@ }, { "type": "arrow", - "version": 609, - "versionNonce": 653506741, + "version": 612, + "versionNonce": 631114349, "isDeleted": false, "id": "eP3iWhpbJlcpQxZeHEF5S", "fillStyle": "solid", @@ -5982,7 +5674,7 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": { @@ -6011,8 +5703,8 @@ }, { "type": "text", - "version": 295, - "versionNonce": 186689429, + "version": 298, + "versionNonce": 317710051, "isDeleted": false, "id": "wuJXG39eQORHr0IZvBJ7z", "fillStyle": "solid", @@ -6032,7 +5724,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 36, @@ -6047,8 +5739,8 @@ }, { "type": "arrow", - "version": 3930, - "versionNonce": 844040251, + "version": 3933, + "versionNonce": 1001141453, "isDeleted": false, "id": "-aCpWJ3yLdM3yVKCyeuEp", "fillStyle": "solid", @@ -6077,7 +5769,7 @@ "id": "N3D1ONhwcwNLib7XcEmAv" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": null, @@ -6106,8 +5798,8 @@ }, { "type": "text", - "version": 437, - "versionNonce": 607186165, + "version": 440, + "versionNonce": 1274546819, "isDeleted": false, "id": "N3D1ONhwcwNLib7XcEmAv", "fillStyle": "solid", @@ -6129,7 +5821,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 20, @@ -6144,8 +5836,8 @@ }, { "type": "arrow", - "version": 1149, - "versionNonce": 626542811, + "version": 1152, + "versionNonce": 390468397, "isDeleted": false, "id": "dAmBT3VTsNnmQaqteaKWr", "fillStyle": "hachure", @@ -6169,7 +5861,7 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": null, @@ -6194,8 +5886,8 @@ }, { "type": "arrow", - "version": 3246, - "versionNonce": 835814997, + "version": 3249, + "versionNonce": 1983496739, "isDeleted": false, "id": "5NuJZrbBlWAWb-OQVM6u8", "fillStyle": "hachure", @@ -6219,7 +5911,7 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": { @@ -6248,8 +5940,8 @@ }, { "type": "arrow", - "version": 1090, - "versionNonce": 850425211, + "version": 1093, + "versionNonce": 1960125837, "isDeleted": false, "id": "7aNJV3mAZct-sbiLj3CKp", "fillStyle": "hachure", @@ -6273,7 +5965,7 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": null, @@ -6298,8 +5990,8 @@ }, { "type": "arrow", - "version": 3181, - "versionNonce": 1725428661, + "version": 3184, + "versionNonce": 1252230595, "isDeleted": false, "id": "Qafx8eR5O9vg_cGPVG_R1", "fillStyle": "hachure", @@ -6323,7 +6015,7 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": { @@ -6352,8 +6044,8 @@ }, { "type": "rectangle", - "version": 2039, - "versionNonce": 2137634069, + "version": 2042, + "versionNonce": 1200810989, "isDeleted": false, "id": "xx3Kx6sy18wOEvXiXRUNq", "fillStyle": "hachure", @@ -6382,14 +6074,14 @@ "id": "DikkjvZL519dtEYTGEVih" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 818, - "versionNonce": 1292341947, + "version": 821, + "versionNonce": 1616106851, "isDeleted": false, "id": "DikkjvZL519dtEYTGEVih", "fillStyle": "solid", @@ -6411,7 +6103,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 28, @@ -6426,8 +6118,8 @@ }, { "type": "rectangle", - "version": 2610, - "versionNonce": 385632885, + "version": 2613, + "versionNonce": 1602807373, "isDeleted": false, "id": "7WiUDAtLI3wHa47TaaPgY", "fillStyle": "solid", @@ -6456,14 +6148,14 @@ "id": "lL4f35LnDc_IgUjjqR3qJ" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 1417, - "versionNonce": 496730971, + "version": 1420, + "versionNonce": 1721315587, "isDeleted": false, "id": "lL4f35LnDc_IgUjjqR3qJ", "fillStyle": "hachure", @@ -6485,7 +6177,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 20, @@ -6500,8 +6192,8 @@ }, { "type": "rectangle", - "version": 4272, - "versionNonce": 1045771221, + "version": 4275, + "versionNonce": 1334875309, "isDeleted": false, "id": "bHbBQbGNhNPa0TVIrwplS", "fillStyle": "solid", @@ -6538,14 +6230,14 @@ "id": "rfR_Y40E8jP7mHWt3X695" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4762, - "versionNonce": 1671979003, + "version": 4765, + "versionNonce": 519182499, "isDeleted": false, "id": "rfR_Y40E8jP7mHWt3X695", "fillStyle": "hachure", @@ -6567,7 +6259,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -6582,8 +6274,8 @@ }, { "type": "rectangle", - "version": 4296, - "versionNonce": 1367994677, + "version": 4299, + "versionNonce": 324237069, "isDeleted": false, "id": "f-4v7ARoKe0UHrdk4rAOW", "fillStyle": "solid", @@ -6616,14 +6308,14 @@ "id": "Yhv272uMUjk4c_xyBCy5G" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4818, - "versionNonce": 1496361115, + "version": 4821, + "versionNonce": 386731075, "isDeleted": false, "id": "Yhv272uMUjk4c_xyBCy5G", "fillStyle": "hachure", @@ -6645,7 +6337,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -6660,8 +6352,8 @@ }, { "type": "arrow", - "version": 3200, - "versionNonce": 234881685, + "version": 3203, + "versionNonce": 1967852909, "isDeleted": false, "id": "2CZ2w1jWP98Z7YI3JDVht", "fillStyle": "hachure", @@ -6690,7 +6382,7 @@ "id": "BALWsaFLjYbg-jdqBo6tX" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": { @@ -6723,8 +6415,8 @@ }, { "type": "text", - "version": 871, - "versionNonce": 1407638843, + "version": 874, + "versionNonce": 583568355, "isDeleted": false, "id": "BALWsaFLjYbg-jdqBo6tX", "fillStyle": "solid", @@ -6746,7 +6438,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 20, @@ -6761,8 +6453,8 @@ }, { "type": "rectangle", - "version": 2408, - "versionNonce": 1751967733, + "version": 2411, + "versionNonce": 885053389, "isDeleted": false, "id": "ejh1h99xkb4w1wuTImtiK", "fillStyle": "solid", @@ -6791,14 +6483,14 @@ "id": "ASrbmuiUQ7TdqLYY0O847" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 1207, - "versionNonce": 1328381403, + "version": 1210, + "versionNonce": 372447107, "isDeleted": false, "id": "ASrbmuiUQ7TdqLYY0O847", "fillStyle": "hachure", @@ -6820,7 +6512,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 20, @@ -6835,8 +6527,8 @@ }, { "type": "rectangle", - "version": 4149, - "versionNonce": 584458581, + "version": 4152, + "versionNonce": 1808684589, "isDeleted": false, "id": "ke-318gOicLdVN2-1RqkP", "fillStyle": "solid", @@ -6865,14 +6557,14 @@ "id": "g4EkOdJh3tBgKvZWvkrUa" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4669, - "versionNonce": 907479675, + "version": 4672, + "versionNonce": 1066086179, "isDeleted": false, "id": "g4EkOdJh3tBgKvZWvkrUa", "fillStyle": "hachure", @@ -6894,7 +6586,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -6909,8 +6601,8 @@ }, { "type": "rectangle", - "version": 4499, - "versionNonce": 579940021, + "version": 4502, + "versionNonce": 895289485, "isDeleted": false, "id": "yJQTdY_MWUNTZ1z8ev19l", "fillStyle": "solid", @@ -6939,14 +6631,14 @@ "id": "CwRQaD6uW6pMBa7a7rBxi" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 5265, - "versionNonce": 1835402011, + "version": 5268, + "versionNonce": 557798083, "isDeleted": false, "id": "CwRQaD6uW6pMBa7a7rBxi", "fillStyle": "hachure", @@ -6968,7 +6660,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.68325562404122, @@ -6983,8 +6675,8 @@ }, { "type": "rectangle", - "version": 4314, - "versionNonce": 105091093, + "version": 4317, + "versionNonce": 321285869, "isDeleted": false, "id": "nRphpmIcy3EX_IGX20jVG", "fillStyle": "solid", @@ -7013,14 +6705,14 @@ "id": "YjEKKgWNQCLsdFbN-zwYp" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4856, - "versionNonce": 495773627, + "version": 4859, + "versionNonce": 1810760291, "isDeleted": false, "id": "YjEKKgWNQCLsdFbN-zwYp", "fillStyle": "hachure", @@ -7042,7 +6734,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -7057,8 +6749,8 @@ }, { "type": "rectangle", - "version": 4518, - "versionNonce": 2078459253, + "version": 4521, + "versionNonce": 330565965, "isDeleted": false, "id": "OoFc6z-xHGoh7XpGdfHmr", "fillStyle": "solid", @@ -7091,14 +6783,14 @@ "type": "arrow" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 5044, - "versionNonce": 1018050651, + "version": 5047, + "versionNonce": 946191875, "isDeleted": false, "id": "WX3lUQoINCDwyc9OpW-t-", "fillStyle": "hachure", @@ -7120,7 +6812,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -7135,8 +6827,8 @@ }, { "type": "rectangle", - "version": 4517, - "versionNonce": 1454657237, + "version": 4520, + "versionNonce": 945772461, "isDeleted": false, "id": "WvQ3bzf-GxctLR18JjDBV", "fillStyle": "solid", @@ -7165,14 +6857,14 @@ "id": "ZgFSX0WOC0h8EyqBWrYZ0" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 5305, - "versionNonce": 1486648571, + "version": 5308, + "versionNonce": 27592099, "isDeleted": false, "id": "ZgFSX0WOC0h8EyqBWrYZ0", "fillStyle": "hachure", @@ -7194,7 +6886,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -7209,8 +6901,8 @@ }, { "type": "rectangle", - "version": 4522, - "versionNonce": 1699589173, + "version": 4525, + "versionNonce": 458349069, "isDeleted": false, "id": "JCKmoUtfRxrmmGObZ569q", "fillStyle": "solid", @@ -7247,14 +6939,14 @@ "type": "arrow" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 5254, - "versionNonce": 551165339, + "version": 5257, + "versionNonce": 1591368003, "isDeleted": false, "id": "n0u1Qef4WUYRjBRO1GmX8", "fillStyle": "hachure", @@ -7276,7 +6968,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -7291,8 +6983,8 @@ }, { "type": "rectangle", - "version": 4243, - "versionNonce": 127163797, + "version": 4246, + "versionNonce": 1434783853, "isDeleted": false, "id": "_YZlFSQ1zBrJaemyAin_Y", "fillStyle": "solid", @@ -7325,14 +7017,14 @@ "id": "SVy1vDyqZpS3HFsvYTtgb" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4745, - "versionNonce": 815379003, + "version": 4748, + "versionNonce": 2103720163, "isDeleted": false, "id": "SVy1vDyqZpS3HFsvYTtgb", "fillStyle": "hachure", @@ -7354,7 +7046,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -7369,8 +7061,8 @@ }, { "type": "rectangle", - "version": 4438, - "versionNonce": 79553269, + "version": 4441, + "versionNonce": 616725197, "isDeleted": false, "id": "z0PQi5SHJSaXnv89mfZP7", "fillStyle": "solid", @@ -7403,14 +7095,14 @@ "type": "arrow" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4961, - "versionNonce": 415085275, + "version": 4964, + "versionNonce": 1523655811, "isDeleted": false, "id": "F7rW_NHcrjEbjX7AZzpVM", "fillStyle": "hachure", @@ -7432,7 +7124,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -7447,8 +7139,8 @@ }, { "type": "rectangle", - "version": 4446, - "versionNonce": 558873685, + "version": 4449, + "versionNonce": 1369676077, "isDeleted": false, "id": "9PEiLoAhsOByWsJZ9OKS9", "fillStyle": "solid", @@ -7481,14 +7173,14 @@ "type": "arrow" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4973, - "versionNonce": 702062459, + "version": 4976, + "versionNonce": 1054841891, "isDeleted": false, "id": "ICxPb20vO7yBcMSUHSe1W", "fillStyle": "hachure", @@ -7510,7 +7202,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, @@ -7525,8 +7217,8 @@ }, { "type": "arrow", - "version": 2259, - "versionNonce": 1964992949, + "version": 2262, + "versionNonce": 1435626381, "isDeleted": false, "id": "nqhZ-8vjQ3h-_3nYJ0U9k", "fillStyle": "solid", @@ -7550,7 +7242,7 @@ "type": 2 }, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "startBinding": { @@ -7579,8 +7271,8 @@ }, { "type": "rectangle", - "version": 4383, - "versionNonce": 2116876315, + "version": 4386, + "versionNonce": 1971199939, "isDeleted": false, "id": "S3jaS7lY7njUd4iFC2CvV", "fillStyle": "solid", @@ -7613,14 +7305,14 @@ "id": "LEnV0ZvIMFDWFqLrs2JCH" } ], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false }, { "type": "text", - "version": 4881, - "versionNonce": 22178581, + "version": 4884, + "versionNonce": 1086779885, "isDeleted": false, "id": "LEnV0ZvIMFDWFqLrs2JCH", "fillStyle": "hachure", @@ -7642,7 +7334,7 @@ "frameId": null, "roundness": null, "boundElements": [], - "updated": 1696007898770, + "updated": 1702675727482, "link": null, "locked": false, "fontSize": 25.664343526865803, diff --git a/standard/ERCs/erc-6900.md b/standard/ERCs/erc-6900.md index 24e8dd02..8487d6ef 100644 --- a/standard/ERCs/erc-6900.md +++ b/standard/ERCs/erc-6900.md @@ -106,29 +106,7 @@ Plugin manager interface. Modular Smart Contract Accounts **MUST** implement thi ```solidity interface IPluginManager { - // Pre/post exec hooks added by the user to limit the scope a plugin has - // These hooks are injected at plugin install time - struct InjectedHook { - // The plugin that provides the hook - address providingPlugin; - // Either a plugin-defined execution function, or the native function executeFromPluginExternal - bytes4 selector; - InjectedHooksInfo injectedHooksInfo; - bytes hookApplyData; - } - - struct InjectedHooksInfo { - uint8 preExecHookFunctionId; - bool isPostHookUsed; - uint8 postExecHookFunctionId; - } - - event PluginInstalled( - address indexed plugin, - bytes32 manifestHash, - FunctionReference[] dependencies, - InjectedHook[] injectedHooks - ); + event PluginInstalled(address indexed plugin, bytes32 manifestHash, FunctionReference[] dependencies); event PluginUninstalled(address indexed plugin, bool indexed callbacksSucceeded); @@ -138,13 +116,11 @@ interface IPluginManager { /// @param pluginInitData Optional data to be decoded and used by the plugin to setup initial plugin data for /// the modular account. /// @param dependencies The dependencies of the plugin, as described in the manifest. - /// @param injectedHooks Optional hooks to be injected over permitted calls this plugin may make. function installPlugin( address plugin, bytes32 manifestHash, bytes calldata pluginInitData, - address[] calldata dependencies, - InjectedHook[] calldata injectedHooks + FunctionReference[] calldata dependencies ) external; /// @notice Uninstall a plugin from the modular account. @@ -153,14 +129,7 @@ interface IPluginManager { /// guarantees. /// @param pluginUninstallData Optional data to be decoded and used by the plugin to clear plugin data for the /// modular account. - /// @param hookUnapplyData Optional data to be decoded and used by the plugin to clear injected hooks for the - /// modular account. - function uninstallPlugin( - address plugin, - bytes calldata config, - bytes calldata pluginUninstallData, - bytes[] calldata hookUnapplyData - ) external; + function uninstallPlugin(address plugin, bytes calldata config, bytes calldata pluginUninstallData) external; } ``` @@ -260,15 +229,6 @@ interface IAccountLoupe { /// @return The pre and post execution hooks for this selector function getExecutionHooks(bytes4 selector) external view returns (ExecutionHooks[] memory); - /// @notice Gets the pre and post permitted call hooks applied for a plugin calling this selector - /// @param callingPlugin The plugin that is calling the selector - /// @param selector The selector the plugin is calling - /// @return The pre and post permitted call hooks for this selector - function getPermittedCallHooks(address callingPlugin, bytes4 selector) - external - view - returns (ExecutionHooks[] memory); - /// @notice Gets 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 @@ -303,28 +263,6 @@ interface IPlugin { /// @param data Optional bytes array to be decoded and used by the plugin to clear plugin data for the modular account. function onUninstall(bytes calldata data) external; - /// @notice A hook that runs when a hook this plugin owns is installed onto another plugin - /// @dev Optional, use to implement any required setup logic - /// @param pluginAppliedOn The plugin that the hook is being applied on - /// @param injectedHooksInfo Contains pre/post exec hook information - /// @param data Any optional data for setup - function onHookApply( - address pluginAppliedOn, - IPluginManager.InjectedHooksInfo calldata injectedHooksInfo, - bytes calldata data - ) external; - - /// @notice A hook that runs when a hook this plugin owns is unapplied from another plugin - /// @dev Optional, use to implement any required unapplied logic - /// @param pluginAppliedOn The plugin that the hook was applied on - /// @param injectedHooksInfo Contains pre/post exec hook information - /// @param data Any optional data for the unapplied call - function onHookUnapply( - address pluginAppliedOn, - IPluginManager.InjectedHooksInfo calldata injectedHooksInfo, - bytes calldata data - ) external; - /// @notice Run the pre user operation validation hook specified by the `functionId`. /// @dev Pre user operation validation hooks MUST NOT return an authorizer value other than 0 or 1. /// @param functionId An identifier that routes the call to different internal implementations, should there be more than one. @@ -377,7 +315,7 @@ interface IPlugin { function postExecutionHook(uint8 functionId, bytes calldata preExecHookData) external; /// @notice Describe the contents and intended configuration of the plugin. - /// @dev The manifest MUST stay constant over time. + /// @dev This manifest MUST stay constant over time. /// @return A manifest describing the contents and intended configuration of the plugin. function pluginManifest() external pure returns (PluginManifest memory); @@ -479,7 +417,6 @@ struct PluginManifest { ManifestAssociatedFunction[] preUserOpValidationHooks; ManifestAssociatedFunction[] preRuntimeValidationHooks; ManifestExecutionHook[] executionHooks; - ManifestExecutionHook[] permittedCallHooks; } ``` @@ -500,7 +437,7 @@ The following behavior must be followed: #### Calls to `installPlugin` -The function `installPlugin` accepts 5 parameters: the address of the plugin to install, the Keccak-256 hash of the plugin's manifest, ABI-encoded data to pass to the plugin's `onInstall` callback, an array of function references that represent the plugin's install dependencies, and permitted call hooks to apply during installation. +The function `installPlugin` accepts 4 parameters: the address of the plugin to install, the Keccak-256 hash of the plugin's manifest, ABI-encoded data to pass to the plugin's `onInstall` callback, and an array of function references that represent the plugin's install dependencies. The function MUST retrieve the plugin's manifest by calling `pluginManifest()` using `staticcall`. @@ -511,7 +448,7 @@ The function MUST perform the following preliminary checks: - Revert if `manifestHash` does not match the computed Keccak-256 hash of the plugin's returned manifest. This prevents installation of plugins that attempt to install a different plugin configuration than the one that was approved by the client. - Revert if any address in `dependencies` does not support the interface at its matching index in the manifest's `dependencyInterfaceIds`, or if the two array lengths do not match, or if any of the dependencies are not already installed on the modular account. -The function MUST record the manifest hash, dependencies, and permitted call hooks that were used for the plugin's installation. Each dependency's record MUST also be updated to reflect that it has a new dependent. These records MUST be used to ensure calls to `uninstallPlugin` are comprehensive and undo all editted configuration state from installation. The mechanism by which these records are stored and validated is up to the implementation. +The function MUST record the manifest hash and dependencies that were used for the plugin's installation. Each dependency's record MUST also be updated to reflect that it has a new dependent. These records MUST be used to ensure calls to `uninstallPlugin` are comprehensive and undo all editted configuration state from installation. The mechanism by which these records are stored and validated is up to the implementation. The function MUST store the plugin's permitted function selectors and external contract calls to be able to validate calls to `executeFromPlugin` and `executeFromPluginExternal`. @@ -522,8 +459,6 @@ The function MUST parse through the execution functions, validation functions, a Next, the function MUST call the plugin's `onInstall` callback with the data provided in the `installData` parameter. This serves to initialize the plugin state for the modular account. If `onInstall` reverts, the `installPlugin` function MUST revert. -For each injected hook provided, the function MUST add the permitted call hook using the currently installing plugin as the caller and the provided function selector as the execution function selector. Then, the function MUST call onHookApply with the user-provided initialization data, if the data is nonempty. - Finally, the function must emit the event `PluginInstalled` with the plugin's address and a hash of its manifest. > **⚠️ The ability to install and uninstall plugins is very powerful. The security of these functions determines the security of the account. It is critical for modular account implementers to make sure the implementation of the functions in `IPluginManager` have the proper security consideration and access control in place.** @@ -541,12 +476,10 @@ The function SHOULD perform the following checks: The function SHOULD update account storage to reflect the uninstall via inspection functions, such as those defined by `IAccountLoupe`. Each dependency's record SHOULD also be updated to reflect that it has no longer has this plugin as a dependent. -The function MUST remove records for the plugin's dependencies, injected permitted call hooks, permitted function selectors, and permitted external calls. The hooks to remove MUST be exactly the same as what was provided during installation. It is up to the implementing modular account to decide how to keep this invariant. The config parameter field MAY be used. +The function MUST remove records for the plugin's dependencies, permitted function selectors, and permitted external calls. The hooks to remove MUST be exactly the same as what was provided during installation. It is up to the implementing modular account to decide how to keep this invariant. The config parameter field MAY be used. The function MUST parse through the execution functions, validation functions, and hooks in the manifest and remove them from the modular account after resolving each `ManifestFunction` type. -Next, for each previously injected hook, the function MUST remove the permitted call hook using the currently uninstalling plugin as the caller and the provided function selector as the execution function selector. Then, the function MUST call onHookUnapply with the user-provided initialization data, if the data is nonempty. - Finally, the function MUST call the plugin's `onUninstall` callback with the data provided in the `uninstallData` parameter. This serves to clear the plugin state for the modular account. If `onUninstall` reverts, execution SHOULD continue to allow the uninstall to complete. > **⚠️ Incorrectly uninstalled plugins can prevent uninstallation of their dependencies. Therefore, some form of validation that the uninstall step completely and correctly removes the plugin and its usage of dependencies is required.** diff --git a/standard/assets/eip-6900/Plugin_Execution_Flow.svg b/standard/assets/eip-6900/Plugin_Execution_Flow.svg index b5b013d5..3a94b512 100644 --- a/standard/assets/eip-6900/Plugin_Execution_Flow.svg +++ b/standard/assets/eip-6900/Plugin_Execution_Flow.svg @@ -1,4 +1,4 @@ - + @@ -11,7 +11,11 @@ font-family: "Cascadia"; src: url("https://excalidraw.com/Cascadia.woff2"); } + @font-face { + font-family: "Assistant"; + src: url("https://excalidraw.com/Assistant-Regular.woff2"); + } - Permitted External Contracts & Methods executeFromPluginPost Permitted Call Hook(s)Pre Execution Hook(s)Pre Permitted Call Hook(s)Permitted Plugin Execution FunctionPost Execution Hook(s)PluginsPlugin Permission Check executeFromPluginExternal(Plugin) Execution Function1 calls plugin 2.2 calls external contracts through executeFromPluginExternalPre Permitted Call Hook(s)Post Permitted Call Hook(s)Plugin Permission CheckModular AccountPlugin Execution Flow2.1 calls other installed plugin through executeFromPluginPre executeFromPluginExternal Hook(s)Post executeFromPluginExternal Hook(s) \ No newline at end of file + Permitted External Contracts & Methods executeFromPluginPre Execution Hook(s)Permitted Plugin Execution FunctionPost Execution Hook(s)PluginsPlugin Permission Check executeFromPluginExternal(Plugin) Execution Function1 calls plugin 2.2 calls external contracts through executeFromPluginExternalPlugin Permission CheckModular AccountPlugin Execution Flow2.1 calls other installed plugin through executeFromPluginPre executeFromPluginExternal Hook(s)Post executeFromPluginExternal Hook(s) \ No newline at end of file diff --git a/test/account/AccountExecHooks.t.sol b/test/account/AccountExecHooks.t.sol index d63e5c2e..957bcb56 100644 --- a/test/account/AccountExecHooks.t.sol +++ b/test/account/AccountExecHooks.t.sol @@ -4,9 +4,6 @@ pragma solidity ^0.8.19; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.sol"; -import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; -import {FunctionReference, FunctionReferenceLib} from "../../src/helpers/FunctionReferenceLib.sol"; -import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; import { IPlugin, ManifestAssociatedFunctionType, @@ -16,6 +13,8 @@ import { PluginManifest } from "../../src/interfaces/IPlugin.sol"; import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; +import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; +import {FunctionReference, FunctionReferenceLib} from "../../src/helpers/FunctionReferenceLib.sol"; import {MockPlugin} from "../mocks/MockPlugin.sol"; import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; @@ -44,13 +43,7 @@ contract AccountExecHooksTest is OptimizedTest { PluginManifest public m1; PluginManifest public m2; - /// @dev Note that we strip hookApplyData from InjectedHooks in this event for gas savings - event PluginInstalled( - address indexed plugin, - bytes32 manifestHash, - FunctionReference[] dependencies, - IPluginManager.InjectedHook[] injectedHooks - ); + event PluginInstalled(address indexed plugin, bytes32 manifestHash, FunctionReference[] dependencies); event PluginUninstalled(address indexed plugin, bool indexed callbacksSucceeded); // emitted by MockPlugin event ReceivedCall(bytes msgData, uint256 msgValue); @@ -427,16 +420,13 @@ contract AccountExecHooksTest is OptimizedTest { vm.expectEmit(true, true, true, true); emit ReceivedCall(abi.encodeCall(IPlugin.onInstall, (bytes(""))), 0); vm.expectEmit(true, true, true, true); - emit PluginInstalled( - address(mockPlugin1), manifestHash1, new FunctionReference[](0), new IPluginManager.InjectedHook[](0) - ); + emit PluginInstalled(address(mockPlugin1), manifestHash1, new FunctionReference[](0)); account.installPlugin({ plugin: address(mockPlugin1), manifestHash: manifestHash1, pluginInitData: bytes(""), - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -461,16 +451,13 @@ contract AccountExecHooksTest is OptimizedTest { vm.expectEmit(true, true, true, true); emit ReceivedCall(abi.encodeCall(IPlugin.onInstall, (bytes(""))), 0); vm.expectEmit(true, true, true, true); - emit PluginInstalled( - address(mockPlugin2), manifestHash2, dependencies, new IPluginManager.InjectedHook[](0) - ); + emit PluginInstalled(address(mockPlugin2), manifestHash2, dependencies); account.installPlugin({ plugin: address(mockPlugin2), manifestHash: manifestHash2, pluginInitData: bytes(""), - dependencies: dependencies, - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: dependencies }); } @@ -480,6 +467,6 @@ contract AccountExecHooksTest is OptimizedTest { vm.expectEmit(true, true, true, true); emit PluginUninstalled(address(plugin), true); - account.uninstallPlugin(address(plugin), bytes(""), bytes(""), new bytes[](0)); + account.uninstallPlugin(address(plugin), bytes(""), bytes("")); } } diff --git a/test/account/AccountLoupe.t.sol b/test/account/AccountLoupe.t.sol index e7981c1f..17f66788 100644 --- a/test/account/AccountLoupe.t.sol +++ b/test/account/AccountLoupe.t.sol @@ -46,13 +46,7 @@ contract AccountLoupeTest is OptimizedTest { account1 = factory.createAccount(address(this), 0); bytes32 manifestHash = keccak256(abi.encode(comprehensivePlugin.pluginManifest())); - account1.installPlugin( - address(comprehensivePlugin), - manifestHash, - "", - new FunctionReference[](0), - new IPluginManager.InjectedHook[](0) - ); + account1.installPlugin(address(comprehensivePlugin), manifestHash, "", new FunctionReference[](0)); ownerUserOpValidation = FunctionReferenceLib.pack( address(singleOwnerPlugin), uint8(ISingleOwnerPlugin.FunctionId.USER_OP_VALIDATION_OWNER) @@ -170,31 +164,6 @@ contract AccountLoupeTest is OptimizedTest { ); } - function test_pluginLoupe_getPermittedCallHooks() public { - IAccountLoupe.ExecutionHooks[] memory hooks = - account1.getPermittedCallHooks(address(comprehensivePlugin), comprehensivePlugin.foo.selector); - - assertEq(hooks.length, 1); - assertEq( - FunctionReference.unwrap(hooks[0].preExecHook), - FunctionReference.unwrap( - FunctionReferenceLib.pack( - address(comprehensivePlugin), - uint8(ComprehensivePlugin.FunctionId.PRE_PERMITTED_CALL_EXECUTION_HOOK) - ) - ) - ); - assertEq( - FunctionReference.unwrap(hooks[0].postExecHook), - FunctionReference.unwrap( - FunctionReferenceLib.pack( - address(comprehensivePlugin), - uint8(ComprehensivePlugin.FunctionId.POST_PERMITTED_CALL_EXECUTION_HOOK) - ) - ) - ); - } - function test_pluginLoupe_getHooks_multiple() public { // Add a second set of execution hooks to the account, and validate that it can return all hooks applied // over the function. @@ -216,29 +185,10 @@ contract AccountLoupeTest is OptimizedTest { }) }); - mockPluginManifest.permittedCallHooks = new ManifestExecutionHook[](2); - // Copy over the same hooks from executionHooks. - mockPluginManifest.permittedCallHooks[0] = mockPluginManifest.executionHooks[0]; - mockPluginManifest.permittedCallHooks[1] = ManifestExecutionHook({ - executionSelector: ComprehensivePlugin.foo.selector, - preExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: 1, - dependencyIndex: 0 - }), - postExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: 1, - dependencyIndex: 0 - }) - }); - MockPlugin mockPlugin = new MockPlugin(mockPluginManifest); bytes32 manifestHash = keccak256(abi.encode(mockPlugin.pluginManifest())); - account1.installPlugin( - address(mockPlugin), manifestHash, "", new FunctionReference[](0), new IPluginManager.InjectedHook[](0) - ); + account1.installPlugin(address(mockPlugin), manifestHash, "", new FunctionReference[](0)); // Assert that the returned execution hooks are what is expected @@ -269,28 +219,6 @@ contract AccountLoupeTest is OptimizedTest { FunctionReference.unwrap(hooks[1].postExecHook), FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0))) ); - - // Assert that the returned permitted call hooks are what is expected - - hooks = account1.getPermittedCallHooks(address(mockPlugin), comprehensivePlugin.foo.selector); - - assertEq(hooks.length, 2); - assertEq( - FunctionReference.unwrap(hooks[0].preExecHook), - FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0))) - ); - assertEq( - FunctionReference.unwrap(hooks[0].postExecHook), - FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(0))) - ); - assertEq( - FunctionReference.unwrap(hooks[1].preExecHook), - FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(1))) - ); - assertEq( - FunctionReference.unwrap(hooks[1].postExecHook), - FunctionReference.unwrap(FunctionReferenceLib.pack(address(mockPlugin), uint8(1))) - ); } function test_pluginLoupe_getPreUserOpValidationHooks() public { diff --git a/test/account/AccountPermittedCallHooks.t.sol b/test/account/AccountPermittedCallHooks.t.sol deleted file mode 100644 index 3dd38363..00000000 --- a/test/account/AccountPermittedCallHooks.t.sol +++ /dev/null @@ -1,406 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.sol"; - -import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; -import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol"; -import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; -import { - IPlugin, - ManifestAssociatedFunctionType, - ManifestAssociatedFunction, - ManifestExecutionHook, - ManifestFunction, - PluginManifest -} from "../../src/interfaces/IPlugin.sol"; -import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; - -import {MockPlugin} from "../mocks/MockPlugin.sol"; -import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; -import {OptimizedTest} from "../utils/OptimizedTest.sol"; - -contract AccountPermittedCallHooksTest is OptimizedTest { - using ECDSA for bytes32; - - EntryPoint public entryPoint; - SingleOwnerPlugin public singleOwnerPlugin; - MSCAFactoryFixture public factory; - - UpgradeableModularAccount public account; - - MockPlugin public mockPlugin1; - bytes32 public manifestHash1; - - bytes4 internal constant _EXEC_SELECTOR = bytes4(uint32(1)); - uint8 internal constant _PRE_HOOK_FUNCTION_ID_1 = 1; - uint8 internal constant _POST_HOOK_FUNCTION_ID_2 = 2; - uint8 internal constant _PRE_HOOK_FUNCTION_ID_3 = 3; - uint8 internal constant _POST_HOOK_FUNCTION_ID_4 = 4; - - PluginManifest public m1; - - /// @dev Note that we strip hookApplyData from InjectedHooks in this event for gas savings - event PluginInstalled( - address indexed plugin, - bytes32 manifestHash, - FunctionReference[] dependencies, - IPluginManager.InjectedHook[] injectedHooks - ); - event PluginUninstalled(address indexed plugin, bool indexed callbacksSucceeded); - // emitted by MockPlugin - event ReceivedCall(bytes msgData, uint256 msgValue); - - function setUp() public { - entryPoint = new EntryPoint(); - singleOwnerPlugin = _deploySingleOwnerPlugin(); - factory = new MSCAFactoryFixture(entryPoint, singleOwnerPlugin); - - // Create an account with "this" as the owner, so we can execute along the runtime path with regular - // solidity semantics - account = factory.createAccount(address(this), 0); - - m1.executionFunctions.push(_EXEC_SELECTOR); - - m1.runtimeValidationFunctions.push( - ManifestAssociatedFunction({ - executionSelector: _EXEC_SELECTOR, - associatedFunction: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW, - functionId: 0, - dependencyIndex: 0 - }) - }) - ); - - m1.permittedExecutionSelectors.push(_EXEC_SELECTOR); - } - - function test_prePermittedCallHook_install() public { - _installPlugin1WithHooks( - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _PRE_HOOK_FUNCTION_ID_1, - dependencyIndex: 0 - }), - ManifestFunction({functionType: ManifestAssociatedFunctionType.NONE, functionId: 0, dependencyIndex: 0}) - ); - } - - /// @dev Plugin hook pair(s): [1, null] - /// Expected execution: [1, null] - function test_prePermittedCallHook_run() public { - test_prePermittedCallHook_install(); - - vm.startPrank(address(mockPlugin1)); - - vm.expectEmit(true, true, true, true); - emit ReceivedCall( - abi.encodeWithSelector( - IPlugin.preExecutionHook.selector, - _PRE_HOOK_FUNCTION_ID_1, - address(mockPlugin1), // caller - 0, // msg.value in call to account - abi.encodePacked(_EXEC_SELECTOR) - ), - 0 // msg value in call to plugin - ); - - account.executeFromPlugin(abi.encodePacked(_EXEC_SELECTOR)); - - vm.stopPrank(); - } - - function test_prePermittedCallHook_uninstall() public { - test_prePermittedCallHook_install(); - - _uninstallPlugin(mockPlugin1); - } - - function test_permittedCallHookPair_install() public { - _installPlugin1WithHooks( - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _PRE_HOOK_FUNCTION_ID_1, - dependencyIndex: 0 - }), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _POST_HOOK_FUNCTION_ID_2, - dependencyIndex: 0 - }) - ); - } - - /// @dev Plugin hook pair(s): [1, 2] - /// Expected execution: [1, 2] - function test_permittedCallHookPair_run() public { - test_permittedCallHookPair_install(); - - vm.startPrank(address(mockPlugin1)); - - vm.expectEmit(true, true, true, true); - // pre hook call - emit ReceivedCall( - abi.encodeWithSelector( - IPlugin.preExecutionHook.selector, - _PRE_HOOK_FUNCTION_ID_1, - address(mockPlugin1), // caller - 0, // msg.value in call to account - abi.encodePacked(_EXEC_SELECTOR) - ), - 0 // msg value in call to plugin - ); - vm.expectEmit(true, true, true, true); - // exec call - emit ReceivedCall(abi.encodePacked(_EXEC_SELECTOR), 0); - vm.expectEmit(true, true, true, true); - // post hook call - emit ReceivedCall( - abi.encodeCall(IPlugin.postExecutionHook, (_POST_HOOK_FUNCTION_ID_2, "")), - 0 // msg value in call to plugin - ); - - account.executeFromPlugin(abi.encodePacked(_EXEC_SELECTOR)); - - vm.stopPrank(); - } - - function test_permittedCallHookPair_uninstall() public { - test_permittedCallHookPair_install(); - - _uninstallPlugin(mockPlugin1); - } - - function test_postOnlyPermittedCallHook_install() public { - _installPlugin1WithHooks( - ManifestFunction({functionType: ManifestAssociatedFunctionType.NONE, functionId: 0, dependencyIndex: 0}), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _POST_HOOK_FUNCTION_ID_2, - dependencyIndex: 0 - }) - ); - } - - /// @dev Plugin hook pair(s): [null, 2] - /// Expected execution: [null, 2] - function test_postOnlyPermittedCallHook_run() public { - test_postOnlyPermittedCallHook_install(); - - vm.startPrank(address(mockPlugin1)); - - vm.expectEmit(true, true, true, true); - emit ReceivedCall( - abi.encodeCall(IPlugin.postExecutionHook, (_POST_HOOK_FUNCTION_ID_2, "")), - 0 // msg value in call to plugin - ); - - account.executeFromPlugin(abi.encodePacked(_EXEC_SELECTOR)); - - vm.stopPrank(); - } - - function test_postOnlyPermittedCallHook_uninstall() public { - test_postOnlyPermittedCallHook_install(); - - _uninstallPlugin(mockPlugin1); - } - - function test_overlappingPermittedCallHookPairs_install() public { - _installPlugin1WithHooks( - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _PRE_HOOK_FUNCTION_ID_1, - dependencyIndex: 0 - }), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _POST_HOOK_FUNCTION_ID_2, - dependencyIndex: 0 - }), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _PRE_HOOK_FUNCTION_ID_1, - dependencyIndex: 0 - }), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _POST_HOOK_FUNCTION_ID_2, - dependencyIndex: 0 - }) - ); - } - - /// @dev Plugin hook pair(s): [1, 2], [1, 2] - /// Expected execution: [1, 2] - function test_overlappingPermittedCallHookPairs_run() public { - test_overlappingPermittedCallHookPairs_install(); - - vm.startPrank(address(mockPlugin1)); - - // Expect the pre hook to be called just once. - vm.expectCall( - address(mockPlugin1), - abi.encodeWithSelector( - IPlugin.preExecutionHook.selector, - _PRE_HOOK_FUNCTION_ID_1, - address(mockPlugin1), // caller - 0, // msg.value in call to account - abi.encodePacked(_EXEC_SELECTOR) - ), - 1 - ); - - // Expect the post hook to be called just once, with the expected data. - vm.expectCall( - address(mockPlugin1), - abi.encodeWithSelector(IPlugin.postExecutionHook.selector, _POST_HOOK_FUNCTION_ID_2, ""), - 1 - ); - - account.executeFromPlugin(abi.encodePacked(_EXEC_SELECTOR)); - - vm.stopPrank(); - } - - function test_overlappingPermittedCallHookPairs_uninstall() public { - test_overlappingPermittedCallHookPairs_install(); - - _uninstallPlugin(mockPlugin1); - } - - function test_overlappingPermittedCallHookPairsOnPost_install() public { - _installPlugin1WithHooks( - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _PRE_HOOK_FUNCTION_ID_1, - dependencyIndex: 0 - }), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _POST_HOOK_FUNCTION_ID_2, - dependencyIndex: 0 - }), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _PRE_HOOK_FUNCTION_ID_3, - dependencyIndex: 0 - }), - ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: _POST_HOOK_FUNCTION_ID_2, - dependencyIndex: 0 - }) - ); - } - - /// @dev Plugin hook pair(s): [1, 2], [3, 2] - /// Expected execution: [1, 2], [3, 2] - function test_overlappingPermittedCallHookPairsOnPost_run() public { - test_overlappingPermittedCallHookPairsOnPost_install(); - - vm.startPrank(address(mockPlugin1)); - - // Expect each pre hook to be called once. - vm.expectCall( - address(mockPlugin1), - abi.encodeWithSelector( - IPlugin.preExecutionHook.selector, - _PRE_HOOK_FUNCTION_ID_3, - address(mockPlugin1), // caller - 0, // msg.value in call to account - abi.encodePacked(_EXEC_SELECTOR) - ), - 1 - ); - vm.expectCall( - address(mockPlugin1), - abi.encodeWithSelector( - IPlugin.preExecutionHook.selector, - _PRE_HOOK_FUNCTION_ID_1, - address(mockPlugin1), // caller - 0, // msg.value in call to account - abi.encodePacked(_EXEC_SELECTOR) - ), - 1 - ); - - // Expect the post hook to be called twice, with the expected data. - vm.expectCall( - address(mockPlugin1), - abi.encodeWithSelector(IPlugin.postExecutionHook.selector, _POST_HOOK_FUNCTION_ID_2, ""), - 2 - ); - - account.executeFromPlugin(abi.encodePacked(_EXEC_SELECTOR)); - - vm.stopPrank(); - } - - function test_overlappingPermittedCallHookPairsOnPost_uninstall() public { - test_overlappingPermittedCallHookPairsOnPost_install(); - - _uninstallPlugin(mockPlugin1); - } - - function _installPlugin1WithHooks(ManifestFunction memory preHook1, ManifestFunction memory postHook1) - internal - { - m1.permittedCallHooks.push(ManifestExecutionHook(_EXEC_SELECTOR, preHook1, postHook1)); - mockPlugin1 = new MockPlugin(m1); - manifestHash1 = keccak256(abi.encode(mockPlugin1.pluginManifest())); - - vm.expectEmit(true, true, true, true); - emit ReceivedCall(abi.encodeCall(IPlugin.onInstall, (bytes(""))), 0); - vm.expectEmit(true, true, true, true); - emit PluginInstalled( - address(mockPlugin1), manifestHash1, new FunctionReference[](0), new IPluginManager.InjectedHook[](0) - ); - - account.installPlugin({ - plugin: address(mockPlugin1), - manifestHash: manifestHash1, - pluginInitData: bytes(""), - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) - }); - } - - function _installPlugin1WithHooks( - ManifestFunction memory preHook1, - ManifestFunction memory postHook1, - ManifestFunction memory preHook2, - ManifestFunction memory postHook2 - ) internal { - m1.permittedCallHooks.push(ManifestExecutionHook(_EXEC_SELECTOR, preHook1, postHook1)); - m1.permittedCallHooks.push(ManifestExecutionHook(_EXEC_SELECTOR, preHook2, postHook2)); - mockPlugin1 = new MockPlugin(m1); - manifestHash1 = keccak256(abi.encode(mockPlugin1.pluginManifest())); - - vm.expectEmit(true, true, true, true); - emit ReceivedCall(abi.encodeCall(IPlugin.onInstall, (bytes(""))), 0); - vm.expectEmit(true, true, true, true); - emit PluginInstalled( - address(mockPlugin1), manifestHash1, new FunctionReference[](0), new IPluginManager.InjectedHook[](0) - ); - - account.installPlugin({ - plugin: address(mockPlugin1), - manifestHash: manifestHash1, - pluginInitData: bytes(""), - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) - }); - } - - function _uninstallPlugin(MockPlugin plugin) internal { - vm.expectEmit(true, true, true, true); - emit ReceivedCall(abi.encodeCall(IPlugin.onUninstall, (bytes(""))), 0); - vm.expectEmit(true, true, true, true); - emit PluginUninstalled(address(plugin), true); - - account.uninstallPlugin(address(plugin), bytes(""), bytes(""), new bytes[](0)); - } -} diff --git a/test/account/AccountReturnData.t.sol b/test/account/AccountReturnData.t.sol index 1ca8996b..808f6d2a 100644 --- a/test/account/AccountReturnData.t.sol +++ b/test/account/AccountReturnData.t.sol @@ -5,7 +5,6 @@ import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.so import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol"; -import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; import {Call} from "../../src/interfaces/IStandardExecutor.sol"; import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; @@ -48,8 +47,7 @@ contract AccountReturnDataTest is OptimizedTest { plugin: address(resultCreatorPlugin), manifestHash: resultCreatorManifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); // Add the result consumer plugin to the account bytes32 resultConsumerManifestHash = keccak256(abi.encode(resultConsumerPlugin.pluginManifest())); @@ -57,8 +55,7 @@ contract AccountReturnDataTest is OptimizedTest { plugin: address(resultConsumerPlugin), manifestHash: resultConsumerManifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } diff --git a/test/account/ExecuteFromPluginPermissions.t.sol b/test/account/ExecuteFromPluginPermissions.t.sol index efb4a7b2..46cdbaef 100644 --- a/test/account/ExecuteFromPluginPermissions.t.sol +++ b/test/account/ExecuteFromPluginPermissions.t.sol @@ -7,18 +7,12 @@ import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.so import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol"; -import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; import {Counter} from "../mocks/Counter.sol"; import {ResultCreatorPlugin} from "../mocks/plugins/ReturnDataPluginMocks.sol"; -import { - EFPCallerPlugin, - EFPCallerPluginAnyExternal, - EFPPermittedCallHookPlugin, - EFPExternalPermittedCallHookPlugin -} from "../mocks/plugins/ExecFromPluginPermissionsMocks.sol"; +import {EFPCallerPlugin, EFPCallerPluginAnyExternal} from "../mocks/plugins/ExecFromPluginPermissionsMocks.sol"; import {OptimizedTest} from "../utils/OptimizedTest.sol"; contract ExecuteFromPluginPermissionsTest is OptimizedTest { @@ -34,8 +28,6 @@ contract ExecuteFromPluginPermissionsTest is OptimizedTest { EFPCallerPlugin public efpCallerPlugin; EFPCallerPluginAnyExternal public efpCallerPluginAnyExternal; - EFPPermittedCallHookPlugin public efpPermittedCallHookPlugin; - EFPExternalPermittedCallHookPlugin public efpExternalPermittedCallHookPlugin; function setUp() public { // Initialize the interaction targets @@ -52,8 +44,6 @@ contract ExecuteFromPluginPermissionsTest is OptimizedTest { // Initialize the EFP caller plugins, which will attempt to use the permissions system to authorize calls. efpCallerPlugin = new EFPCallerPlugin(); efpCallerPluginAnyExternal = new EFPCallerPluginAnyExternal(); - efpPermittedCallHookPlugin = new EFPPermittedCallHookPlugin(); - efpExternalPermittedCallHookPlugin = new EFPExternalPermittedCallHookPlugin(); // Create an account with "this" as the owner, so we can execute along the runtime path with regular // solidity semantics @@ -65,8 +55,7 @@ contract ExecuteFromPluginPermissionsTest is OptimizedTest { plugin: address(resultCreatorPlugin), manifestHash: resultCreatorManifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); // Add the EFP caller plugin to the account bytes32 efpCallerManifestHash = keccak256(abi.encode(efpCallerPlugin.pluginManifest())); @@ -74,8 +63,7 @@ contract ExecuteFromPluginPermissionsTest is OptimizedTest { plugin: address(efpCallerPlugin), manifestHash: efpCallerManifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); // Add the EFP caller plugin with any external permissions to the account @@ -85,30 +73,7 @@ contract ExecuteFromPluginPermissionsTest is OptimizedTest { plugin: address(efpCallerPluginAnyExternal), manifestHash: efpCallerAnyExternalManifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) - }); - - // Add the EFP caller plugin with permitted call hooks to the account - bytes32 efpPermittedCallHookManifestHash = - keccak256(abi.encode(efpPermittedCallHookPlugin.pluginManifest())); - account.installPlugin({ - plugin: address(efpPermittedCallHookPlugin), - manifestHash: efpPermittedCallHookManifestHash, - pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) - }); - - // Add the EFP caller plugin with an external permitted call hook to the account - bytes32 efpExternalPermittedCallHookManifestHash = - keccak256(abi.encode(efpExternalPermittedCallHookPlugin.pluginManifest())); - account.installPlugin({ - plugin: address(efpExternalPermittedCallHookPlugin), - manifestHash: efpExternalPermittedCallHookManifestHash, - pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -255,33 +220,4 @@ contract ExecuteFromPluginPermissionsTest is OptimizedTest { retrievedNumber = abi.decode(result, (uint256)); assertEq(retrievedNumber, 18); } - - function test_executeFromPlugin_PermittedCallHooks() public { - assertFalse(efpPermittedCallHookPlugin.preExecHookCalled()); - assertFalse(efpPermittedCallHookPlugin.postExecHookCalled()); - - bytes memory result = EFPPermittedCallHookPlugin(address(account)).performEFPCall(); - - bytes32 actual = abi.decode(result, (bytes32)); - - assertEq(actual, keccak256("bar")); - - assertTrue(efpPermittedCallHookPlugin.preExecHookCalled()); - assertTrue(efpPermittedCallHookPlugin.postExecHookCalled()); - } - - function test_executeFromPluginExternal_PermittedCallHooks() public { - counter1.setNumber(17); - - assertFalse(efpExternalPermittedCallHookPlugin.preExecHookCalled()); - assertFalse(efpExternalPermittedCallHookPlugin.postExecHookCalled()); - - EFPExternalPermittedCallHookPlugin(address(account)).performIncrement(); - - assertTrue(efpExternalPermittedCallHookPlugin.preExecHookCalled()); - assertTrue(efpExternalPermittedCallHookPlugin.postExecHookCalled()); - - uint256 retrievedNumber = counter1.number(); - assertEq(retrievedNumber, 18); - } } diff --git a/test/account/ManifestValidity.t.sol b/test/account/ManifestValidity.t.sol index d85f03aa..e620bf28 100644 --- a/test/account/ManifestValidity.t.sol +++ b/test/account/ManifestValidity.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.19; import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.sol"; +import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {PluginManagerInternals} from "../../src/account/PluginManagerInternals.sol"; import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol"; -import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; @@ -51,8 +51,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -69,8 +68,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -87,8 +85,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -103,8 +100,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -119,8 +115,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -136,8 +131,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -153,8 +147,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -169,8 +162,7 @@ contract ManifestValidityTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } } diff --git a/test/account/UpgradeableModularAccount.t.sol b/test/account/UpgradeableModularAccount.t.sol index 49b7f078..02a5b3b1 100644 --- a/test/account/UpgradeableModularAccount.t.sol +++ b/test/account/UpgradeableModularAccount.t.sol @@ -13,7 +13,6 @@ import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol"; import {IPlugin, PluginManifest} from "../../src/interfaces/IPlugin.sol"; import {IAccountLoupe} from "../../src/interfaces/IAccountLoupe.sol"; import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; -import {IPluginExecutor} from "../../src/interfaces/IPluginExecutor.sol"; import {Call} from "../../src/interfaces/IStandardExecutor.sol"; import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; import {TokenReceiverPlugin} from "../../src/plugins/TokenReceiverPlugin.sol"; @@ -44,21 +43,11 @@ contract UpgradeableModularAccountTest is OptimizedTest { address public ethRecipient; Counter public counter; PluginManifest public manifest; - IPluginManager.InjectedHooksInfo public injectedHooksInfo = IPluginManager.InjectedHooksInfo({ - preExecHookFunctionId: 2, - isPostHookUsed: true, - postExecHookFunctionId: 3 - }); uint256 public constant CALL_GAS_LIMIT = 50000; uint256 public constant VERIFICATION_GAS_LIMIT = 1200000; - event PluginInstalled( - address indexed plugin, - bytes32 manifestHash, - FunctionReference[] dependencies, - IPluginManager.InjectedHook[] injectedHooks - ); + event PluginInstalled(address indexed plugin, bytes32 manifestHash, FunctionReference[] dependencies); event PluginUninstalled(address indexed plugin, bool indexed callbacksSucceeded); event ReceivedCall(bytes msgData, uint256 msgValue); @@ -276,18 +265,12 @@ contract UpgradeableModularAccountTest is OptimizedTest { bytes32 manifestHash = keccak256(abi.encode(tokenReceiverPlugin.pluginManifest())); vm.expectEmit(true, true, true, true); - emit PluginInstalled( - address(tokenReceiverPlugin), - manifestHash, - new FunctionReference[](0), - new IPluginManager.InjectedHook[](0) - ); + emit PluginInstalled(address(tokenReceiverPlugin), manifestHash, new FunctionReference[](0)); IPluginManager(account2).installPlugin({ plugin: address(tokenReceiverPlugin), manifestHash: manifestHash, pluginInitData: abi.encode(uint48(1 days)), - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); address[] memory plugins = IAccountLoupe(account2).getInstalledPlugins(); @@ -310,8 +293,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(mockPluginWithBadPermittedExec), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -323,8 +305,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(tokenReceiverPlugin), manifestHash: bytes32(0), pluginInitData: abi.encode(uint48(1 days)), - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -339,8 +320,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(badPlugin), manifestHash: bytes32(0), pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -352,8 +332,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(tokenReceiverPlugin), manifestHash: manifestHash, pluginInitData: abi.encode(uint48(1 days)), - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); vm.expectRevert( @@ -365,8 +344,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(tokenReceiverPlugin), manifestHash: manifestHash, pluginInitData: abi.encode(uint48(1 days)), - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); } @@ -379,18 +357,12 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); vm.expectEmit(true, true, true, true); emit PluginUninstalled(address(plugin), true); - IPluginManager(account2).uninstallPlugin({ - plugin: address(plugin), - config: "", - pluginUninstallData: "", - hookUnapplyData: new bytes[](0) - }); + IPluginManager(account2).uninstallPlugin({plugin: address(plugin), config: "", pluginUninstallData: ""}); address[] memory plugins = IAccountLoupe(account2).getInstalledPlugins(); assertEq(plugins.length, 1); assertEq(plugins[0], address(singleOwnerPlugin)); @@ -406,8 +378,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); vm.expectEmit(true, true, true, true); @@ -415,8 +386,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { IPluginManager(account2).uninstallPlugin({ plugin: address(plugin), config: serializedManifest, - pluginUninstallData: "", - hookUnapplyData: new bytes[](0) + pluginUninstallData: "" }); address[] memory plugins = IAccountLoupe(account2).getInstalledPlugins(); assertEq(plugins.length, 1); @@ -433,8 +403,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); // Attempt to uninstall with a blank manifest @@ -444,8 +413,7 @@ contract UpgradeableModularAccountTest is OptimizedTest { IPluginManager(account2).uninstallPlugin({ plugin: address(plugin), config: abi.encode(blankManifest), - pluginUninstallData: "", - hookUnapplyData: new bytes[](0) + pluginUninstallData: "" }); address[] memory plugins = IAccountLoupe(account2).getInstalledPlugins(); assertEq(plugins.length, 2); @@ -463,190 +431,12 @@ contract UpgradeableModularAccountTest is OptimizedTest { plugin: address(plugin), manifestHash: manifestHash, pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); vm.stopPrank(); } - function _installWithInjectHooks() - internal - returns (MockPlugin hooksPlugin, MockPlugin newPlugin, bytes32 manifestHash) - { - hooksPlugin = _installPluginWithExecHooks(); - - manifest.permitAnyExternalAddress = true; - newPlugin = new MockPlugin(manifest); - - manifestHash = keccak256(abi.encode(newPlugin.pluginManifest())); - - IPluginManager.InjectedHook[] memory hooks = new IPluginManager.InjectedHook[](1); - hooks[0] = IPluginManager.InjectedHook( - address(hooksPlugin), IPluginExecutor.executeFromPluginExternal.selector, injectedHooksInfo, "" - ); - - vm.prank(owner2); - vm.expectEmit(true, true, true, true); - emit PluginInstalled(address(newPlugin), manifestHash, new FunctionReference[](0), hooks); - emit ReceivedCall(abi.encodeCall(IPlugin.onHookApply, (address(newPlugin), injectedHooksInfo, "")), 0); - IPluginManager(account2).installPlugin({ - plugin: address(newPlugin), - manifestHash: manifestHash, - pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: hooks - }); - } - - function test_injectHooks() external { - (, MockPlugin newPlugin,) = _installWithInjectHooks(); - - // order of emitting events: pre hook is run, exec function is run, post hook is run - vm.expectEmit(true, true, true, true); - emit ReceivedCall( - abi.encodeWithSelector( - IPlugin.preExecutionHook.selector, - injectedHooksInfo.preExecHookFunctionId, - address(newPlugin), // caller - 0, // msg.value in call to account - abi.encodeCall( - account2.executeFromPluginExternal, - (address(counter), 0, abi.encodePacked(counter.increment.selector)) - ) - ), - 0 // msg value in call to plugin - ); - emit ReceivedCall( - abi.encodeCall(IPlugin.postExecutionHook, (injectedHooksInfo.postExecHookFunctionId, "")), - 0 // msg value in call to plugin - ); - vm.prank(address(newPlugin)); - account2.executeFromPluginExternal(address(counter), 0, abi.encodePacked(counter.increment.selector)); - } - - function test_injectHooksApplyGoodCalldata() external { - MockPlugin hooksPlugin = _installPluginWithExecHooks(); - - MockPlugin newPlugin = new MockPlugin(manifest); - - bytes32 manifestHash = keccak256(abi.encode(newPlugin.pluginManifest())); - - IPluginManager.InjectedHook[] memory hooks = new IPluginManager.InjectedHook[](1); - bytes memory onApplyData = abi.encode(keccak256("randomdata")); - hooks[0] = IPluginManager.InjectedHook( - address(hooksPlugin), - IPluginExecutor.executeFromPluginExternal.selector, - injectedHooksInfo, - onApplyData - ); - - vm.expectEmit(true, true, true, true); - emit PluginInstalled(address(newPlugin), manifestHash, new FunctionReference[](0), hooks); - emit ReceivedCall( - abi.encodeCall(IPlugin.onHookApply, (address(newPlugin), injectedHooksInfo, onApplyData)), 0 - ); - vm.prank(owner2); - IPluginManager(account2).installPlugin({ - plugin: address(newPlugin), - manifestHash: manifestHash, - pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: hooks - }); - } - - function test_injectHooksMissingPlugin() external { - // hooks plugin not installed - MockPlugin hooksPlugin = MockPlugin(payable(address(1))); - - MockPlugin newPlugin = new MockPlugin(manifest); - - bytes32 manifestHash = keccak256(abi.encode(newPlugin.pluginManifest())); - - IPluginManager.InjectedHook[] memory hooks = new IPluginManager.InjectedHook[](1); - hooks[0] = IPluginManager.InjectedHook( - address(hooksPlugin), IPluginExecutor.executeFromPluginExternal.selector, injectedHooksInfo, "" - ); - - vm.expectRevert( - abi.encodeWithSelector(PluginManagerInternals.MissingPluginDependency.selector, address(hooksPlugin)) - ); - vm.prank(owner2); - IPluginManager(account2).installPlugin({ - plugin: address(newPlugin), - manifestHash: manifestHash, - pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: hooks - }); - } - - function test_injectHooksUninstall() external { - (, MockPlugin newPlugin,) = _installWithInjectHooks(); - - vm.expectEmit(true, true, true, true); - emit PluginUninstalled(address(newPlugin), true); - vm.prank(owner2); - IPluginManager(account2).uninstallPlugin({ - plugin: address(newPlugin), - config: "", - pluginUninstallData: "", - hookUnapplyData: new bytes[](0) - }); - } - - function test_injectHooksBadUninstallDependency() external { - (MockPlugin hooksPlugin,,) = _installWithInjectHooks(); - - vm.prank(owner2); - vm.expectRevert( - abi.encodeWithSelector(PluginManagerInternals.PluginDependencyViolation.selector, address(hooksPlugin)) - ); - IPluginManager(account2).uninstallPlugin({ - plugin: address(hooksPlugin), - config: "", - pluginUninstallData: "", - hookUnapplyData: new bytes[](0) - }); - } - - function test_injectHooksUnapplyGoodCalldata() external { - (, MockPlugin newPlugin,) = _installWithInjectHooks(); - - bytes[] memory injectedHooksDatas = new bytes[](1); - injectedHooksDatas[0] = abi.encode(keccak256("randomdata")); - - vm.expectEmit(true, true, true, true); - emit ReceivedCall( - abi.encodeCall(IPlugin.onHookUnapply, (address(newPlugin), injectedHooksInfo, injectedHooksDatas[0])), - 0 - ); - vm.prank(owner2); - IPluginManager(account2).uninstallPlugin({ - plugin: address(newPlugin), - config: "", - pluginUninstallData: "", - hookUnapplyData: injectedHooksDatas - }); - } - - function test_injectHooksUnapplyBadCalldata() external { - (, MockPlugin newPlugin,) = _installWithInjectHooks(); - - // length != installed hooks length - bytes[] memory injectedHooksDatas = new bytes[](2); - - vm.expectRevert(PluginManagerInternals.ArrayLengthMismatch.selector); - vm.prank(owner2); - IPluginManager(account2).uninstallPlugin({ - plugin: address(newPlugin), - config: "", - pluginUninstallData: "", - hookUnapplyData: injectedHooksDatas - }); - } - // Internal Functions function _printStorageReadsAndWrites(address addr) internal { diff --git a/test/account/ValidationIntersection.t.sol b/test/account/ValidationIntersection.t.sol index d098b40b..ea8f5bcc 100644 --- a/test/account/ValidationIntersection.t.sol +++ b/test/account/ValidationIntersection.t.sol @@ -6,7 +6,6 @@ import {UserOperation} from "@eth-infinitism/account-abstraction/interfaces/User import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol"; -import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; @@ -49,22 +48,19 @@ contract ValidationIntersectionTest is OptimizedTest { plugin: address(noHookPlugin), manifestHash: keccak256(abi.encode(noHookPlugin.pluginManifest())), pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); account1.installPlugin({ plugin: address(oneHookPlugin), manifestHash: keccak256(abi.encode(oneHookPlugin.pluginManifest())), pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); account1.installPlugin({ plugin: address(twoHookPlugin), manifestHash: keccak256(abi.encode(twoHookPlugin.pluginManifest())), pluginInitData: "", - dependencies: new FunctionReference[](0), - injectedHooks: new IPluginManager.InjectedHook[](0) + dependencies: new FunctionReference[](0) }); vm.stopPrank(); } diff --git a/test/mocks/plugins/ComprehensivePlugin.sol b/test/mocks/plugins/ComprehensivePlugin.sol index 4be37ff8..30b656cd 100644 --- a/test/mocks/plugins/ComprehensivePlugin.sol +++ b/test/mocks/plugins/ComprehensivePlugin.sol @@ -226,21 +226,6 @@ contract ComprehensivePlugin is BasePlugin { }) }); - manifest.permittedCallHooks = new ManifestExecutionHook[](1); - manifest.permittedCallHooks[0] = ManifestExecutionHook({ - executionSelector: this.foo.selector, - preExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: uint8(FunctionId.PRE_PERMITTED_CALL_EXECUTION_HOOK), - dependencyIndex: 0 // Unused. - }), - postExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: uint8(FunctionId.POST_PERMITTED_CALL_EXECUTION_HOOK), - dependencyIndex: 0 // Unused. - }) - }); - return manifest; } diff --git a/test/mocks/plugins/ExecFromPluginPermissionsMocks.sol b/test/mocks/plugins/ExecFromPluginPermissionsMocks.sol index ece287cf..e858d8ee 100644 --- a/test/mocks/plugins/ExecFromPluginPermissionsMocks.sol +++ b/test/mocks/plugins/ExecFromPluginPermissionsMocks.sol @@ -204,130 +204,3 @@ contract EFPCallerPluginAnyExternal is BaseTestPlugin { return IPluginExecutor(msg.sender).executeFromPluginExternal(target, value, data); } } - -// Create pre and post permitted call hooks for calling ResultCreatorPlugin.foo via `executeFromPlugin` -contract EFPPermittedCallHookPlugin is BaseTestPlugin { - bool public preExecHookCalled; - bool public postExecHookCalled; - - function preExecutionHook(uint8, address, uint256, bytes calldata) external override returns (bytes memory) { - preExecHookCalled = true; - return "context for post exec hook"; - } - - function postExecutionHook(uint8, bytes calldata preExecHookData) external override { - require( - keccak256(preExecHookData) == keccak256("context for post exec hook"), "Invalid pre exec hook data" - ); - postExecHookCalled = true; - } - - function onInstall(bytes calldata) external override {} - - function onUninstall(bytes calldata) external override {} - - function pluginManifest() external pure override returns (PluginManifest memory) { - PluginManifest memory manifest; - - manifest.executionFunctions = new bytes4[](1); - manifest.executionFunctions[0] = this.performEFPCall.selector; - - manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](1); - manifest.runtimeValidationFunctions[0] = ManifestAssociatedFunction({ - executionSelector: this.performEFPCall.selector, - associatedFunction: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW, - functionId: 0, - dependencyIndex: 0 - }) - }); - - manifest.permittedCallHooks = new ManifestExecutionHook[](1); - manifest.permittedCallHooks[0] = ManifestExecutionHook({ - executionSelector: ResultCreatorPlugin.foo.selector, - preExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: 0, - dependencyIndex: 0 - }), - postExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: 0, - dependencyIndex: 0 - }) - }); - - manifest.permittedExecutionSelectors = new bytes4[](1); - manifest.permittedExecutionSelectors[0] = ResultCreatorPlugin.foo.selector; - - return manifest; - } - - function performEFPCall() external returns (bytes memory) { - return IPluginExecutor(msg.sender).executeFromPlugin(abi.encodeCall(ResultCreatorPlugin.foo, ())); - } -} - -// Creates pre and post permitted call hooks for `executeFromPluginExternal` -contract EFPExternalPermittedCallHookPlugin is BaseTestPlugin { - bool public preExecHookCalled; - bool public postExecHookCalled; - - function onInstall(bytes calldata) external override {} - - function onUninstall(bytes calldata) external override {} - - function preExecutionHook(uint8, address, uint256, bytes calldata) external override returns (bytes memory) { - preExecHookCalled = true; - return "context for post exec hook"; - } - - function postExecutionHook(uint8, bytes calldata preExecHookData) external override { - require( - keccak256(preExecHookData) == keccak256("context for post exec hook"), "Invalid pre exec hook data" - ); - postExecHookCalled = true; - } - - function pluginManifest() external pure override returns (PluginManifest memory) { - PluginManifest memory manifest; - - manifest.executionFunctions = new bytes4[](1); - manifest.executionFunctions[0] = this.performIncrement.selector; - - manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](1); - manifest.runtimeValidationFunctions[0] = ManifestAssociatedFunction({ - executionSelector: this.performIncrement.selector, - associatedFunction: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW, - functionId: 0, - dependencyIndex: 0 - }) - }); - - manifest.permittedCallHooks = new ManifestExecutionHook[](1); - manifest.permittedCallHooks[0] = ManifestExecutionHook({ - executionSelector: IPluginExecutor.executeFromPluginExternal.selector, - preExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: 0, - dependencyIndex: 0 - }), - postExecHook: ManifestFunction({ - functionType: ManifestAssociatedFunctionType.SELF, - functionId: 0, - dependencyIndex: 0 - }) - }); - - manifest.permitAnyExternalAddress = true; - - return manifest; - } - - function performIncrement() external { - IPluginExecutor(msg.sender).executeFromPluginExternal( - counter1, 0, abi.encodeWithSelector(Counter.increment.selector) - ); - } -} diff --git a/test/plugin/TokenReceiverPlugin.t.sol b/test/plugin/TokenReceiverPlugin.t.sol index c3a7a03a..49692e34 100644 --- a/test/plugin/TokenReceiverPlugin.t.sol +++ b/test/plugin/TokenReceiverPlugin.t.sol @@ -10,7 +10,6 @@ import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Re import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {FunctionReference} from "../../src/helpers/FunctionReferenceLib.sol"; -import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; import {TokenReceiverPlugin} from "../../src/plugins/TokenReceiverPlugin.sol"; import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; @@ -61,9 +60,7 @@ contract TokenReceiverPluginTest is OptimizedTest, IERC1155Receiver { function _initPlugin() internal { bytes32 manifestHash = keccak256(abi.encode(plugin.pluginManifest())); - acct.installPlugin( - address(plugin), manifestHash, "", new FunctionReference[](0), new IPluginManager.InjectedHook[](0) - ); + acct.installPlugin(address(plugin), manifestHash, "", new FunctionReference[](0)); } function test_failERC721Transfer() public {