From fa6a208f2f4c9e3168bf211b5380326573615c59 Mon Sep 17 00:00:00 2001 From: JohnGuilding Date: Tue, 2 Jul 2024 20:40:07 +0200 Subject: [PATCH] Update safe unit base --- test/unit/SafeUnitBase.t.sol | 184 ++---------------- .../acceptanceSubjectTemplates.t.sol | 3 +- ...ecoveredAccountFromAcceptanceSubject.t.sol | 3 +- ...tRecoveredAccountFromRecoverySubject.t.sol | 3 +- .../getPreviousOwnerInLinkedList.t.sol | 11 +- .../recoverySubjectTemplates.t.sol | 3 +- .../validateAcceptanceSubject.t.sol | 5 +- .../validateRecoverySubject.t.sol | 9 +- 8 files changed, 49 insertions(+), 172 deletions(-) diff --git a/test/unit/SafeUnitBase.t.sol b/test/unit/SafeUnitBase.t.sol index a5c93254..5bd66025 100644 --- a/test/unit/SafeUnitBase.t.sol +++ b/test/unit/SafeUnitBase.t.sol @@ -2,27 +2,8 @@ pragma solidity ^0.8.25; import { console2 } from "forge-std/console2.sol"; - -import { Safe } from "@safe-global/safe-contracts/contracts/Safe.sol"; -import { - SafeProxy, - SafeProxyFactory -} from "@safe-global/safe-contracts/contracts/proxies/SafeProxyFactory.sol"; -import { Safe7579Launchpad } from "safe7579/Safe7579Launchpad.sol"; -import { IERC7484 } from "safe7579/interfaces/IERC7484.sol"; -import { Safe7579 } from "safe7579/Safe7579.sol"; -import { ModuleInit } from "safe7579/DataTypes.sol"; -import { IERC7579Account } from "erc7579/interfaces/IERC7579Account.sol"; -import { ExecutionLib } from "erc7579/lib/ExecutionLib.sol"; -import { ModeLib } from "erc7579/lib/ModeLib.sol"; -import { ISafe7579 } from "safe7579/ISafe7579.sol"; -import { PackedUserOperation } from "modulekit/external/ERC4337.sol"; -import { etchEntrypoint, IEntryPoint } from "modulekit/test/predeploy/EntryPoint.sol"; -import { MockExecutor, MockTarget } from "modulekit/Mocks.sol"; -import { MockValidator } from "module-bases/mocks/MockValidator.sol"; import { EmailAuthMsg, EmailProof } from "ether-email-auth/packages/contracts/src/EmailAuth.sol"; import { SubjectUtils } from "ether-email-auth/packages/contracts/src/libraries/SubjectUtils.sol"; -import { Solarray } from "solarray/Solarray.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { EmailRecoveryManagerHarness } from "./EmailRecoveryManagerHarness.sol"; @@ -30,7 +11,6 @@ import { EmailRecoveryManager } from "src/EmailRecoveryManager.sol"; import { UniversalEmailRecoveryModule } from "src/modules/UniversalEmailRecoveryModule.sol"; import { SafeRecoverySubjectHandlerHarness } from "./SafeRecoverySubjectHandlerHarness.sol"; import { EmailRecoveryFactory } from "src/EmailRecoveryFactory.sol"; -import { MockRegistry } from "src/test/MockRegistry.sol"; import { IntegrationBase } from "../integration/IntegrationBase.t.sol"; abstract contract SafeUnitBase is IntegrationBase { @@ -46,20 +26,30 @@ abstract contract SafeUnitBase is IntegrationBase { bytes recoveryCalldata; bytes32 calldataHash; - Safe7579 safe7579; - Safe singleton; - Safe safe; - SafeProxyFactory safeProxyFactory; - Safe7579Launchpad launchpad; - - MockValidator defaultValidator; - MockExecutor defaultExecutor; - MockTarget target; + /** + * Helper function to return if current account type is safe or not + */ + function isAccountTypeSafe() public returns (bool) { + string memory currentAccountType = vm.envOr("ACCOUNT_TYPE", string("")); + if (Strings.equal(currentAccountType, "SAFE")) { + return true; + } else { + return false; + } + } - IEntryPoint entrypoint; - IERC7484 registry; + function skipIfNotSafeAccountType() public { + if (isAccountTypeSafe()) { + vm.skip(false); + } else { + vm.skip(true); + } + } function setUp() public virtual override { + if (!isAccountTypeSafe()) { + return; + } super.setUp(); // Deploy handler, manager and module @@ -81,9 +71,6 @@ abstract contract SafeUnitBase is IntegrationBase { recoveryModuleAddress = address(emailRecoveryModule); emailRecoveryManager.initialize(recoveryModuleAddress); - safe = deploySafe(); - accountAddress1 = address(safe); - functionSelector = bytes4(keccak256(bytes("swapOwner(address,address,address)"))); address previousOwnerInLinkedList = address(1); // address previousOwnerInLinkedList = @@ -103,135 +90,6 @@ abstract contract SafeUnitBase is IntegrationBase { emailRecoveryManager.computeEmailAuthAddress(instance1.account, accountSalt3); } - /** - * Taken from safe7579/test/Launchpad.t.sol - */ - function deploySafe() internal returns (Safe) { - entrypoint = etchEntrypoint(); - singleton = new Safe(); - safeProxyFactory = new SafeProxyFactory(); - registry = new MockRegistry(); - safe7579 = new Safe7579(); - launchpad = new Safe7579Launchpad(address(entrypoint), registry); - - // Set up Modules - defaultValidator = new MockValidator(); - defaultExecutor = new MockExecutor(); - target = new MockTarget(); - - bytes32 salt; - - ModuleInit[] memory validators = new ModuleInit[](1); - validators[0] = ModuleInit({ module: address(defaultValidator), initData: bytes("") }); - ModuleInit[] memory executors = new ModuleInit[](1); - executors[0] = ModuleInit({ module: address(defaultExecutor), initData: bytes("") }); - ModuleInit[] memory fallbacks = new ModuleInit[](0); - ModuleInit[] memory hooks = new ModuleInit[](0); - - Safe7579Launchpad.InitData memory initData = Safe7579Launchpad.InitData({ - singleton: address(singleton), - owners: Solarray.addresses(owner1), - threshold: 1, - setupTo: address(launchpad), - setupData: abi.encodeCall( - Safe7579Launchpad.initSafe7579, - ( - address(safe7579), - executors, - fallbacks, - hooks, - Solarray.addresses(makeAddr("attester1"), makeAddr("attester2")), - 2 - ) - ), - safe7579: ISafe7579(safe7579), - validators: validators, - callData: abi.encodeCall( - IERC7579Account.execute, - ( - ModeLib.encodeSimpleSingle(), - ExecutionLib.encodeSingle({ - target: address(target), - value: 0, - callData: abi.encodeCall(MockTarget.set, (1337)) - }) - ) - ) - }); - bytes32 initHash = launchpad.hash(initData); - - bytes memory factoryInitializer = - abi.encodeCall(Safe7579Launchpad.preValidationSetup, (initHash, address(0), "")); - - PackedUserOperation memory userOp = - getDefaultUserOp(address(safe), address(defaultValidator)); - - { - userOp.callData = abi.encodeCall(Safe7579Launchpad.setupSafe, (initData)); - userOp.initCode = _initCode(factoryInitializer, salt); - } - - address predict = launchpad.predictSafeAddress({ - singleton: address(launchpad), - safeProxyFactory: address(safeProxyFactory), - creationCode: type(SafeProxy).creationCode, - salt: salt, - factoryInitializer: factoryInitializer - }); - userOp.sender = predict; - assertEq(userOp.sender, predict); - userOp.signature = abi.encodePacked( - uint48(0), uint48(type(uint48).max), hex"4141414141414141414141414141414141" - ); - - entrypoint.getUserOpHash(userOp); - PackedUserOperation[] memory userOps = new PackedUserOperation[](1); - userOps[0] = userOp; - deal(address(userOp.sender), 1 ether); - - entrypoint.handleOps(userOps, payable(address(0x69))); - - return Safe(payable(predict)); - } - - function _initCode( - bytes memory initializer, - bytes32 salt - ) - internal - view - returns (bytes memory initCode) - { - initCode = abi.encodePacked( - address(safeProxyFactory), - abi.encodeCall( - SafeProxyFactory.createProxyWithNonce, - (address(launchpad), initializer, uint256(salt)) - ) - ); - } - - function getDefaultUserOp( - address account, - address validator - ) - internal - view - returns (PackedUserOperation memory userOp) - { - userOp = PackedUserOperation({ - sender: account, - nonce: safe7579.getNonce(account, validator), - initCode: "", - callData: "", - accountGasLimits: bytes32(abi.encodePacked(uint128(2e6), uint128(2e6))), - preVerificationGas: 2e6, - gasFees: bytes32(abi.encodePacked(uint128(2e6), uint128(2e6))), - paymasterAndData: bytes(""), - signature: abi.encodePacked(hex"41414141") - }); - } - function generateMockEmailProof( string memory subject, bytes32 nullifier, diff --git a/test/unit/handlers/SafeRecoverySubjectHandler/acceptanceSubjectTemplates.t.sol b/test/unit/handlers/SafeRecoverySubjectHandler/acceptanceSubjectTemplates.t.sol index 3d1b545b..6b3bc442 100644 --- a/test/unit/handlers/SafeRecoverySubjectHandler/acceptanceSubjectTemplates.t.sol +++ b/test/unit/handlers/SafeRecoverySubjectHandler/acceptanceSubjectTemplates.t.sol @@ -10,7 +10,8 @@ contract SafeRecoverySubjectHandler_acceptanceSubjectTemplates_Test is SafeUnitB super.setUp(); } - function test_AcceptanceSubjectTemplates_Succeeds() public view { + function test_AcceptanceSubjectTemplates_Succeeds() public { + skipIfNotSafeAccountType(); string[][] memory templates = safeRecoverySubjectHandler.acceptanceSubjectTemplates(); assertEq(templates.length, 1); diff --git a/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromAcceptanceSubject.t.sol b/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromAcceptanceSubject.t.sol index 190298dc..4addbced 100644 --- a/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromAcceptanceSubject.t.sol +++ b/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromAcceptanceSubject.t.sol @@ -12,7 +12,8 @@ contract SafeRecoverySubjectHandler_extractRecoveredAccountFromAcceptanceSubject super.setUp(); } - function test_ExtractRecoveredAccountFromAcceptanceSubject_Succeeds() public view { + function test_ExtractRecoveredAccountFromAcceptanceSubject_Succeeds() public { + skipIfNotSafeAccountType(); bytes[] memory subjectParams = new bytes[](1); subjectParams[0] = abi.encode(accountAddress1); diff --git a/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromRecoverySubject.t.sol b/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromRecoverySubject.t.sol index 94132fa9..af6a0a28 100644 --- a/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromRecoverySubject.t.sol +++ b/test/unit/handlers/SafeRecoverySubjectHandler/extractRecoveredAccountFromRecoverySubject.t.sol @@ -11,7 +11,8 @@ contract SafeRecoverySubjectHandler_extractRecoveredAccountFromRecoverySubject_T super.setUp(); } - function test_ExtractRecoveredAccountFromRecoverySubject_Succeeds() public view { + function test_ExtractRecoveredAccountFromRecoverySubject_Succeeds() public { + skipIfNotSafeAccountType(); bytes[] memory subjectParams = new bytes[](3); subjectParams[0] = abi.encode(accountAddress1); subjectParams[1] = abi.encode(newOwner1); diff --git a/test/unit/handlers/SafeRecoverySubjectHandler/getPreviousOwnerInLinkedList.t.sol b/test/unit/handlers/SafeRecoverySubjectHandler/getPreviousOwnerInLinkedList.t.sol index 6c465168..ad57d96b 100644 --- a/test/unit/handlers/SafeRecoverySubjectHandler/getPreviousOwnerInLinkedList.t.sol +++ b/test/unit/handlers/SafeRecoverySubjectHandler/getPreviousOwnerInLinkedList.t.sol @@ -11,7 +11,8 @@ contract SafeRecoverySubjectHandler_getPreviousOwnerInLinkedList_Test is SafeUni super.setUp(); } - function test_GetPreviousOwnerInLinkedList_InvalidOwner_ReturnsSentinel() public view { + function test_GetPreviousOwnerInLinkedList_InvalidOwner_ReturnsSentinel() public { + skipIfNotSafeAccountType(); address invalidOwner = address(0); address previousOwner = safeRecoverySubjectHandler.exposed_getPreviousOwnerInLinkedList( @@ -21,7 +22,8 @@ contract SafeRecoverySubjectHandler_getPreviousOwnerInLinkedList_Test is SafeUni assertEq(previousOwner, SENTINEL_OWNERS); } - function test_GetPreviousOwnerInLinkedList_OwnerIsSentinel_ReturnsSentinel() public view { + function test_GetPreviousOwnerInLinkedList_OwnerIsSentinel_ReturnsSentinel() public { + skipIfNotSafeAccountType(); address invalidOwner = SENTINEL_OWNERS; address previousOwner = safeRecoverySubjectHandler.exposed_getPreviousOwnerInLinkedList( @@ -32,13 +34,15 @@ contract SafeRecoverySubjectHandler_getPreviousOwnerInLinkedList_Test is SafeUni } function test_GetPreviousOwnerInLinkedList_RevertWhen_InvalidAccount() public { + skipIfNotSafeAccountType(); address invalidAccount = address(0); vm.expectRevert(); safeRecoverySubjectHandler.exposed_getPreviousOwnerInLinkedList(invalidAccount, owner1); } - function test_GetPreviousOwnerInLinkedList_Succeeds() public view { + function test_GetPreviousOwnerInLinkedList_Succeeds() public { + skipIfNotSafeAccountType(); address expectedPreviousOwner = address(1); address previousOwner = safeRecoverySubjectHandler.exposed_getPreviousOwnerInLinkedList(accountAddress1, owner1); @@ -47,6 +51,7 @@ contract SafeRecoverySubjectHandler_getPreviousOwnerInLinkedList_Test is SafeUni } function test_GetPreviousOwnerInLinkedList_SucceedsWithMultipleAccounts() public { + skipIfNotSafeAccountType(); address expectedPreviousOwner = address(1); address previousOwner = safeRecoverySubjectHandler.exposed_getPreviousOwnerInLinkedList(accountAddress1, owner1); diff --git a/test/unit/handlers/SafeRecoverySubjectHandler/recoverySubjectTemplates.t.sol b/test/unit/handlers/SafeRecoverySubjectHandler/recoverySubjectTemplates.t.sol index 4d5fae48..a2abb78a 100644 --- a/test/unit/handlers/SafeRecoverySubjectHandler/recoverySubjectTemplates.t.sol +++ b/test/unit/handlers/SafeRecoverySubjectHandler/recoverySubjectTemplates.t.sol @@ -9,7 +9,8 @@ contract SafeRecoverySubjectHandler_recoverySubjectTemplates_Test is SafeUnitBas super.setUp(); } - function test_RecoverySubjectTemplates_Succeeds() public view { + function test_RecoverySubjectTemplates_Succeeds() public { + skipIfNotSafeAccountType(); string[][] memory templates = safeRecoverySubjectHandler.recoverySubjectTemplates(); assertEq(templates.length, 1); diff --git a/test/unit/handlers/SafeRecoverySubjectHandler/validateAcceptanceSubject.t.sol b/test/unit/handlers/SafeRecoverySubjectHandler/validateAcceptanceSubject.t.sol index 3ca87f35..b277c6cf 100644 --- a/test/unit/handlers/SafeRecoverySubjectHandler/validateAcceptanceSubject.t.sol +++ b/test/unit/handlers/SafeRecoverySubjectHandler/validateAcceptanceSubject.t.sol @@ -11,6 +11,7 @@ contract SafeRecoverySubjectHandler_validateAcceptanceSubject_Test is SafeUnitBa } function test_ValidateAcceptanceSubject_RevertWhen_NoSubjectParams() public { + skipIfNotSafeAccountType(); bytes[] memory emptySubjectParams; vm.expectRevert(SafeRecoverySubjectHandler.InvalidSubjectParams.selector); @@ -18,6 +19,7 @@ contract SafeRecoverySubjectHandler_validateAcceptanceSubject_Test is SafeUnitBa } function test_ValidateAcceptanceSubject_RevertWhen_TooManySubjectParams() public { + skipIfNotSafeAccountType(); bytes[] memory subjectParams = new bytes[](2); subjectParams[0] = abi.encode(accountAddress1); subjectParams[1] = abi.encode("extra param"); @@ -26,7 +28,8 @@ contract SafeRecoverySubjectHandler_validateAcceptanceSubject_Test is SafeUnitBa safeRecoverySubjectHandler.validateAcceptanceSubject(templateIdx, subjectParams); } - function test_ValidateAcceptanceSubject_Succeeds() public view { + function test_ValidateAcceptanceSubject_Succeeds() public { + skipIfNotSafeAccountType(); bytes[] memory subjectParams = new bytes[](1); subjectParams[0] = abi.encode(accountAddress1); diff --git a/test/unit/handlers/SafeRecoverySubjectHandler/validateRecoverySubject.t.sol b/test/unit/handlers/SafeRecoverySubjectHandler/validateRecoverySubject.t.sol index 1d9810e1..3de74451 100644 --- a/test/unit/handlers/SafeRecoverySubjectHandler/validateRecoverySubject.t.sol +++ b/test/unit/handlers/SafeRecoverySubjectHandler/validateRecoverySubject.t.sol @@ -22,6 +22,7 @@ contract SafeRecoverySubjectHandler_validateRecoverySubject_Test is SafeUnitBase } function test_ValidateAcceptanceSubject_RevertWhen_NoSubjectParams() public { + skipIfNotSafeAccountType(); bytes[] memory emptySubjectParams; vm.expectRevert(SafeRecoverySubjectHandler.InvalidSubjectParams.selector); @@ -31,6 +32,7 @@ contract SafeRecoverySubjectHandler_validateRecoverySubject_Test is SafeUnitBase } function test_ValidateAcceptanceSubject_RevertWhen_TooManySubjectParams() public { + skipIfNotSafeAccountType(); bytes[] memory longSubjectParams = new bytes[](5); longSubjectParams[0] = subjectParams[0]; longSubjectParams[1] = subjectParams[1]; @@ -45,6 +47,7 @@ contract SafeRecoverySubjectHandler_validateRecoverySubject_Test is SafeUnitBase } function test_ValidateRecoverySubject_RevertWhen_InvalidOldOwner() public { + skipIfNotSafeAccountType(); subjectParams[1] = abi.encode(address(0)); vm.expectRevert(SafeRecoverySubjectHandler.InvalidOldOwner.selector); @@ -54,6 +57,7 @@ contract SafeRecoverySubjectHandler_validateRecoverySubject_Test is SafeUnitBase } function test_ValidateRecoverySubject_RevertWhen_InvalidNewOwner() public { + skipIfNotSafeAccountType(); subjectParams[2] = abi.encode(address(0)); vm.expectRevert(SafeRecoverySubjectHandler.InvalidNewOwner.selector); @@ -63,6 +67,7 @@ contract SafeRecoverySubjectHandler_validateRecoverySubject_Test is SafeUnitBase } function test_ValidateRecoverySubject_RevertWhen_RecoveryModuleAddressIsZero() public { + skipIfNotSafeAccountType(); subjectParams[3] = abi.encode(address(0)); vm.expectRevert(SafeRecoverySubjectHandler.InvalidRecoveryModule.selector); @@ -74,6 +79,7 @@ contract SafeRecoverySubjectHandler_validateRecoverySubject_Test is SafeUnitBase function test_ValidateRecoverySubject_RevertWhen_RecoveryModuleNotEqualToExpectedAddress() public { + skipIfNotSafeAccountType(); subjectParams[3] = abi.encode(address(1)); vm.expectRevert(SafeRecoverySubjectHandler.InvalidRecoveryModule.selector); @@ -82,7 +88,8 @@ contract SafeRecoverySubjectHandler_validateRecoverySubject_Test is SafeUnitBase ); } - function test_ValidateRecoverySubject_Succeeds() public view { + function test_ValidateRecoverySubject_Succeeds() public { + skipIfNotSafeAccountType(); (address accountFromEmail, bytes32 calldataHashFromEmail) = safeRecoverySubjectHandler .validateRecoverySubject(templateIdx, subjectParams, emailRecoveryManagerAddress); assertEq(accountFromEmail, accountAddress1);