Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[profile.default]
evm_version = "cancun"
evm_version = "prague"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

evm_version = "prague"

src = "src"
out = "out"
libs = ["node_modules"]
Expand Down
21 changes: 18 additions & 3 deletions src/MSAAdvanced.sol
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ contract MSAAdvanced is
if (isERC7702) {
_addStorageBase(MODULEMANAGER_STORAGE_LOCATION);
_addStorageBase(HOOKMANAGER_STORAGE_LOCATION);
_addStorageBase(PREVALIDATION_HOOKMANAGER_STORAGE_LOCATION);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

        _addStorageBase(PREVALIDATION_HOOKMANAGER_STORAGE_LOCATION);

}

// bootstrap the account
Expand All @@ -438,10 +439,24 @@ contract MSAAdvanced is
if (!success) revert();
}

function _onRedelegation() internal override {
_tryUninstallValidators();
_tryUninstallExecutors();
function _onRedelegation(bytes calldata context) internal override {
// Decode the context data which should contain arrays of uninstall data for validators and executors
(bytes[] memory validatorUninstallData, bytes[] memory executorUninstallData) = abi.decode(context, (bytes[], bytes[]));

// Call the uninstall functions with the decoded data
_tryUninstallValidators(validatorUninstallData);
_tryUninstallExecutors(executorUninstallData);

// Continue with other uninstallations
_tryUninstallHook(_getHook());
_tryUninstallPreValidationHook(
_getPreValidationHook(MODULE_TYPE_PREVALIDATION_HOOK_ERC1271),
MODULE_TYPE_PREVALIDATION_HOOK_ERC1271
);
_tryUninstallPreValidationHook(
_getPreValidationHook(MODULE_TYPE_PREVALIDATION_HOOK_ERC4337),
MODULE_TYPE_PREVALIDATION_HOOK_ERC4337
);
_initModuleManager();
}
}
14 changes: 11 additions & 3 deletions src/core/ERC7779Adapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ abstract contract ERC7779Adapter is IERC7779 {
assembly {
$.slot := ERC7779_STORAGE_BASE
}
// Check if the storageBase already exists to avoid duplication
for (uint256 i = 0; i < $.storageBases.length; i++) {
if ($.storageBases[i] == storageBase) {
return; // Exit if the storageBase is already present
}
}
$.storageBases.push(storageBase);
}

Expand All @@ -54,14 +60,16 @@ abstract contract ERC7779Adapter is IERC7779 {
* It should uninitialize storages if needed and execute wallet-specific logic to prepare
for redelegation.
* msg.sender should be the owner of the account.
* @param context - The context of the redelegation. Additional data required to uninitialize storages.
*/
function onRedelegation() external returns (bool) {
function onRedelegation(bytes calldata context) external returns (bool) {
require(msg.sender == address(this), NonAuthorizedOnRedelegationCaller());
_onRedelegation();
_onRedelegation(context);
return true;
}

/// @dev This function is called before redelegation.
/// @dev Account should override this function to implement the specific logic.
function _onRedelegation() internal virtual;
/// @param context The context is the additional data required to uninitialize storages.
function _onRedelegation(bytes calldata context) internal virtual;
}
58 changes: 28 additions & 30 deletions src/core/ModuleManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,36 +95,35 @@ abstract contract ModuleManager is AccountBase, Receiver {
IValidator(validator).onUninstall(disableModuleData);
}

/*
function _tryUninstallValidators(bytes[] calldata data) internal {
function _tryUninstallValidators() internal virtual {
SentinelListLib.SentinelList storage $valdiators = $moduleManager().$valdiators;
uint256 length = data.length;
uint256 index;
address validator = $valdiators.getNext(SENTINEL);
while (validator != SENTINEL) {
bytes memory uninstallData;
if (index < length) {
uninstallData = data[index];
}
try IValidator(validator).onUninstall(uninstallData) {} catch {
emit ValidatorUninstallFailed(validator, uninstallData);
try IValidator(validator).onUninstall("") { }
catch {
emit ValidatorUninstallFailed(validator, "");
}
validator = $valdiators.getNext(validator);
index++;
}
$valdiators.popAll();
}
*/

function _tryUninstallValidators() internal {
function _tryUninstallValidators(bytes[] memory data) internal virtual {
SentinelListLib.SentinelList storage $valdiators = $moduleManager().$valdiators;
uint256 length = data.length;
uint256 index;
address validator = $valdiators.getNext(SENTINEL);
while (validator != SENTINEL) {
try IValidator(validator).onUninstall("") { }
bytes memory uninstallData;
if (index < length) {
uninstallData = data[index];
}
try IValidator(validator).onUninstall(uninstallData) { }
catch {
emit ValidatorUninstallFailed(validator, "");
emit ValidatorUninstallFailed(validator, uninstallData);
}
validator = $valdiators.getNext(validator);
index++;
}
$valdiators.popAll();
}
Expand Down Expand Up @@ -168,36 +167,35 @@ abstract contract ModuleManager is AccountBase, Receiver {
IExecutor(executor).onUninstall(disableModuleData);
}

/*
function _tryUninstallExecutors(bytes[] calldata data) internal {
function _tryUninstallExecutors() internal virtual {
SentinelListLib.SentinelList storage $executors = $moduleManager().$executors;
uint256 length = data.length;
uint256 index;
address executor = $executors.getNext(SENTINEL);
while (executor != SENTINEL) {
bytes memory uninstallData;
if (index < length) {
uninstallData = data[index];
}
try IExecutor(executor).onUninstall(uninstallData) {} catch {
emit ExecutorUninstallFailed(executor, uninstallData);
try IExecutor(executor).onUninstall("") { }
catch {
emit ExecutorUninstallFailed(executor, "");
}
executor = $executors.getNext(executor);
index++;
}
$executors.popAll();
}
*/

function _tryUninstallExecutors() internal {
function _tryUninstallExecutors(bytes[] memory data) internal virtual {
SentinelListLib.SentinelList storage $executors = $moduleManager().$executors;
uint256 length = data.length;
uint256 index;
address executor = $executors.getNext(SENTINEL);
while (executor != SENTINEL) {
try IExecutor(executor).onUninstall("") { }
bytes memory uninstallData;
if (index < length) {
uninstallData = data[index];
}
try IExecutor(executor).onUninstall(uninstallData) { }
catch {
emit ExecutorUninstallFailed(executor, "");
emit ExecutorUninstallFailed(executor, uninstallData);
}
executor = $executors.getNext(executor);
index++;
}
$executors.popAll();
}
Expand Down
1 change: 1 addition & 0 deletions src/core/PreValidationHookManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ abstract contract PreValidationHookManager {
}

function _tryUninstallPreValidationHook(address hook, uint256 hookType) internal virtual {
if (hook == address(0)) return;
PreValidationHookManagerStorage storage $ = _getStorage();
if (hookType == MODULE_TYPE_PREVALIDATION_HOOK_ERC1271) {
try $.hook1271.onUninstall("") { }
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IERC7779.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface IERC7779 {
* It should uninitialize storages if needed and execute wallet-specific logic to prepare
for redelegation.
* msg.sender should be the owner of the account.
* @param context - The context of the redelegation. Additional data required to uninitialize storages.
*/
function onRedelegation() external returns (bool);
function onRedelegation(bytes calldata context) external returns (bool);
}
2 changes: 1 addition & 1 deletion test/advanced/EIP7702.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ contract EIP7702 is TestBaseUtilAdvanced {
assertTrue(IMSA(account).isModuleInstalled(MODULE_TYPE_HOOK, address(hook), ""));
// storage is cleared
vm.prank(address(account));
IMSA(account).onRedelegation();
IMSA(account).onRedelegation(bytes(""));
assertFalse(
IMSA(account).isModuleInstalled(MODULE_TYPE_VALIDATOR, address(defaultValidator), "")
);
Expand Down
2 changes: 1 addition & 1 deletion test/mocks/MockERC7779.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ contract MockERC7779 is ERC7779Adapter {
_addStorageBase(storageBase);
}

function _onRedelegation() internal override {
function _onRedelegation(bytes calldata context) internal override {
// do nothing
}
}
Loading