Skip to content

Commit

Permalink
Add onlyWhenActive modifier to GuardianManager
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnGuilding committed Nov 2, 2024
1 parent 228e0fb commit a40aecf
Show file tree
Hide file tree
Showing 17 changed files with 73 additions and 23 deletions.
7 changes: 0 additions & 7 deletions src/EmailRecoveryManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,6 @@ abstract contract EmailRecoveryManager is
mapping(address account => PreviousRecoveryRequest previousRecoveryRequest) internal
previousRecoveryRequests;

modifier onlyWhenActive() {
if (killSwitchEnabled) {
revert KillSwitchEnabled();
}
_;
}

constructor(
address _verifier,
address _dkimRegistry,
Expand Down
25 changes: 22 additions & 3 deletions src/GuardianManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ abstract contract GuardianManager is IGuardianManager {
_;
}

/**
* @notice Modifier to check if the kill switch has been enabled
* @dev This impacts EmailRecoveryManager & GuardianManager
*/
modifier onlyWhenActive() {
bool killSwitchEnabled = IEmailRecoveryManager(address(this)).killSwitchEnabled();
if (killSwitchEnabled) {
revert KillSwitchEnabled();
}
_;
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* GUARDIAN LOGIC */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
Expand Down Expand Up @@ -120,7 +132,14 @@ abstract contract GuardianManager is IGuardianManager {
* @param guardian The address of the guardian to be added
* @param weight The weight assigned to the guardian
*/
function addGuardian(address guardian, uint256 weight) public onlyWhenNotRecovering {
function addGuardian(
address guardian,
uint256 weight
)
public
onlyWhenNotRecovering
onlyWhenActive
{
// Threshold can only be 0 at initialization.
// Check ensures that setup function should be called first
if (guardianConfigs[msg.sender].threshold == 0) {
Expand Down Expand Up @@ -165,7 +184,7 @@ abstract contract GuardianManager is IGuardianManager {
* no recovery is in process
* @param guardian The address of the guardian to be removed
*/
function removeGuardian(address guardian) external onlyWhenNotRecovering {
function removeGuardian(address guardian) external onlyWhenNotRecovering onlyWhenActive {
GuardianConfig memory guardianConfig = guardianConfigs[msg.sender];
GuardianStorage memory guardianStorage = guardiansStorage[msg.sender].get(guardian);

Expand Down Expand Up @@ -197,7 +216,7 @@ abstract contract GuardianManager is IGuardianManager {
* only if no recovery is in process
* @param threshold The new threshold for guardian approvals
*/
function changeThreshold(uint256 threshold) external onlyWhenNotRecovering {
function changeThreshold(uint256 threshold) external onlyWhenNotRecovering onlyWhenActive {
// Threshold can only be 0 at initialization.
// Check ensures that setup function should be called first
if (guardianConfigs[msg.sender].threshold == 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IEmailRecoveryManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ interface IEmailRecoveryManager {
/* ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

error KillSwitchEnabled();
error InvalidVerifier();
error InvalidDkimRegistry();
error InvalidEmailAuthImpl();
Expand Down Expand Up @@ -124,6 +123,8 @@ interface IEmailRecoveryManager {
/* FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

function killSwitchEnabled() external returns (bool);

function getRecoveryConfig(address account) external view returns (RecoveryConfig memory);

function getRecoveryRequest(address account)
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/IGuardianManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface IGuardianManager {
event ChangedThreshold(address indexed account, uint256 threshold);

error RecoveryInProcess();
error KillSwitchEnabled();
error IncorrectNumberOfWeights(uint256 guardianCount, uint256 weightCount);
error ThresholdCannotBeZero();
error InvalidGuardianAddress(address guardian);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ contract OwnableValidatorRecovery_EmailRecoveryModule_Integration_Test is
executeRecoveryFlowForAccount(accountAddress1, guardians1, recoveryDataHash1, recoveryData1);

// new module should not be useable
vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
EmailAccountRecovery(newRecoveryModuleAddress).completeRecovery(
accountAddress1, abi.encodePacked("1")
);
Expand Down Expand Up @@ -386,7 +386,7 @@ contract OwnableValidatorRecovery_EmailRecoveryModule_Integration_Test is

instance1.uninstallModule(MODULE_TYPE_EXECUTOR, emailRecoveryModuleAddress, "");
// the second module installation should fail after the kill switch is enabled.
instance1.expect4337Revert(IEmailRecoveryManager.KillSwitchEnabled.selector);
instance1.expect4337Revert(IGuardianManager.KillSwitchEnabled.selector);
instance1.installModule({
moduleTypeId: MODULE_TYPE_EXECUTOR,
module: emailRecoveryModuleAddress,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Integration_Test
string memory currentAccountType = vm.envOr("ACCOUNT_TYPE", string(""));
if (bytes(currentAccountType).length != 0) {
vm.skip(true);
}
}
executeRecoveryFlowForAccount(accountAddress1, guardians1, recoveryDataHash1, recoveryData1);
address updatedOwner1 = validator.owners(accountAddress1);
assertEq(updatedOwner1, newOwner1);
Expand All @@ -497,7 +497,7 @@ contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Integration_Test
IEmailRecoveryManager(emailRecoveryModuleAddress).toggleKillSwitch();
vm.stopPrank();

instance1.expect4337Revert(IEmailRecoveryManager.KillSwitchEnabled.selector);
instance1.expect4337Revert(IGuardianManager.KillSwitchEnabled.selector);
instance1.installModule({
moduleTypeId: MODULE_TYPE_EXECUTOR,
module: emailRecoveryModuleAddress,
Expand Down
2 changes: 1 addition & 1 deletion test/unit/EmailRecoveryManager/acceptGuardian.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ contract EmailRecoveryManager_acceptGuardian_Test is UnitBase {
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.exposed_acceptGuardian(
guardians1[0], templateIdx, commandParams, nullifier
);
Expand Down
3 changes: 2 additions & 1 deletion test/unit/EmailRecoveryManager/cancelExpiredRecovery.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.25;

import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { UnitBase } from "../UnitBase.t.sol";
import { IGuardianManager } from "src/interfaces/IGuardianManager.sol";
import { IEmailRecoveryManager } from "src/interfaces/IEmailRecoveryManager.sol";

contract EmailRecoveryManager_cancelExpiredRecovery_Test is UnitBase {
Expand All @@ -17,7 +18,7 @@ contract EmailRecoveryManager_cancelExpiredRecovery_Test is UnitBase {
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.cancelExpiredRecovery(accountAddress1);
}

Expand Down
3 changes: 2 additions & 1 deletion test/unit/EmailRecoveryManager/cancelRecovery.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.25;

import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { UnitBase } from "../UnitBase.t.sol";
import { IGuardianManager } from "src/interfaces/IGuardianManager.sol";
import { IEmailRecoveryManager } from "src/interfaces/IEmailRecoveryManager.sol";

contract EmailRecoveryManager_cancelRecovery_Test is UnitBase {
Expand All @@ -17,7 +18,7 @@ contract EmailRecoveryManager_cancelRecovery_Test is UnitBase {
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.cancelRecovery();
}

Expand Down
3 changes: 2 additions & 1 deletion test/unit/EmailRecoveryManager/completeRecovery.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.25;

import { UnitBase } from "../UnitBase.t.sol";
import { IGuardianManager } from "src/interfaces/IGuardianManager.sol";
import { IEmailRecoveryManager } from "src/interfaces/IEmailRecoveryManager.sol";

contract EmailRecoveryManager_completeRecovery_Test is UnitBase {
Expand All @@ -14,7 +15,7 @@ contract EmailRecoveryManager_completeRecovery_Test is UnitBase {
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.completeRecovery(accountAddress1, recoveryData);
}

Expand Down
2 changes: 1 addition & 1 deletion test/unit/EmailRecoveryManager/configureRecovery.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ contract EmailRecoveryManager_configureRecovery_Test is UnitBase {
vm.stopPrank();

vm.startPrank(accountAddress1);
vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.exposed_configureRecovery(
guardians1, guardianWeights, threshold, delay, expiry
);
Expand Down
3 changes: 2 additions & 1 deletion test/unit/EmailRecoveryManager/processRecovery.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { CommandHandlerType } from "../../Base.t.sol";
import { IEmailRecoveryManager } from "src/interfaces/IEmailRecoveryManager.sol";
import { IEmailRecoveryCommandHandler } from "src/interfaces/IEmailRecoveryCommandHandler.sol";
import { GuardianStatus } from "src/libraries/EnumerableGuardianMap.sol";
import { IGuardianManager } from "src/interfaces/IGuardianManager.sol";

contract EmailRecoveryManager_processRecovery_Test is UnitBase {
using ModuleKitHelpers for *;
Expand Down Expand Up @@ -50,7 +51,7 @@ contract EmailRecoveryManager_processRecovery_Test is UnitBase {
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.exposed_processRecovery(
guardians1[0], templateIdx, commandParams, nullifier
);
Expand Down
2 changes: 1 addition & 1 deletion test/unit/EmailRecoveryManager/updateRecoveryConfig.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ contract EmailRecoveryManager_updateRecoveryConfig_Test is UnitBase {
vm.stopPrank();

vm.startPrank(accountAddress1);
vm.expectRevert(IEmailRecoveryManager.KillSwitchEnabled.selector);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.updateRecoveryConfig(recoveryConfig);
}

Expand Down
10 changes: 10 additions & 0 deletions test/unit/GuardianManager/addGuardian.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ contract GuardianManager_addGuardian_Test is UnitBase {
super.setUp();
}

function test_AddGuardian_RevertWhen_KillSwitchEnabled() public {
vm.prank(killSwitchAuthorizer);
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.startPrank(accountAddress1);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.addGuardian(guardians1[0], guardianWeights[0]);
}

function test_AddGuardian_RevertWhen_AlreadyRecovering() public {
acceptGuardian(accountAddress1, guardians1[0], emailRecoveryModuleAddress);
acceptGuardian(accountAddress1, guardians1[1], emailRecoveryModuleAddress);
Expand Down
10 changes: 10 additions & 0 deletions test/unit/GuardianManager/changeThreshold.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ contract GuardianManager_changeThreshold_Test is UnitBase {
super.setUp();
}

function test_RevertWhen_KillSwitchEnabled() public {
vm.prank(killSwitchAuthorizer);
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.startPrank(accountAddress1);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.changeThreshold(threshold);
}

function test_RevertWhen_AlreadyRecovering() public {
acceptGuardian(accountAddress1, guardians1[0], emailRecoveryModuleAddress);
acceptGuardian(accountAddress1, guardians1[1], emailRecoveryModuleAddress);
Expand Down
12 changes: 12 additions & 0 deletions test/unit/GuardianManager/removeGuardian.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ contract GuardianManager_removeGuardian_Test is UnitBase {
super.setUp();
}

function test_RemoveGuardian_RevertWhen_KillSwitchEnabled() public {
address guardian = guardians1[0];

vm.prank(killSwitchAuthorizer);
emailRecoveryModule.toggleKillSwitch();
vm.stopPrank();

vm.startPrank(accountAddress1);
vm.expectRevert(IGuardianManager.KillSwitchEnabled.selector);
emailRecoveryModule.removeGuardian(guardian);
}

function test_RemoveGuardian_RevertWhen_AlreadyRecovering() public {
address guardian = guardians1[0];

Expand Down
2 changes: 1 addition & 1 deletion test/unit/assertErrorSelectors.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ contract LogErrorSelectors_Test is Test {
}

function test_IEmailRecoveryManager_AssertSelectors() public pure {
assertEq(IEmailRecoveryManager.KillSwitchEnabled.selector, bytes4(0xec7fb2a0));
assertEq(IEmailRecoveryManager.InvalidVerifier.selector, bytes4(0xbaa3de5f));
assertEq(IEmailRecoveryManager.InvalidDkimRegistry.selector, bytes4(0x260ce05b));
assertEq(IEmailRecoveryManager.InvalidEmailAuthImpl.selector, bytes4(0xe98100fb));
Expand Down Expand Up @@ -117,6 +116,7 @@ contract LogErrorSelectors_Test is Test {

function test_IGuardianManager_AssertSelectors() public pure {
assertEq(IGuardianManager.RecoveryInProcess.selector, bytes4(0xf90ea6fc));
assertEq(IGuardianManager.KillSwitchEnabled.selector, bytes4(0xec7fb2a0));
assertEq(IGuardianManager.IncorrectNumberOfWeights.selector, bytes4(0x166e79bd));
assertEq(IGuardianManager.ThresholdCannotBeZero.selector, bytes4(0xf4124166));
assertEq(IGuardianManager.InvalidGuardianAddress.selector, bytes4(0x1af74975));
Expand Down

0 comments on commit a40aecf

Please sign in to comment.