@@ -328,6 +328,27 @@ abstract contract ModuleManager is AllStorage, EIP712, IModuleManager {
328328 }
329329 }
330330
331+ // Review: if uninstalling selectors also need some data.
332+ function _tryUninstallFallbacks () internal {
333+ AccountStorage storage ds = _getAccountStorage ();
334+ uint256 len = ds.fallbackSelectors.length ;
335+
336+ for (uint256 i = 0 ; i < len; i++ ) {
337+ bytes4 selector = ds.fallbackSelectors[i];
338+ FallbackHandler memory handler = ds.fallbacks[selector];
339+
340+ if (address (handler.handler) == address (0 )) continue ;
341+
342+ handler.handler.excessivelySafeCall (
343+ gasleft (), 0 , 0 , abi.encodeWithSelector (IModule.onUninstall.selector , abi.encodePacked (selector))
344+ );
345+
346+ ds.fallbacks[selector] = FallbackHandler (address (0 ), CallType.wrap (0x00 ));
347+ }
348+
349+ delete ds.fallbackSelectors;
350+ }
351+
331352 /// @dev Sets the current hook in the storage to the specified address.
332353 /// @param hook The new hook address.
333354 function _setHook (address hook ) internal virtual {
@@ -365,9 +386,14 @@ abstract contract ModuleManager is AllStorage, EIP712, IModuleManager {
365386 // This check ensures that we do not overwrite an existing fallback handler, which could lead to unexpected behavior.
366387 require (! _isFallbackHandlerInstalled (selector), FallbackAlreadyInstalledForSelector (selector));
367388
389+ AccountStorage storage ds = _getAccountStorage ();
390+
368391 // Store the fallback handler and its call type in the account storage.
369392 // This maps the function selector to the specified fallback handler and call type.
370- _getAccountStorage ().fallbacks[selector] = FallbackHandler (handler, calltype);
393+ ds.fallbacks[selector] = FallbackHandler (handler, calltype);
394+
395+ // Add the selector to the maintained list of fallback selectors
396+ ds.fallbackSelectors.push (selector);
371397
372398 // Invoke the `onInstall` function of the fallback handler with the provided initialization data.
373399 // This step allows the fallback handler to perform any necessary setup or initialization.
@@ -378,7 +404,20 @@ abstract contract ModuleManager is AllStorage, EIP712, IModuleManager {
378404 /// @param fallbackHandler The address of the fallback handler to uninstall.
379405 /// @param data The de-initialization data containing the selector.
380406 function _uninstallFallbackHandler (address fallbackHandler , bytes calldata data ) internal virtual {
381- _getAccountStorage ().fallbacks[bytes4 (data[0 :4 ])] = FallbackHandler (address (0 ), CallType.wrap (0x00 ));
407+ AccountStorage storage ds = _getAccountStorage ();
408+ bytes4 selector = bytes4 (data[0 :4 ]);
409+ ds.fallbacks[selector] = FallbackHandler (address (0 ), CallType.wrap (0x00 ));
410+
411+ // Remove selector from fallbackSelectors via swap-and-pop
412+ uint256 len = ds.fallbackSelectors.length ;
413+ for (uint256 i = 0 ; i < len; i++ ) {
414+ if (ds.fallbackSelectors[i] == selector) {
415+ ds.fallbackSelectors[i] = ds.fallbackSelectors[len - 1 ];
416+ ds.fallbackSelectors.pop ();
417+ break ;
418+ }
419+ }
420+
382421 fallbackHandler.excessivelySafeCall (gasleft (), 0 , 0 , abi.encodeWithSelector (IModule.onUninstall.selector , data[4 :]));
383422 }
384423
0 commit comments