Skip to content

Commit

Permalink
Merge pull request #28 from zkemail/feat/add-is-activated-function
Browse files Browse the repository at this point in the history
Add functions which returns the user state is in module enabled or recovery is activated.
  • Loading branch information
JohnGuilding authored Aug 6, 2024
2 parents 03f5547 + ca8fb13 commit 95a3fcb
Show file tree
Hide file tree
Showing 18 changed files with 172 additions and 155 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
"dependencies": {
"@matterlabs": "github:matter-labs/era-contracts",
"@openzeppelin/contracts-upgradeable": "v5.0.1",
"@rhinestone/modulekit": "github:rhinestonewtf/modulekit#test/safe-latest",
"@rhinestone/modulekit": "github:rhinestonewtf/modulekit",
"@zk-email/contracts": "v6.0.3",
"email-wallet-sdk": "github:zkemail/email-wallet-sdk",
"erc7579-implementation": "github:erc7579/erc7579-implementation",
"ether-email-auth": "github:zkemail/ether-email-auth",
"ether-email-auth": "github:zkemail/ether-email-auth#711c7892c244b210febe9d6f8cc28eddbce5fbdc",
"solidity-stringutils": "github:Arachnid/solidity-stringutils"
},
"files": [
Expand Down
144 changes: 83 additions & 61 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions src/EmailRecoveryManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ abstract contract EmailRecoveryManager is
return recoveryRequests[account];
}

/**
* @notice Checks if the recovery is activated for a given account
* @param account The address of the account for which the activation status is being checked
* @return bool True if the recovery request is activated, false otherwise
*/
function isActivated(address account) public view override returns (bool) {
return guardianConfigs[account].threshold > 0;
}

/**
* @notice Returns a two-dimensional array of strings representing the subject templates for an
* acceptance by a new guardian.
Expand Down Expand Up @@ -273,6 +282,10 @@ abstract contract EmailRecoveryManager is
revert RecoveryInProcess();
}

if (!isActivated(account)) {
revert RecoveryIsNotActivated();
}

// This check ensures GuardianStatus is correct and also implicitly that the
// account in email is a valid account
GuardianStorage memory guardianStorage = getGuardian(account, guardian);
Expand Down Expand Up @@ -313,6 +326,10 @@ abstract contract EmailRecoveryManager is
templateIdx, subjectParams, address(this)
);

if (!isActivated(account)) {
revert RecoveryIsNotActivated();
}

GuardianConfig memory guardianConfig = guardianConfigs[account];
if (guardianConfig.threshold > guardianConfig.acceptedWeight) {
revert ThresholdExceedsAcceptedWeight(
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/IEmailRecoveryManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ interface IEmailRecoveryManager {
error RecoveryRequestExpired(uint256 blockTimestamp, uint256 executeBefore);
error InvalidCalldataHash(bytes32 calldataHash, bytes32 expectedCalldataHash);
error NoRecoveryInProcess();
error RecoveryIsNotActivated();

/*//////////////////////////////////////////////////////////////////////////
FUNCTIONS
Expand Down
1 change: 0 additions & 1 deletion src/modules/EmailRecoveryModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ contract EmailRecoveryModule is EmailRecoveryManager, ERC7579ExecutorBase, IEmai
) {
revert InvalidValidator(validator);
}

configureRecovery(guardians, weights, threshold, delay, expiry);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,7 @@ contract EmailRecoveryManager_Integration_Test is
EmailAuthMsg memory emailAuthMsg =
getAcceptanceEmailAuthMessage(accountAddress1, guardians1[0]);

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleAcceptance(emailAuthMsg, templateIdx);
}

Expand Down Expand Up @@ -212,23 +206,11 @@ contract EmailRecoveryManager_Integration_Test is
vm.warp(12 seconds);

emailAuthMsg = getRecoveryEmailAuthMessage(accountAddress1, guardians1[0], calldataHash1);
vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.ACCEPTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleRecovery(emailAuthMsg, templateIdx);

emailAuthMsg = getRecoveryEmailAuthMessage(accountAddress1, guardians1[1], calldataHash1);
vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.ACCEPTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleRecovery(emailAuthMsg, templateIdx);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,7 @@ contract OwnableValidatorRecovery_EmailRecoveryModule_Integration_Test is
EmailAuthMsg memory emailAuthMsg =
getAcceptanceEmailAuthMessage(accountAddress1, guardians1[0]);

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleAcceptance(emailAuthMsg, templateIdx);
}

Expand All @@ -160,13 +154,7 @@ contract OwnableValidatorRecovery_EmailRecoveryModule_Integration_Test is
EmailAuthMsg memory emailAuthMsg =
getAcceptanceEmailAuthMessage(accountAddress1, guardians1[1]);

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleAcceptance(emailAuthMsg, templateIdx);
}

Expand All @@ -181,13 +169,8 @@ contract OwnableValidatorRecovery_EmailRecoveryModule_Integration_Test is
getRecoveryEmailAuthMessage(accountAddress1, guardians1[0], calldataHash1);

instance1.uninstallModule(MODULE_TYPE_EXECUTOR, recoveryModuleAddress, "");
vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.ACCEPTED)
)
);

vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleRecovery(emailAuthMsg, templateIdx);
}

Expand Down Expand Up @@ -227,13 +210,7 @@ contract OwnableValidatorRecovery_EmailRecoveryModule_Integration_Test is
EmailAuthMsg memory emailAuthMsg =
getAcceptanceEmailAuthMessage(accountAddress1, guardians1[0]);

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleAcceptance(emailAuthMsg, templateIdx);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,7 @@ contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Integration_Test
EmailAuthMsg memory emailAuthMsg =
getAcceptanceEmailAuthMessage(accountAddress1, guardians1[0]);

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleAcceptance(emailAuthMsg, templateIdx);
}

Expand All @@ -158,13 +152,7 @@ contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Integration_Test
EmailAuthMsg memory emailAuthMsg =
getAcceptanceEmailAuthMessage(accountAddress1, guardians1[1]);

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleAcceptance(emailAuthMsg, templateIdx);
}

Expand All @@ -179,13 +167,8 @@ contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Integration_Test
getRecoveryEmailAuthMessage(accountAddress1, guardians1[0], calldataHash1);

instance1.uninstallModule(MODULE_TYPE_EXECUTOR, recoveryModuleAddress, "");
vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.ACCEPTED)
)
);

vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleRecovery(emailAuthMsg, templateIdx);
}

Expand Down Expand Up @@ -225,13 +208,7 @@ contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Integration_Test
EmailAuthMsg memory emailAuthMsg =
getAcceptanceEmailAuthMessage(accountAddress1, guardians1[0]);

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.handleAcceptance(emailAuthMsg, templateIdx);
}

Expand Down
8 changes: 1 addition & 7 deletions test/unit/EmailRecoveryManager/acceptGuardian.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,7 @@ contract EmailRecoveryManager_acceptGuardian_Test is UnitBase {
instance.uninstallModule(MODULE_TYPE_EXECUTOR, recoveryModuleAddress, "");
vm.stopPrank();

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.REQUESTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.exposed_acceptGuardian(guardian1, templateIdx, subjectParams, nullifier);
}

Expand Down
6 changes: 6 additions & 0 deletions test/unit/EmailRecoveryManager/configureRecovery.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ contract EmailRecoveryManager_configureRecovery_Test is UnitBase {
vm.startPrank(accountAddress);
emailRecoveryModule.workaround_validatorsPush(accountAddress, validatorAddress);

bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertFalse(isActivated);

vm.expectEmit();
emit IEmailRecoveryManager.RecoveryConfigured(
instance.account, guardians.length, totalWeight, threshold
Expand All @@ -66,6 +69,9 @@ contract EmailRecoveryManager_configureRecovery_Test is UnitBase {
emailRecoveryModule.getGuardian(accountAddress, guardians[0]);
assertEq(uint256(guardian.status), uint256(GuardianStatus.REQUESTED));
assertEq(guardian.weight, guardianWeights[0]);

isActivated = emailRecoveryModule.isActivated(accountAddress);
assertTrue(isActivated);
}

function test_ConfigureRecovery_RevertWhen_ZeroGuardians() public {
Expand Down
6 changes: 6 additions & 0 deletions test/unit/EmailRecoveryManager/deInitRecoveryModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ contract EmailRecoveryManager_deInitRecoveryModule_Test is UnitBase {
acceptGuardian(accountSalt1);
acceptGuardian(accountSalt2);

bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertTrue(isActivated);

vm.prank(accountAddress);
vm.expectEmit();
emit IEmailRecoveryManager.RecoveryDeInitialized(accountAddress);
Expand Down Expand Up @@ -66,5 +69,8 @@ contract EmailRecoveryManager_deInitRecoveryModule_Test is UnitBase {
assertEq(guardianConfig.totalWeight, 0);
assertEq(guardianConfig.acceptedWeight, 0);
assertEq(guardianConfig.threshold, 0);

isActivated = emailRecoveryModule.isActivated(accountAddress);
assertFalse(isActivated);
}
}
29 changes: 29 additions & 0 deletions test/unit/EmailRecoveryManager/isActivated.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import { console2 } from "forge-std/console2.sol";
import { ModuleKitHelpers } from "modulekit/ModuleKit.sol";
import { MODULE_TYPE_EXECUTOR } from "modulekit/external/ERC7579.sol";
import { IEmailRecoveryManager } from "src/interfaces/IEmailRecoveryManager.sol";
import { GuardianStorage, GuardianStatus } from "src/libraries/EnumerableGuardianMap.sol";
import { UnitBase } from "../UnitBase.t.sol";

contract EmailRecoveryManager_isActivated_Test is UnitBase {
using ModuleKitHelpers for *;

function setUp() public override {
super.setUp();
}

function test_isActivated_ReturnsTrueWhenModuleIsInstalled() public {
bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertTrue(isActivated);
}

function test_isActivated_ReturnsFalseWhenModuleIsInstalled() public {
instance.uninstallModule(MODULE_TYPE_EXECUTOR, recoveryModuleAddress, "");

bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertFalse(isActivated);
}
}
8 changes: 1 addition & 7 deletions test/unit/EmailRecoveryManager/processRecovery.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,7 @@ contract EmailRecoveryManager_processRecovery_Test is UnitBase {
instance.uninstallModule(MODULE_TYPE_EXECUTOR, recoveryModuleAddress, "");
vm.stopPrank();

vm.expectRevert(
abi.encodeWithSelector(
IEmailRecoveryManager.InvalidGuardianStatus.selector,
uint256(GuardianStatus.NONE),
uint256(GuardianStatus.ACCEPTED)
)
);
vm.expectRevert(IEmailRecoveryManager.RecoveryIsNotActivated.selector);
emailRecoveryModule.exposed_processRecovery(
guardian1, templateIdx, subjectParams, nullifier
);
Expand Down
1 change: 1 addition & 0 deletions test/unit/assertErrorSelectors.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ contract LogErrorSelectors_Test is Test {
assertEq(IEmailRecoveryManager.RecoveryRequestExpired.selector, bytes4(0x566ad75e));
assertEq(IEmailRecoveryManager.InvalidCalldataHash.selector, bytes4(0x54d53855));
assertEq(IEmailRecoveryManager.NoRecoveryInProcess.selector, bytes4(0x87434f51));
assertEq(IEmailRecoveryManager.RecoveryIsNotActivated.selector, bytes4(0xc737140f));
}

function test_EmailRecoveryUniversalFactory_AssertSelectors() public {
Expand Down
3 changes: 3 additions & 0 deletions test/unit/modules/EmailRecoveryModule/onInstall.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,8 @@ contract EmailRecoveryModule_onInstall_Test is EmailRecoveryModuleBase {

bool isInitialized = emailRecoveryModule.isInitialized(accountAddress);
assertTrue(isInitialized);

bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertTrue(isActivated);
}
}
3 changes: 3 additions & 0 deletions test/unit/modules/EmailRecoveryModule/onUninstall.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@ contract EmailRecoveryModule_onUninstall_Test is EmailRecoveryModuleBase {

bool isInitialized = emailRecoveryModule.isInitialized(accountAddress);
assertFalse(isInitialized);

bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertFalse(isActivated);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,8 @@ contract UniversalEmailRecoveryModule_onInstall_Test is UnitBase {
bytes4[] memory allowedSelectors = emailRecoveryModule.getAllowedSelectors(accountAddress);
assertEq(allowedValidators.length, 1);
assertEq(allowedSelectors.length, 1);

bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertTrue(isActivated);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,8 @@ contract UniversalEmailRecoveryModule_onUninstall_Test is UnitBase {
allowedSelectors = emailRecoveryModule.getAllowedSelectors(accountAddress);
assertEq(allowedValidators.length, 0);
assertEq(allowedSelectors.length, 0);

bool isActivated = emailRecoveryModule.isActivated(accountAddress);
assertFalse(isActivated);
}
}

0 comments on commit 95a3fcb

Please sign in to comment.