From 6b0c2e7c671b81e0691339b6f35f2e300a79ea4a Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Thu, 4 Jul 2024 10:38:23 +0900 Subject: [PATCH 1/2] Decompose the factory to reduce its contract size. --- script/DeploySafeRecovery.s.sol | 4 +- .../DeployUniversalEmailRecoveryModule.s.sol | 6 +-- src/EmailRecoveryFactory.sol | 32 ------------ src/EmailRecoveryUniversalFactory.sol | 52 +++++++++++++++++++ .../UniversalEmailRecoveryModuleBase.t.sol | 6 ++- .../deployEmailRecoveryModule.t.sol | 3 +- .../deployUniversalEmailRecoveryModule.t.sol | 18 +++++-- test/unit/UnitBase.t.sol | 6 ++- 8 files changed, 82 insertions(+), 45 deletions(-) create mode 100644 src/EmailRecoveryUniversalFactory.sol diff --git a/script/DeploySafeRecovery.s.sol b/script/DeploySafeRecovery.s.sol index 8b8696ee..3e220fd2 100644 --- a/script/DeploySafeRecovery.s.sol +++ b/script/DeploySafeRecovery.s.sol @@ -5,6 +5,7 @@ import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; import { SafeRecoverySubjectHandler } from "src/handlers/SafeRecoverySubjectHandler.sol"; import { EmailRecoveryFactory } from "src/EmailRecoveryFactory.sol"; +import { EmailRecoveryUniversalFactory } from "src/EmailRecoveryUniversalFactory.sol"; import { Verifier } from "ether-email-auth/packages/contracts/src/utils/Verifier.sol"; import { ECDSAOwnedDKIMRegistry } from "ether-email-auth/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol"; @@ -44,7 +45,8 @@ contract DeploySafeRecovery_Script is Script { console.log("Deployed Email Auth at", emailAuthImpl); } - EmailRecoveryFactory factory = new EmailRecoveryFactory(verifier, emailAuthImpl); + EmailRecoveryUniversalFactory factory = + new EmailRecoveryUniversalFactory(verifier, emailAuthImpl); (address module, address manager, address subjectHandler) = factory .deployUniversalEmailRecoveryModule( bytes32(uint256(0)), diff --git a/script/DeployUniversalEmailRecoveryModule.s.sol b/script/DeployUniversalEmailRecoveryModule.s.sol index 2d4853e5..8198d5d9 100644 --- a/script/DeployUniversalEmailRecoveryModule.s.sol +++ b/script/DeployUniversalEmailRecoveryModule.s.sol @@ -8,7 +8,7 @@ import { Verifier } from "ether-email-auth/packages/contracts/src/utils/Verifier import { ECDSAOwnedDKIMRegistry } from "ether-email-auth/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol"; import { EmailAuth } from "ether-email-auth/packages/contracts/src/EmailAuth.sol"; -import { EmailRecoveryFactory } from "src/EmailRecoveryFactory.sol"; +import { EmailRecoveryUniversalFactory } from "src/EmailRecoveryUniversalFactory.sol"; contract DeployUniversalEmailRecoveryModuleScript is Script { function run() public { @@ -38,11 +38,11 @@ contract DeployUniversalEmailRecoveryModuleScript is Script { address _factory = vm.envOr("RECOVERY_FACTORY", address(0)); if (_factory == address(0)) { - _factory = address(new EmailRecoveryFactory(verifier, emailAuthImpl)); + _factory = address(new EmailRecoveryUniversalFactory(verifier, emailAuthImpl)); console.log("Deployed Email Recovery Factory at", _factory); } { - EmailRecoveryFactory factory = EmailRecoveryFactory(_factory); + EmailRecoveryUniversalFactory factory = EmailRecoveryUniversalFactory(_factory); (address module, address manager, address subjectHandler) = factory .deployUniversalEmailRecoveryModule( bytes32(uint256(0)), diff --git a/src/EmailRecoveryFactory.sol b/src/EmailRecoveryFactory.sol index 6fd181f0..3d90e457 100644 --- a/src/EmailRecoveryFactory.sol +++ b/src/EmailRecoveryFactory.sol @@ -54,36 +54,4 @@ contract EmailRecoveryFactory { return (emailRecoveryModule, emailRecoveryManager, subjectHandler); } - - function deployUniversalEmailRecoveryModule( - bytes32 subjectHandlerSalt, - bytes32 recoveryManagerSalt, - bytes32 recoveryModuleSalt, - bytes memory subjectHandlerBytecode, - address dkimRegistry - ) - external - returns (address, address, address) - { - // Deploy subject handler - address subjectHandler = Create2.deploy(0, subjectHandlerSalt, subjectHandlerBytecode); - - // Deploy recovery manager - address emailRecoveryManager = address( - new EmailRecoveryManager{ salt: recoveryManagerSalt }( - verifier, dkimRegistry, emailAuthImpl, subjectHandler - ) - ); - - // Deploy recovery module - address emailRecoveryModule = address( - new UniversalEmailRecoveryModule{ salt: recoveryModuleSalt }(emailRecoveryManager) - ); - - // Initialize recovery manager with module address - EmailRecoveryManager(emailRecoveryManager).initialize(emailRecoveryModule); - emit EmailRecoveryModuleDeployed(emailRecoveryModule, emailRecoveryManager, subjectHandler); - - return (emailRecoveryModule, emailRecoveryManager, subjectHandler); - } } diff --git a/src/EmailRecoveryUniversalFactory.sol b/src/EmailRecoveryUniversalFactory.sol new file mode 100644 index 00000000..210c8940 --- /dev/null +++ b/src/EmailRecoveryUniversalFactory.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; +import { EmailRecoveryManager } from "./EmailRecoveryManager.sol"; +import { UniversalEmailRecoveryModule } from "./modules/UniversalEmailRecoveryModule.sol"; + +contract EmailRecoveryUniversalFactory { + address public immutable verifier; + address public immutable emailAuthImpl; + + event EmailRecoveryModuleDeployed( + address emailRecoveryModule, address emailRecoveryManager, address subjectHandler + ); + + constructor(address _verifier, address _emailAuthImpl) { + verifier = _verifier; + emailAuthImpl = _emailAuthImpl; + } + + function deployUniversalEmailRecoveryModule( + bytes32 subjectHandlerSalt, + bytes32 recoveryManagerSalt, + bytes32 recoveryModuleSalt, + bytes memory subjectHandlerBytecode, + address dkimRegistry + ) + external + returns (address, address, address) + { + // Deploy subject handler + address subjectHandler = Create2.deploy(0, subjectHandlerSalt, subjectHandlerBytecode); + + // Deploy recovery manager + address emailRecoveryManager = address( + new EmailRecoveryManager{ salt: recoveryManagerSalt }( + verifier, dkimRegistry, emailAuthImpl, subjectHandler + ) + ); + + // Deploy recovery module + address emailRecoveryModule = address( + new UniversalEmailRecoveryModule{ salt: recoveryModuleSalt }(emailRecoveryManager) + ); + + // Initialize recovery manager with module address + EmailRecoveryManager(emailRecoveryManager).initialize(emailRecoveryModule); + emit EmailRecoveryModuleDeployed(emailRecoveryModule, emailRecoveryManager, subjectHandler); + + return (emailRecoveryModule, emailRecoveryManager, subjectHandler); + } +} diff --git a/test/integration/OwnableValidatorRecovery/UniversalEmailRecoveryModule/UniversalEmailRecoveryModuleBase.t.sol b/test/integration/OwnableValidatorRecovery/UniversalEmailRecoveryModule/UniversalEmailRecoveryModuleBase.t.sol index f754d023..272c9e04 100644 --- a/test/integration/OwnableValidatorRecovery/UniversalEmailRecoveryModule/UniversalEmailRecoveryModuleBase.t.sol +++ b/test/integration/OwnableValidatorRecovery/UniversalEmailRecoveryModule/UniversalEmailRecoveryModuleBase.t.sol @@ -13,6 +13,7 @@ import { import { SubjectUtils } from "ether-email-auth/packages/contracts/src/libraries/SubjectUtils.sol"; import { EmailRecoverySubjectHandler } from "src/handlers/EmailRecoverySubjectHandler.sol"; import { EmailRecoveryFactory } from "src/EmailRecoveryFactory.sol"; +import { EmailRecoveryUniversalFactory } from "src/EmailRecoveryUniversalFactory.sol"; import { EmailRecoveryManager } from "src/EmailRecoveryManager.sol"; import { OwnableValidator } from "src/test/OwnableValidator.sol"; import { IntegrationBase } from "../../IntegrationBase.t.sol"; @@ -23,7 +24,7 @@ abstract contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Base is using Strings for uint256; using Strings for address; - EmailRecoveryFactory emailRecoveryFactory; + EmailRecoveryUniversalFactory emailRecoveryFactory; EmailRecoverySubjectHandler emailRecoveryHandler; EmailRecoveryManager emailRecoveryManager; @@ -46,7 +47,8 @@ abstract contract OwnableValidatorRecovery_UniversalEmailRecoveryModule_Base is function setUp() public virtual override { super.setUp(); - emailRecoveryFactory = new EmailRecoveryFactory(address(verifier), address(emailAuthImpl)); + emailRecoveryFactory = + new EmailRecoveryUniversalFactory(address(verifier), address(emailAuthImpl)); emailRecoveryHandler = new EmailRecoverySubjectHandler(); // Deploy EmailRecoveryManager & UniversalEmailRecoveryModule diff --git a/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol b/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol index 4a28f2a8..aaaaa4fd 100644 --- a/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol +++ b/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol @@ -5,6 +5,7 @@ import { console2 } from "forge-std/console2.sol"; import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; import { UnitBase } from "../UnitBase.t.sol"; import { EmailRecoveryFactory } from "src/EmailRecoveryFactory.sol"; +import { EmailRecoveryUniversalFactory } from "src/EmailRecoveryUniversalFactory.sol"; import { EmailRecoverySubjectHandler } from "src/handlers/EmailRecoverySubjectHandler.sol"; import { EmailRecoveryManager } from "src/EmailRecoveryManager.sol"; import { EmailRecoveryModule } from "src/modules/EmailRecoveryModule.sol"; @@ -12,7 +13,7 @@ import { EmailRecoveryModule } from "src/modules/EmailRecoveryModule.sol"; contract EmailRecoveryFactory_deployAll_Test is UnitBase { function setUp() public override { super.setUp(); - emailRecoveryFactory = new EmailRecoveryFactory(address(verifier), address(emailAuthImpl)); + // emailRecoveryFactory = new EmailRecoveryFactory(address(verifier), } function test_DeployEmailRecoveryModule_Succeeds() public { diff --git a/test/unit/EmailRecoveryFactory/deployUniversalEmailRecoveryModule.t.sol b/test/unit/EmailRecoveryFactory/deployUniversalEmailRecoveryModule.t.sol index 01444523..01899448 100644 --- a/test/unit/EmailRecoveryFactory/deployUniversalEmailRecoveryModule.t.sol +++ b/test/unit/EmailRecoveryFactory/deployUniversalEmailRecoveryModule.t.sol @@ -5,6 +5,7 @@ import { console2 } from "forge-std/console2.sol"; import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; import { UnitBase } from "../UnitBase.t.sol"; import { EmailRecoveryFactory } from "src/EmailRecoveryFactory.sol"; +import { EmailRecoveryUniversalFactory } from "src/EmailRecoveryUniversalFactory.sol"; import { EmailRecoverySubjectHandler } from "src/handlers/EmailRecoverySubjectHandler.sol"; import { EmailRecoveryManager } from "src/EmailRecoveryManager.sol"; import { UniversalEmailRecoveryModule } from "src/modules/UniversalEmailRecoveryModule.sol"; @@ -12,7 +13,8 @@ import { UniversalEmailRecoveryModule } from "src/modules/UniversalEmailRecovery contract EmailRecoveryFactory_deployUniversalEmailRecoveryModule_Test is UnitBase { function setUp() public override { super.setUp(); - emailRecoveryFactory = new EmailRecoveryFactory(address(verifier), address(emailAuthImpl)); + emailRecoveryUniversalFactory = + new EmailRecoveryUniversalFactory(address(verifier), address(emailAuthImpl)); } function test_DeployUniversalEmailRecoveryModule_Succeeds() public { @@ -22,7 +24,9 @@ contract EmailRecoveryFactory_deployUniversalEmailRecoveryModule_Test is UnitBas bytes memory subjectHandlerBytecode = type(EmailRecoverySubjectHandler).creationCode; address expectedSubjectHandler = Create2.computeAddress( - subjectHandlerSalt, keccak256(subjectHandlerBytecode), address(emailRecoveryFactory) + subjectHandlerSalt, + keccak256(subjectHandlerBytecode), + address(emailRecoveryUniversalFactory) ); bytes memory recoveryManagerBytecode = abi.encodePacked( @@ -35,18 +39,22 @@ contract EmailRecoveryFactory_deployUniversalEmailRecoveryModule_Test is UnitBas ) ); address expectedManager = Create2.computeAddress( - recoveryManagerSalt, keccak256(recoveryManagerBytecode), address(emailRecoveryFactory) + recoveryManagerSalt, + keccak256(recoveryManagerBytecode), + address(emailRecoveryUniversalFactory) ); bytes memory recoveryModuleBytecode = abi.encodePacked( type(UniversalEmailRecoveryModule).creationCode, abi.encode(expectedManager) ); address expectedModule = Create2.computeAddress( - recoveryModuleSalt, keccak256(recoveryModuleBytecode), address(emailRecoveryFactory) + recoveryModuleSalt, + keccak256(recoveryModuleBytecode), + address(emailRecoveryUniversalFactory) ); (address emailRecoveryModule, address emailRecoveryManager, address subjectHandler) = - emailRecoveryFactory.deployUniversalEmailRecoveryModule( + emailRecoveryUniversalFactory.deployUniversalEmailRecoveryModule( subjectHandlerSalt, recoveryManagerSalt, recoveryModuleSalt, diff --git a/test/unit/UnitBase.t.sol b/test/unit/UnitBase.t.sol index a552339a..cef63f24 100644 --- a/test/unit/UnitBase.t.sol +++ b/test/unit/UnitBase.t.sol @@ -26,6 +26,7 @@ import { EmailRecoverySubjectHandler } from "src/handlers/EmailRecoverySubjectHa import { UniversalEmailRecoveryModuleHarness } from "./UniversalEmailRecoveryModuleHarness.sol"; import { EmailRecoveryManager } from "src/EmailRecoveryManager.sol"; import { EmailRecoveryFactory } from "src/EmailRecoveryFactory.sol"; +import { EmailRecoveryUniversalFactory } from "src/EmailRecoveryUniversalFactory.sol"; import { OwnableValidator } from "src/test/OwnableValidator.sol"; import { MockGroth16Verifier } from "src/test/MockGroth16Verifier.sol"; @@ -41,6 +42,7 @@ abstract contract UnitBase is RhinestoneModuleKit, Test { EmailAuth emailAuthImpl; EmailRecoveryFactory emailRecoveryFactory; + EmailRecoveryUniversalFactory emailRecoveryUniversalFactory; EmailRecoverySubjectHandler emailRecoveryHandler; EmailRecoveryManagerHarness emailRecoveryManager; UniversalEmailRecoveryModuleHarness emailRecoveryModule; @@ -110,6 +112,8 @@ abstract contract UnitBase is RhinestoneModuleKit, Test { // Deploy handler, manager and module emailRecoveryHandler = new EmailRecoverySubjectHandler(); emailRecoveryFactory = new EmailRecoveryFactory(address(verifier), address(emailAuthImpl)); + emailRecoveryUniversalFactory = + new EmailRecoveryUniversalFactory(address(verifier), address(emailAuthImpl)); emailRecoveryManager = new EmailRecoveryManagerHarness( address(verifier), @@ -179,7 +183,7 @@ abstract contract UnitBase is RhinestoneModuleKit, Test { threshold, delay, expiry - ) + ) }); } From ba910d0bf5edcf6f8fd36b65463bd3b21fe92521 Mon Sep 17 00:00:00 2001 From: JohnGuilding Date: Thu, 4 Jul 2024 10:34:41 +0200 Subject: [PATCH 2/2] Minor restructure of test files --- test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol | 1 - .../deployUniversalEmailRecoveryModule.t.sol | 2 -- test/unit/UnitBase.t.sol | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) rename test/unit/{EmailRecoveryFactory => EmailRecoveryUniversalFactory}/deployUniversalEmailRecoveryModule.t.sol (95%) diff --git a/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol b/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol index aaaaa4fd..080f17e3 100644 --- a/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol +++ b/test/unit/EmailRecoveryFactory/deployEmailRecoveryModule.t.sol @@ -13,7 +13,6 @@ import { EmailRecoveryModule } from "src/modules/EmailRecoveryModule.sol"; contract EmailRecoveryFactory_deployAll_Test is UnitBase { function setUp() public override { super.setUp(); - // emailRecoveryFactory = new EmailRecoveryFactory(address(verifier), } function test_DeployEmailRecoveryModule_Succeeds() public { diff --git a/test/unit/EmailRecoveryFactory/deployUniversalEmailRecoveryModule.t.sol b/test/unit/EmailRecoveryUniversalFactory/deployUniversalEmailRecoveryModule.t.sol similarity index 95% rename from test/unit/EmailRecoveryFactory/deployUniversalEmailRecoveryModule.t.sol rename to test/unit/EmailRecoveryUniversalFactory/deployUniversalEmailRecoveryModule.t.sol index 01899448..79591fc0 100644 --- a/test/unit/EmailRecoveryFactory/deployUniversalEmailRecoveryModule.t.sol +++ b/test/unit/EmailRecoveryUniversalFactory/deployUniversalEmailRecoveryModule.t.sol @@ -13,8 +13,6 @@ import { UniversalEmailRecoveryModule } from "src/modules/UniversalEmailRecovery contract EmailRecoveryFactory_deployUniversalEmailRecoveryModule_Test is UnitBase { function setUp() public override { super.setUp(); - emailRecoveryUniversalFactory = - new EmailRecoveryUniversalFactory(address(verifier), address(emailAuthImpl)); } function test_DeployUniversalEmailRecoveryModule_Succeeds() public { diff --git a/test/unit/UnitBase.t.sol b/test/unit/UnitBase.t.sol index cef63f24..76fa540d 100644 --- a/test/unit/UnitBase.t.sol +++ b/test/unit/UnitBase.t.sol @@ -183,7 +183,7 @@ abstract contract UnitBase is RhinestoneModuleKit, Test { threshold, delay, expiry - ) + ) }); }