From d1a0f8f31a6b4e7267bf5e22fc433eab6dae92cc Mon Sep 17 00:00:00 2001 From: Alfredo Lopez Date: Wed, 15 May 2024 15:15:53 +0200 Subject: [PATCH] ADD: update comments of helpers function and unit-test --- .gas-snapshot | 269 +++++++++++----------- script/DeployKeyperEnv.s.sol | 3 +- script/SkipExecutionOnBehalf.s.sol | 14 +- src/KeyperRoles.sol | 4 + test/DeploySafe.t.sol | 1 + test/EnableGuard.t.sol | 3 + test/EnableModule.t.sol | 3 + test/EventsChecker.t.sol | 12 + test/Hierarchies.t.sol | 24 +- test/KeyperRoles.t.sol | 2 +- test/deploy.t.sol | 2 + test/helpers/DeployHelper.t.sol | 2 +- test/helpers/GnosisSafeHelper.t.sol | 215 ++++++++++++----- test/helpers/KeyperModuleHelper.t.sol | 36 ++- test/helpers/ReentrancyAttackHelper.t.sol | 18 ++ test/helpers/SignersHelper.t.sol | 10 + test/helpers/SkipGnosisSafeHelper.t.sol | 12 +- test/helpers/SkipSetupEnv.s.sol | 1 + 18 files changed, 418 insertions(+), 213 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index a244163..82eab16 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -6,7 +6,7 @@ DenyHelperKeyperModuleTest:testGetPrevUserList() (gas: 415799) DenyHelperKeyperModuleTest:testRevertAddToDuplicateAddress() (gas: 411920) DenyHelperKeyperModuleTest:testRevertAddToListInvalidAddress() (gas: 297747) DenyHelperKeyperModuleTest:testRevertAddToListZeroAddress() (gas: 108133) -DenyHelperKeyperModuleTest:testRevertIfCallAnotherSafeNotRegistered() (gas: 6750561) +DenyHelperKeyperModuleTest:testRevertIfCallAnotherSafeNotRegistered() (gas: 6748556) DenyHelperKeyperModuleTest:testRevertIfDenyHelpersDisabled() (gas: 235814) DenyHelperKeyperModuleTest:testRevertIfInvalidAddressProvidedForAllowList() (gas: 417459) DenyHelperKeyperModuleTest:testRevertIfInvalidAddressProvidedForDenyList() (gas: 404791) @@ -14,146 +14,145 @@ DenyHelperKeyperModuleTest:testRevertIfListEmptyForAllowList() (gas: 226607) DenyHelperKeyperModuleTest:testRevertIfListEmptyForDenyList() (gas: 226401) DenyHelperKeyperModuleTest:testRevertInvalidGnosisRootSafe() (gas: 403990) DenyHelperKeyperModuleTest:testRevertInvalidGnosisSafe() (gas: 187764) -EventsChekers:testEventWhenAddSquad() (gas: 1335323) -EventsChekers:testEventWhenAddToList() (gas: 986983) -EventsChekers:testEventWhenDisconnectSafe() (gas: 1326455) -EventsChekers:testEventWhenDropFromList() (gas: 994365) -EventsChekers:testEventWhenExecutionOnBehalf() (gas: 1889961) -EventsChekers:testEventWhenPromoteRootSafe() (gas: 2031889) -EventsChekers:testEventWhenRegisterRootOrg() (gas: 732761) -EventsChekers:testEventWhenRegisterRootSafe() (gas: 1342851) -EventsChekers:testEventWhenRemoveSquad() (gas: 1390591) -EventsChekers:testEventWhenRemoveWholeTree() (gas: 2519292) -EventsChekers:testEventWhenUpdateNewLimit() (gas: 1373528) -EventsChekers:testEventWhenUpdateSuper() (gas: 2451882) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_ROOT_SAFE_and_Target_Root_SameTree_2_levels() (gas: 2572802) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SameTree() (gas: 1945923) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_SAFE_LEAD_as_EOA_is_TARGETS_LEAD() (gas: 1871223) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD() (gas: 3818078) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_SUPER_SAFE_as_SAFE_is_TARGETS_LEAD_SameTree() (gas: 2583785) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES() (gas: 2512650) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES_signed_one_by_one_Inverse_WAY() (gas: 2694314) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES_signed_one_by_one_Straight_way() (gas: 2694158) -ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES_signed_one_by_one_Straight_way_from_superSafe() (gas: 2696859) -ExecTransactionOnBehalf:testCannot_ExecTransactionOnBehalf_Wrapper_ExecTransactionOnBehalf_ChildSquad_over_RootSafe_With_SAFE() (gas: 3305716) -ExecTransactionOnBehalf:testReentrancyAttack() (gas: 6554082) -ExecTransactionOnBehalf:testRevertInvalidAddressProvidedExecTransactionOnBehalfScenarioOne() (gas: 1750262) -ExecTransactionOnBehalf:testRevertInvalidGnosisSafeExecTransactionOnBehalf() (gas: 1741757) -ExecTransactionOnBehalf:testRevertInvalidSignatureExecOnBehalf() (gas: 1864582) -ExecTransactionOnBehalf:testRevertOrgNotRegisteredExecTransactionOnBehalfScenarioThree() (gas: 1757234) -ExecTransactionOnBehalf:testRevertSuperSafeExecOnBehalf() (gas: 3032242) -ExecTransactionOnBehalf:testRevertZeroAddressProvidedExecTransactionOnBehalfScenarioTwo() (gas: 1739524) -ExecTransactionOnBehalf:testRevert_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_INVALID_SIGNATURES() (gas: 2443176) -ExecTransactionOnBehalf:testRevert_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_WRONG_SIGNATURES() (gas: 2426869) -GnosisSafeHelper:testNewKeyperSafe() (gas: 9403967) -Hierarchies:testAddSquad() (gas: 1700565) -Hierarchies:testAddSubSquad() (gas: 2318305) -Hierarchies:testCreateSquadThreeTiersTree() (gas: 2303268) +EventsChekers:testEventWhenAddSquad() (gas: 1334787) +EventsChekers:testEventWhenAddToList() (gas: 986715) +EventsChekers:testEventWhenDisconnectSafe() (gas: 1325919) +EventsChekers:testEventWhenDropFromList() (gas: 994097) +EventsChekers:testEventWhenExecutionOnBehalf() (gas: 1889267) +EventsChekers:testEventWhenPromoteRootSafe() (gas: 2031085) +EventsChekers:testEventWhenRegisterRootOrg() (gas: 732493) +EventsChekers:testEventWhenRegisterRootSafe() (gas: 1342315) +EventsChekers:testEventWhenRemoveSquad() (gas: 1390055) +EventsChekers:testEventWhenRemoveWholeTree() (gas: 2518428) +EventsChekers:testEventWhenUpdateNewLimit() (gas: 1372992) +EventsChekers:testEventWhenUpdateSuper() (gas: 2450810) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_ROOT_SAFE_and_Target_Root_SameTree_2_levels() (gas: 2571803) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SameTree() (gas: 1945117) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_SAFE_LEAD_as_EOA_is_TARGETS_LEAD() (gas: 1870529) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD() (gas: 3816748) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_SUPER_SAFE_as_SAFE_is_TARGETS_LEAD_SameTree() (gas: 2582786) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES() (gas: 2511763) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES_signed_one_by_one_Inverse_WAY() (gas: 2693427) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES_signed_one_by_one_Straight_way() (gas: 2693271) +ExecTransactionOnBehalf:testCan_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_RIGHTS_SIGNATURES_signed_one_by_one_Straight_way_from_superSafe() (gas: 2695972) +ExecTransactionOnBehalf:testCannot_ExecTransactionOnBehalf_Wrapper_ExecTransactionOnBehalf_ChildSquad_over_RootSafe_With_SAFE() (gas: 3304359) +ExecTransactionOnBehalf:testReentrancyAttack() (gas: 6553801) +ExecTransactionOnBehalf:testRevertInvalidAddressProvidedExecTransactionOnBehalfScenarioOne() (gas: 1749568) +ExecTransactionOnBehalf:testRevertInvalidGnosisSafeExecTransactionOnBehalf() (gas: 1741063) +ExecTransactionOnBehalf:testRevertInvalidSignatureExecOnBehalf() (gas: 1863776) +ExecTransactionOnBehalf:testRevertOrgNotRegisteredExecTransactionOnBehalfScenarioThree() (gas: 1756540) +ExecTransactionOnBehalf:testRevertSuperSafeExecOnBehalf() (gas: 3031162) +ExecTransactionOnBehalf:testRevertZeroAddressProvidedExecTransactionOnBehalfScenarioTwo() (gas: 1738830) +ExecTransactionOnBehalf:testRevert_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_INVALID_SIGNATURES() (gas: 2442289) +ExecTransactionOnBehalf:testRevert_ExecTransactionOnBehalf_as_EOA_is_NOT_ROLE_with_WRONG_SIGNATURES() (gas: 2425982) +Hierarchies:testAddSquad() (gas: 1699849) +Hierarchies:testAddSubSquad() (gas: 2317343) +Hierarchies:testCreateSquadThreeTiersTree() (gas: 2302381) Hierarchies:testExpectInvalidSquadId() (gas: 14380) Hierarchies:testExpectSquadNotRegistered() (gas: 16790) -Hierarchies:testIsSuperSafe() (gas: 2929578) -Hierarchies:testOrgFourTiersTreeSuperSafeRoles() (gas: 2918929) -Hierarchies:testRegisterRootOrg() (gas: 361277) -Hierarchies:testRevertIfTryInvalidLimit() (gas: 1748588) -Hierarchies:testRevertIfTryNotRootSafe() (gas: 4397254) -Hierarchies:testRevertSafeAlreadyRegisteredAddSquad() (gas: 2331238) -Hierarchies:testRevertUpdateSuperIfCallerIsNotSafe() (gas: 1652619) -Hierarchies:testRevertUpdateSuperIfCallerNotPartofTheOrg() (gas: 3100190) -Hierarchies:testRevertUpdateSuperInvalidSquadId() (gas: 1671487) -Hierarchies:testRevertifExceedMaxDepthTreeLimit() (gas: 5813669) -Hierarchies:testRevertifExceedMaxDepthTreeLimitAndUpdateSuper() (gas: 7976810) -Hierarchies:testRevertifUpdateDepthTreeLimitAndUpdateSuperToAnotherOrg() (gas: 12355212) -Hierarchies:testRevertifUpdateLimitAndExceedMaxDepthTreeLimit() (gas: 10761357) -Hierarchies:testRevertifUpdateLimitAndExceedMaxDepthTreeLimitAndUpdateSuper() (gas: 12990498) -Hierarchies:testRevertifUpdateSuperToAnotherOrg() (gas: 7311641) -Hierarchies:testTreeOrgsTreeMember() (gas: 3770336) -Hierarchies:testUpdateSuper() (gas: 3649585) -KeyperGuardTest:testCanPromoteToRoot_As_ROOTSAFE_TARGET_SUPER_SAFE() (gas: 2502068) -KeyperGuardTest:testCanRemoveWholeTree() (gas: 4036947) -KeyperGuardTest:testCanRemoveWholeTreeFourthLevel() (gas: 3101922) -KeyperGuardTest:testCannotDisableKeyperGuardAfterRemoveSquad() (gas: 1888602) -KeyperGuardTest:testCannotDisableKeyperGuardIfGuardEnabled() (gas: 1791992) -KeyperGuardTest:testCannotDisableKeyperModuleAfterRemoveSquad() (gas: 1826541) -KeyperGuardTest:testCannotDisableKeyperModuleIfGuardEnabled() (gas: 1782363) -KeyperGuardTest:testCannotDisconnectSafe_As_ROOTSAFE_TARGET_ITSELF_If_Have_children() (gas: 1741953) -KeyperGuardTest:testCannotDisconnectSafe_As_ROOTSAFE_TARGET_ROOTSAFE_SAME_TREE() (gas: 2328580) -KeyperGuardTest:testCannotDisconnectSafe_As_RootSafe_As_DifferentTree() (gas: 4678504) -KeyperGuardTest:testCannotDisconnectSafe_As_SafeLead_As_EOA() (gas: 2382038) -KeyperGuardTest:testCannotDisconnectSafe_As_SafeLead_As_SAFE() (gas: 2785356) -KeyperGuardTest:testCannotDisconnectSafe_As_SuperSafe_As_DifferentTree() (gas: 4649914) -KeyperGuardTest:testCannotDisconnectSafe_As_SuperSafe_As_SameTree() (gas: 2423464) -KeyperGuardTest:testCannotPromoteToRoot_As_ROOTSAFE_TARGET_SQUAD_SAFE() (gas: 2432107) -KeyperGuardTest:testCannotPromoteToRoot_As_ROOTSAFE_TARGET_SUPER_SAFE_ANOTHER_ORG() (gas: 4644877) -KeyperGuardTest:testCannotPromoteToRoot_As_ROOTSAFE_TARGET_SUPER_SAFE_ANOTHER_TREE() (gas: 4559991) -KeyperGuardTest:testCannotReplayAttackDisconnectedSafe() (gas: 1706651) -KeyperGuardTest:testCannotReplayAttackRemoveSquad() (gas: 1783810) -KeyperGuardTest:testCannotReplayAttackRemoveWholeTree() (gas: 3095171) -KeyperGuardTest:testDisableKeyperGuard() (gas: 133253) -KeyperGuardTest:testDisableKeyperModule() (gas: 104822) -KeyperGuardTest:testDisconnectSafeBeforeToRemoveSquad_One_Level() (gas: 2299401) -KeyperGuardTest:testDisconnectSafeBeforeToRemoveSquad_Two_Level() (gas: 2928037) -KeyperGuardTest:testDisconnectSafe_As_ROOTSAFE_TARGET_ITSELF_If_Not_Have_children() (gas: 1902672) -KeyperGuardTest:testDisconnectSafe_As_ROOTSAFE_TARGET_ROOT_SAFE() (gas: 2391380) -KeyperGuardTest:testDisconnectSafe_As_ROOTSAFE_TARGET_SUPERSAFE_SAME_TREE() (gas: 1703257) +Hierarchies:testIsSuperSafe() (gas: 2928498) +Hierarchies:testOrgFourTiersTreeSuperSafeRoles() (gas: 2917849) +Hierarchies:testRegisterRootOrg() (gas: 361198) +Hierarchies:testRevertIfTryInvalidLimit() (gas: 1747894) +Hierarchies:testRevertIfTryNotRootSafe() (gas: 4395480) +Hierarchies:testRevertSafeAlreadyRegisteredAddSquad() (gas: 2330250) +Hierarchies:testRevertUpdateSuperIfCallerIsNotSafe() (gas: 1651925) +Hierarchies:testRevertUpdateSuperIfCallerNotPartofTheOrg() (gas: 3098802) +Hierarchies:testRevertUpdateSuperInvalidSquadId() (gas: 1670793) +Hierarchies:testRevertifExceedMaxDepthTreeLimit() (gas: 5811744) +Hierarchies:testRevertifExceedMaxDepthTreeLimitAndUpdateSuper() (gas: 7973703) +Hierarchies:testRevertifUpdateDepthTreeLimitAndUpdateSuperToAnotherOrg() (gas: 12351241) +Hierarchies:testRevertifUpdateLimitAndExceedMaxDepthTreeLimit() (gas: 10758080) +Hierarchies:testRevertifUpdateLimitAndExceedMaxDepthTreeLimitAndUpdateSuper() (gas: 12986039) +Hierarchies:testRevertifUpdateSuperToAnotherOrg() (gas: 7309022) +Hierarchies:testTreeOrgsTreeMember() (gas: 3768755) +Hierarchies:testUpdateSuper() (gas: 3648312) +KeyperGuardTest:testCanPromoteToRoot_As_ROOTSAFE_TARGET_SUPER_SAFE() (gas: 2501091) +KeyperGuardTest:testCanRemoveWholeTree() (gas: 4034674) +KeyperGuardTest:testCanRemoveWholeTreeFourthLevel() (gas: 3100832) +KeyperGuardTest:testCannotDisableKeyperGuardAfterRemoveSquad() (gas: 1887616) +KeyperGuardTest:testCannotDisableKeyperGuardIfGuardEnabled() (gas: 1791074) +KeyperGuardTest:testCannotDisableKeyperModuleAfterRemoveSquad() (gas: 1825623) +KeyperGuardTest:testCannotDisableKeyperModuleIfGuardEnabled() (gas: 1781445) +KeyperGuardTest:testCannotDisconnectSafe_As_ROOTSAFE_TARGET_ITSELF_If_Have_children() (gas: 1741215) +KeyperGuardTest:testCannotDisconnectSafe_As_ROOTSAFE_TARGET_ROOTSAFE_SAME_TREE() (gas: 2327537) +KeyperGuardTest:testCannotDisconnectSafe_As_RootSafe_As_DifferentTree() (gas: 4676244) +KeyperGuardTest:testCannotDisconnectSafe_As_SafeLead_As_EOA() (gas: 2381151) +KeyperGuardTest:testCannotDisconnectSafe_As_SafeLead_As_SAFE() (gas: 2784300) +KeyperGuardTest:testCannotDisconnectSafe_As_SuperSafe_As_DifferentTree() (gas: 4647654) +KeyperGuardTest:testCannotDisconnectSafe_As_SuperSafe_As_SameTree() (gas: 2422421) +KeyperGuardTest:testCannotPromoteToRoot_As_ROOTSAFE_TARGET_SQUAD_SAFE() (gas: 2431220) +KeyperGuardTest:testCannotPromoteToRoot_As_ROOTSAFE_TARGET_SUPER_SAFE_ANOTHER_ORG() (gas: 4642773) +KeyperGuardTest:testCannotPromoteToRoot_As_ROOTSAFE_TARGET_SUPER_SAFE_ANOTHER_TREE() (gas: 4557898) +KeyperGuardTest:testCannotReplayAttackDisconnectedSafe() (gas: 1705845) +KeyperGuardTest:testCannotReplayAttackRemoveSquad() (gas: 1783004) +KeyperGuardTest:testCannotReplayAttackRemoveWholeTree() (gas: 3094080) +KeyperGuardTest:testDisableKeyperGuard() (gas: 133183) +KeyperGuardTest:testDisableKeyperModule() (gas: 104743) +KeyperGuardTest:testDisconnectSafeBeforeToRemoveSquad_One_Level() (gas: 2298358) +KeyperGuardTest:testDisconnectSafeBeforeToRemoveSquad_Two_Level() (gas: 2926801) +KeyperGuardTest:testDisconnectSafe_As_ROOTSAFE_TARGET_ITSELF_If_Not_Have_children() (gas: 1901664) +KeyperGuardTest:testDisconnectSafe_As_ROOTSAFE_TARGET_ROOT_SAFE() (gas: 2390225) +KeyperGuardTest:testDisconnectSafe_As_ROOTSAFE_TARGET_SUPERSAFE_SAME_TREE() (gas: 1702407) KeyperRoleDeployTest:testSetUserRoles() (gas: 32278) KeyperRoleDeployTest:testSetupRolesCapabilities() (gas: 157803) KeyperRolesTest:testCan_KeyperModule_Setup_RoleContract() (gas: 18046) KeyperRolesTest:testCan_ROOT_SAFE_SetRole_ROOT_SAFE_When_RegisterOrg() (gas: 261578) -KeyperRolesTest:testCan_ROOT_SAFE_SetRole_SAFE_LEAD_to_EAO() (gas: 1754991) -KeyperRolesTest:testCan_ROOT_SAFE_SetRole_SAFE_LEAD_to_SAFE() (gas: 2192766) -KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_ROOT_SAFE_to_EAO() (gas: 1680031) -KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_ROOT_SAFE_to_EOA_DifferentTree_Safe() (gas: 3012977) -KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_SUPER_SAFE_to_EAO() (gas: 1679916) -KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_SUPER_SAFE_to_SAFE() (gas: 2303128) -KeyperRolesTest:testCannot_SUPER_SAFE_SetRole_SAFE_LEAD_to_EAO() (gas: 1679368) -ModifySafeOwners:testCan_AddOwnerWithThreshold_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 2435178) -ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_EOA_is_TARGETS_LEAD() (gas: 1839151) -ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_SAFE_is_TARGETS_LEAD() (gas: 3254480) -ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_as_EOA_is_TARGETS_LEAD() (gas: 3181314) -ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD() (gas: 3254758) -ModifySafeOwners:testCan_AddOwnerWithThreshold_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 2446090) -ModifySafeOwners:testCan_RemoveOwner_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 2391200) -ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_EOA_is_TARGETS_LEAD() (gas: 1806494) -ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_SAFE_is_TARGETS_LEAD() (gas: 3214633) -ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_as_EOA_is_TARGETS_LEAD() (gas: 1811083) -ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD() (gas: 2542711) -ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD_DifferentTree() (gas: 3196077) -ModifySafeOwners:testCan_RemoveOwner_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 2402030) -ModifySafeOwners:testRevertInvalidThresholdAddOwnerWithThreshold() (gas: 1878757) -ModifySafeOwners:testRevertInvalidThresholdRemoveOwner() (gas: 1850062) -ModifySafeOwners:testRevertOwnerAlreadyExistsAddOwnerWithThreshold() (gas: 1794906) -ModifySafeOwners:testRevertOwnerNotFoundRemoveOwner() (gas: 496767) -ModifySafeOwners:testRevertRootSafeToAttemptTo_AddOwnerWithThreshold_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 3043215) -ModifySafeOwners:testRevertRootSafeToAttemptTo_AddOwnerWithThreshold_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 4471986) -ModifySafeOwners:testRevertRootSafeToAttemptTo_removeOwner_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 3044724) -ModifySafeOwners:testRevertRootSafeToAttemptTo_removeOwner_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 4473066) -ModifySafeOwners:testRevertRootSafesAttemptToAddToExternalSafeOrg() (gas: 3032113) -ModifySafeOwners:testRevertRootSafesToAttemptToRemoveFromExternalOrg() (gas: 3045921) -ModifySafeOwners:testRevertSafeNotRegisteredAddOwnerWithThreshold_EOA_Caller() (gas: 936337) -ModifySafeOwners:testRevertSafeNotRegisteredAddOwnerWithThreshold_SAFE_Caller() (gas: 940203) -ModifySafeOwners:testRevertSafeNotRegisteredRemoveOwner_EOA_Caller() (gas: 505264) -ModifySafeOwners:testRevertSafeNotRegisteredRemoveOwner_SAFE_Caller() (gas: 509494) -ModifySafeOwners:testRevertZeroAddressAddOwnerWithThreshold() (gas: 1672722) -ModifySafeOwners:testRevertZeroAddressProvidedRemoveOwner() (gas: 3080094) +KeyperRolesTest:testCan_ROOT_SAFE_SetRole_SAFE_LEAD_to_EAO() (gas: 1754297) +KeyperRolesTest:testCan_ROOT_SAFE_SetRole_SAFE_LEAD_to_SAFE() (gas: 2191804) +KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_ROOT_SAFE_to_EAO() (gas: 1679337) +KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_ROOT_SAFE_to_EOA_DifferentTree_Safe() (gas: 3011600) +KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_SUPER_SAFE_to_EAO() (gas: 1679222) +KeyperRolesTest:testCannot_ROOT_SAFE_SetRole_SUPER_SAFE_to_SAFE() (gas: 2302241) +KeyperRolesTest:testCannot_SUPER_SAFE_SetRole_SAFE_LEAD_to_EAO() (gas: 1678674) +ModifySafeOwners:testCan_AddOwnerWithThreshold_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 2434025) +ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_EOA_is_TARGETS_LEAD() (gas: 1838369) +ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_SAFE_is_TARGETS_LEAD() (gas: 3252837) +ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_as_EOA_is_TARGETS_LEAD() (gas: 3179761) +ModifySafeOwners:testCan_AddOwnerWithThreshold_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD() (gas: 3253115) +ModifySafeOwners:testCan_AddOwnerWithThreshold_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 2444937) +ModifySafeOwners:testCan_RemoveOwner_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 2390069) +ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_EOA_is_TARGETS_LEAD() (gas: 1805690) +ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_MODIFY_OWNERS_ONLY_as_SAFE_is_TARGETS_LEAD() (gas: 3212990) +ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_as_EOA_is_TARGETS_LEAD() (gas: 1810257) +ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD() (gas: 2541415) +ModifySafeOwners:testCan_RemoveOwner_SAFE_LEAD_as_SAFE_is_TARGETS_LEAD_DifferentTree() (gas: 3194522) +ModifySafeOwners:testCan_RemoveOwner_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 2400899) +ModifySafeOwners:testRevertInvalidThresholdAddOwnerWithThreshold() (gas: 1878041) +ModifySafeOwners:testRevertInvalidThresholdRemoveOwner() (gas: 1849302) +ModifySafeOwners:testRevertOwnerAlreadyExistsAddOwnerWithThreshold() (gas: 1794146) +ModifySafeOwners:testRevertOwnerNotFoundRemoveOwner() (gas: 496666) +ModifySafeOwners:testRevertRootSafeToAttemptTo_AddOwnerWithThreshold_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 3041750) +ModifySafeOwners:testRevertRootSafeToAttemptTo_AddOwnerWithThreshold_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 4469805) +ModifySafeOwners:testRevertRootSafeToAttemptTo_removeOwner_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SAFE() (gas: 3043259) +ModifySafeOwners:testRevertRootSafeToAttemptTo_removeOwner_SUPER_SAFE_as_SAFE_is_TARGETS_SUPER_SAFE() (gas: 4470885) +ModifySafeOwners:testRevertRootSafesAttemptToAddToExternalSafeOrg() (gas: 3030714) +ModifySafeOwners:testRevertRootSafesToAttemptToRemoveFromExternalOrg() (gas: 3044478) +ModifySafeOwners:testRevertSafeNotRegisteredAddOwnerWithThreshold_EOA_Caller() (gas: 935779) +ModifySafeOwners:testRevertSafeNotRegisteredAddOwnerWithThreshold_SAFE_Caller() (gas: 939645) +ModifySafeOwners:testRevertSafeNotRegisteredRemoveOwner_EOA_Caller() (gas: 504952) +ModifySafeOwners:testRevertSafeNotRegisteredRemoveOwner_SAFE_Caller() (gas: 509182) +ModifySafeOwners:testRevertZeroAddressAddOwnerWithThreshold() (gas: 1671984) +ModifySafeOwners:testRevertZeroAddressProvidedRemoveOwner() (gas: 3078651) TestDeploy:testDeploy() (gas: 6283203) -TestDeploySafe:testTransferFundsSafe() (gas: 109672) -TestEnableGuard:testEnableKeyperGuard() (gas: 120880) -TestEnableGuard:testEnableKeyperModule() (gas: 122295) -TestEnableModule:testEnableKeyperModule() (gas: 122305) -TestEnableModule:testNewSafeWithKeyperModule() (gas: 470263) +TestDeploySafe:testTransferFundsSafe() (gas: 109606) +TestEnableGuard:testEnableKeyperGuard() (gas: 120823) +TestEnableGuard:testEnableKeyperModule() (gas: 122238) +TestEnableModule:testEnableKeyperModule() (gas: 122248) +TestEnableModule:testNewSafeWithKeyperModule() (gas: 469951) TestKeyperSafe:testAuthorityAddress() (gas: 10869) -TestKeyperSafe:testCan_RemoveSquad_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SameTree() (gas: 3025393) -TestKeyperSafe:testCan_RemoveSquad_SUPER_SAFE_as_SAFE_is_SUPER_SAFE_SameTree() (gas: 2411046) -TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_not_root_of_target() (gas: 1686189) -TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_not_super_safe_of_target() (gas: 2308948) -TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_root_of_target() (gas: 1683489) -TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_super_safe_of_target() (gas: 2304216) -TestKeyperSafe:testCannot_RemoveSquad_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_DifferentOrg() (gas: 4603954) -TestKeyperSafe:testCannot_RemoveSquad_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_DifferentTree() (gas: 3095166) -TestKeyperSafe:testCannot_RemoveSquad_SUPER_SAFE_as_SAFE_is_not_TARGET_SUPER_SAFE_DifferentTree() (gas: 4613454) -TestKeyperSafe:testCannot_RemoveSquad_SUPER_SAFE_as_SAFE_is_not_TARGET_SUPER_SAFE_SameTree() (gas: 2950385) -TestKeyperSafe:testDisableDenyHelperList() (gas: 2667735) -TestKeyperSafe:testRemoveSquadAndCheckDisables() (gas: 1786600) +TestKeyperSafe:testCan_RemoveSquad_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_SameTree() (gas: 3024201) +TestKeyperSafe:testCan_RemoveSquad_SUPER_SAFE_as_SAFE_is_SUPER_SAFE_SameTree() (gas: 2410047) +TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_not_root_of_target() (gas: 1685495) +TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_not_super_safe_of_target() (gas: 2308061) +TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_root_of_target() (gas: 1682795) +TestKeyperSafe:testCan_hasNotPermissionOverTarget_is_super_safe_of_target() (gas: 2303329) +TestKeyperSafe:testCannot_RemoveSquad_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_DifferentOrg() (gas: 4601850) +TestKeyperSafe:testCannot_RemoveSquad_ROOT_SAFE_as_SAFE_is_TARGETS_ROOT_DifferentTree() (gas: 3093789) +TestKeyperSafe:testCannot_RemoveSquad_SUPER_SAFE_as_SAFE_is_not_TARGET_SUPER_SAFE_DifferentTree() (gas: 4611350) +TestKeyperSafe:testCannot_RemoveSquad_SUPER_SAFE_as_SAFE_is_not_TARGET_SUPER_SAFE_SameTree() (gas: 2949305) +TestKeyperSafe:testDisableDenyHelperList() (gas: 2666848) +TestKeyperSafe:testRemoveSquadAndCheckDisables() (gas: 1785794) TestKeyperSafe:testRevertAuthForRegisterOrgTx() (gas: 14097) -TestKeyperSafe:testRevertSuperSafeExecOnBehalfIsDenyList() (gas: 2527485) -TestKeyperSafe:testRevertSuperSafeExecOnBehalfIsNotAllowList() (gas: 2436481) \ No newline at end of file +TestKeyperSafe:testRevertSuperSafeExecOnBehalfIsDenyList() (gas: 2526598) +TestKeyperSafe:testRevertSuperSafeExecOnBehalfIsNotAllowList() (gas: 2435594) \ No newline at end of file diff --git a/script/DeployKeyperEnv.s.sol b/script/DeployKeyperEnv.s.sol index 3c18065..c5aaed3 100644 --- a/script/DeployKeyperEnv.s.sol +++ b/script/DeployKeyperEnv.s.sol @@ -21,10 +21,11 @@ contract DeployKeyperEnv is Script { // The address https://sepolia.etherscan.io/address/0x93FEC2C00BfE902F733B57c5a6CeeD7CD1384AE1#code, is the address of the CREATE3Factory in Sepolia CREATE3Factory factory = CREATE3Factory(0x93FEC2C00BfE902F733B57c5a6CeeD7CD1384AE1); + // Salt is a random number that is used to predict the deployment address bytes32 salt = keccak256(abi.encode(0xddff)); // need to be unique to avoid collision address keyperModulePredicted = factory.getDeployed(msg.sender, salt); - // Deploy Safe contracts in goerli + // Deploy Safe contracts in any network Solenv.config(); address masterCopy = vm.envAddress("MASTER_COPY_ADDRESS"); address proxyFactory = vm.envAddress("PROXY_FACTORY_ADDRESS"); diff --git a/script/SkipExecutionOnBehalf.s.sol b/script/SkipExecutionOnBehalf.s.sol index e55d290..aeea42e 100644 --- a/script/SkipExecutionOnBehalf.s.sol +++ b/script/SkipExecutionOnBehalf.s.sol @@ -13,7 +13,7 @@ contract SkipSeveralScenarios is Script, SkipSetupEnv { function setUp() public { // Set up env run(); - testRevertInvalidGnosisSafeExecTransactionOnBehalf(); + testRevertInvalidSignatureExecOnBehalf(); // These are different chain test scenarios, specifically for the execTransactionOnBehalf function in Polygon and Sepolia. // We test each scenario independently manually and get the results on the Live Mainnet on Polygon and Sepolia. // testCannot_ExecTransactionOnBehalf_Wrapper_ExecTransactionOnBehalf_ChildSquad_over_RootSafe_With_SAFE(); // ✅ @@ -424,7 +424,7 @@ contract SkipSeveralScenarios is Script, SkipSetupEnv { // // ! ********************** REVERT ******************** - // Revert: "GS026" execTransactionOnBehalf when is Any EOA, passing the wrong signature of the Root/Super Safe of Target Safe + // Revert: "GS020" execTransactionOnBehalf when is Any EOA, passing the wrong signature of the Root/Super Safe of Target Safe // Caller: callerEOA // Caller Type: EOA // Caller Role: nothing @@ -467,7 +467,7 @@ contract SkipSeveralScenarios is Script, SkipSetupEnv { Enum.Operation(0) ); - // vm.expectRevert("GS020"); // GS020: Invalid signatures provided + // vm.expectRevert("GS020"); // GS020: Signatures data too short keyperModule.execTransactionOnBehalf( orgHash, rootAddr, @@ -481,7 +481,7 @@ contract SkipSeveralScenarios is Script, SkipSetupEnv { vm.stopBroadcast(); } - // Revert: "GS013" execTransactionOnBehalf when is Any EOA, (invalid signatures provided) + // Revert: "GS026" execTransactionOnBehalf when is Any EOA, (invalid signatures provided) // Caller: callerEOA // Caller Type: EOA // Caller Role: nothing @@ -523,7 +523,7 @@ contract SkipSeveralScenarios is Script, SkipSetupEnv { Enum.Operation(0) ); - // vm.expectRevert("GS026"); // GS026: Invalid signatures provided + // vm.expectRevert("GS026"); // GS026: Invalid owner provided keyperModule.execTransactionOnBehalf( orgHash, rootAddr, @@ -596,7 +596,7 @@ contract SkipSeveralScenarios is Script, SkipSetupEnv { vm.stopBroadcast(); } - // Revert "GS013" execTransactionOnBehalf (invalid signatures provided) + // Revert "GS026" execTransactionOnBehalf (invalid signatures provided) // Caller: rootAddr // Caller Type: rootSafe // Caller Role: ROOT_SAFE @@ -625,7 +625,7 @@ contract SkipSeveralScenarios is Script, SkipSetupEnv { Enum.Operation(0) ); - // vm.expectRevert("GS013"); // GS013: Invalid signatures provided + // vm.expectRevert("GS013"); // GS026/GS013: Invalid owner provided execTransactionOnBehalfTx( orgHash, rootAddr, diff --git a/src/KeyperRoles.sol b/src/KeyperRoles.sol index 5dc1665..8e48717 100644 --- a/src/KeyperRoles.sol +++ b/src/KeyperRoles.sol @@ -224,6 +224,10 @@ contract KeyperRoles is RolesAuthority, ValidAddress { USER ROLE (OVERRIDE) ASSIGNMENT LOGIC //////////////////////////////////////////////////////////////*/ + /// function to assign a role to a user + /// @param user address of the user + /// @param role uint8 role to assign + /// @param enabled bool enable or disable the role function setUserRole(address user, uint8 role, bool enabled) public virtual diff --git a/test/DeploySafe.t.sol b/test/DeploySafe.t.sol index a2f5507..564292a 100644 --- a/test/DeploySafe.t.sol +++ b/test/DeploySafe.t.sol @@ -18,6 +18,7 @@ contract TestDeploySafe is Test, SigningUtils, SignDigestHelper { gnosisSafeAddr = gnosisHelper.setupSafeEnv(); } + /// @notice Test to transfer funds to safe function testTransferFundsSafe() public { bytes memory emptyData; diff --git a/test/EnableGuard.t.sol b/test/EnableGuard.t.sol index edc284e..e6e1723 100644 --- a/test/EnableGuard.t.sol +++ b/test/EnableGuard.t.sol @@ -15,6 +15,7 @@ contract TestEnableGuard is Test { GnosisSafeHelper gnosisHelper; address gnosisSafeAddr; + /// @notice Set up the environment for testing function setUp() public { // Init new safe gnosisHelper = new GnosisSafeHelper(); @@ -32,6 +33,7 @@ contract TestEnableGuard is Test { gnosisHelper.setKeyperGuard(address(keyperGuard)); } + /// @notice Test enabling the KeyperModule function testEnableKeyperModule() public { bool result = gnosisHelper.enableModuleTx(gnosisSafeAddr); assertEq(result, true); @@ -41,6 +43,7 @@ contract TestEnableGuard is Test { assertEq(isKeyperModuleEnabled, true); } + /// @notice Test enabling the KeyperGuard function testEnableKeyperGuard() public { bool result = gnosisHelper.enableGuardTx(gnosisSafeAddr); assertEq(result, true); diff --git a/test/EnableModule.t.sol b/test/EnableModule.t.sol index 80f4fa5..2007e19 100644 --- a/test/EnableModule.t.sol +++ b/test/EnableModule.t.sol @@ -12,6 +12,7 @@ contract TestEnableModule is Test { GnosisSafeHelper gnosisHelper; address gnosisSafeAddr; + /// @notice Set up the environment function setUp() public { // Init new safe gnosisHelper = new GnosisSafeHelper(); @@ -27,6 +28,7 @@ contract TestEnableModule is Test { gnosisHelper.setKeyperModule(address(keyperModule)); } + /// @notice Test enable Keyper Module function testEnableKeyperModule() public { bool result = gnosisHelper.enableModuleTx(gnosisSafeAddr); assertEq(result, true); @@ -36,6 +38,7 @@ contract TestEnableModule is Test { assertEq(isKeyperModuleEnabled, true); } + /// @notice Test disable Keyper Module function testNewSafeWithKeyperModule() public { // Create new safe with setup called while creating contract gnosisHelper.newKeyperSafe(4, 2); diff --git a/test/EventsChecker.t.sol b/test/EventsChecker.t.sol index 53b06d3..840222f 100644 --- a/test/EventsChecker.t.sol +++ b/test/EventsChecker.t.sol @@ -110,6 +110,7 @@ contract EventsChekers is DeployHelper { owners[4] = address(0xEEE); } + /// @notice Test Events when Register Root Organization function testEventWhenRegisterRootOrg() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -122,6 +123,7 @@ contract EventsChekers is DeployHelper { vm.stopPrank(); } + /// @notice Test Events when Add Squad function testEventWhenAddSquad() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -149,6 +151,7 @@ contract EventsChekers is DeployHelper { keyperModule.addSquad(rootId, squadA1Name); } + /// @notice Test Events when Remove Squad function testEventWhenRemoveSquad() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -190,6 +193,7 @@ contract EventsChekers is DeployHelper { keyperModule.removeSquad(squadId); } + /// @notice Test Events when Register Root Safe function testEventWhenRegisterRootSafe() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -216,6 +220,7 @@ contract EventsChekers is DeployHelper { keyperModule.createRootSafeSquad(rootSafeAddr, org2Name); } + /// @notice Test Events when Update Super Safe function testEventWhenUpdateSuper() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -273,6 +278,7 @@ contract EventsChekers is DeployHelper { keyperModule.updateSuper(squadId, rootsafeId); } + /// @notice Test Events when Promote Squad to Root Safe function testEventWhenPromoteRootSafe() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -329,6 +335,7 @@ contract EventsChekers is DeployHelper { keyperModule.promoteRoot(squadId); } + /// @notice Test Events when Disconnect Safe function testEventWhenDisconnectSafe() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -377,6 +384,7 @@ contract EventsChekers is DeployHelper { keyperModule.disconnectSafe(squadId); } + /// @notice Test Events when Call Execution on Behalf function testEventWhenExecutionOnBehalf() public { (uint256 rootId, uint256 safeSquadA1) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -419,6 +427,7 @@ contract EventsChekers is DeployHelper { vm.stopPrank(); } + /// @notice Test Events when Remove Whole Tree function testEventWhenRemoveWholeTree() public { ( uint256 rootId, @@ -438,6 +447,7 @@ contract EventsChekers is DeployHelper { keyperModule.removeWholeTree(); } + /// @notice Test Events when Update New Limit function testEventWhenUpdateNewLimit() public { // Register Org through safe tx address rootAddr = gnosisHelper.newKeyperSafe(4, 2); @@ -474,6 +484,7 @@ contract EventsChekers is DeployHelper { keyperModule.updateDepthTreeLimit(49); } + /// @notice Test Events when Add Address to Enable/Denied Allow List function testEventWhenAddToList() public { address rootAddr = gnosisHelper.newKeyperSafe(4, 2); vm.startPrank(rootAddr); @@ -484,6 +495,7 @@ contract EventsChekers is DeployHelper { keyperModule.addToList(owners); } + /// @notice Test Events when Drop Address to Enable/Denied Allow List function testEventWhenDropFromList() public { address rootAddr = gnosisHelper.newKeyperSafe(4, 2); vm.startPrank(rootAddr); diff --git a/test/Hierarchies.t.sol b/test/Hierarchies.t.sol index babbb79..f1ee170 100644 --- a/test/Hierarchies.t.sol +++ b/test/Hierarchies.t.sol @@ -4,11 +4,12 @@ pragma solidity ^0.8.15; import "./helpers/DeployHelper.t.sol"; contract Hierarchies is DeployHelper { - // Function called before each test is run + /// Function called before each test is run function setUp() public { DeployHelper.deployAllContracts(90); } + /// @notice Test Register Root Organization function testRegisterRootOrg() public { bool result = gnosisHelper.registerOrgTx(orgName); assertEq(result, true); @@ -39,6 +40,7 @@ contract Hierarchies is DeployHelper { ); } + /// @notice Test Add Squad to Root Organization function testAddSquad() public { (uint256 rootId, uint256 squadIdA1) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -77,12 +79,14 @@ contract Hierarchies is DeployHelper { ); } + /// @notice Test Expect Invalid Squad Id function testExpectInvalidSquadId() public { uint256 orgIdNotRegistered = 2; vm.expectRevert(Errors.InvalidSquadId.selector); keyperModule.addSquad(orgIdNotRegistered, squadA1Name); } + /// @notice Test Expect Squad Not Registered function testExpectSquadNotRegistered() public { uint256 orgIdNotRegistered = 1; vm.expectRevert( @@ -93,6 +97,7 @@ contract Hierarchies is DeployHelper { keyperModule.addSquad(orgIdNotRegistered, squadA1Name); } + /// @notice Test Add SubSquad to Squad function testAddSubSquad() public { (uint256 rootId, uint256 squadIdA1) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -105,6 +110,7 @@ contract Hierarchies is DeployHelper { assertEq(keyperModule.isSuperSafe(squadIdA1, squadIdB), true); } + /// @notice Test an Org with Tree Levels of Tree Member function testTreeOrgsTreeMember() public { (uint256 rootId, uint256 squadIdA1, uint256 subSquadIdA1,,) = keyperSafeBuilder.setupOrgThreeTiersTree( @@ -120,6 +126,7 @@ contract Hierarchies is DeployHelper { assertEq(keyperModule.isTreeMember(rootId, squadIdB), false); } + /// @notice Test if a Squad is Super Safe function testIsSuperSafe() public { ( uint256 rootId, @@ -138,6 +145,7 @@ contract Hierarchies is DeployHelper { assertEq(keyperModule.isSuperSafe(subSquadIdA1, squadIdA1), false); } + /// @notice Test Update Super Safe function testUpdateSuper() public { ( uint256 rootId, @@ -195,6 +203,7 @@ contract Hierarchies is DeployHelper { ); } + /// @notice Test Revert Expected when Update Super Invalid Squad Id function testRevertUpdateSuperInvalidSquadId() public { (uint256 rootId, uint256 squadIdA1) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -207,6 +216,7 @@ contract Hierarchies is DeployHelper { keyperModule.updateSuper(squadIdA1, squadNotRegisteredId); } + /// @notice Test Revert Expected when Update Super if Caller is not Safe function testRevertUpdateSuperIfCallerIsNotSafe() public { (uint256 rootId, uint256 squadIdA1) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -220,6 +230,7 @@ contract Hierarchies is DeployHelper { vm.stopPrank(); } + /// @notice Test Revert Expected when Update Super if Caller is not Part of the Org function testRevertUpdateSuperIfCallerNotPartofTheOrg() public { (uint256 rootId, uint256 squadIdA1) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -233,6 +244,7 @@ contract Hierarchies is DeployHelper { vm.stopPrank(); } + /// @notice Test Create Squad Three Tiers Tree function testCreateSquadThreeTiersTree() public { (uint256 orgRootId, uint256 safeSquadA1Id, uint256 safeSubSquadA1Id,,) = keyperSafeBuilder.setupOrgThreeTiersTree( @@ -273,6 +285,7 @@ contract Hierarchies is DeployHelper { assertEq(superSafe, safeSquadA1Id); } + /// @notice Test Create Squad Four Tiers Tree function testOrgFourTiersTreeSuperSafeRoles() public { ( uint256 rootId, @@ -316,6 +329,7 @@ contract Hierarchies is DeployHelper { ); } + /// @notice Test Revert Expected when Add Squad Already Registered function testRevertSafeAlreadyRegisteredAddSquad() public { (, uint256 squadIdA1) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -342,6 +356,7 @@ contract Hierarchies is DeployHelper { } // ! **************** List of Test for Depth Tree Limits ******************************* + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit with Invalid Value function testRevertIfTryInvalidLimit() public { (uint256 rootId,) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -356,6 +371,7 @@ contract Hierarchies is DeployHelper { vm.stopPrank(); } + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit from Non Root Safe function testRevertIfTryNotRootSafe() public { (, uint256 squadA1Id) = keyperSafeBuilder.setupRootOrgAndOneSquad(orgName, squadA1Name); @@ -383,6 +399,7 @@ contract Hierarchies is DeployHelper { vm.stopPrank(); } + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit with a Value to Exceed the Max Limit function testRevertifExceedMaxDepthTreeLimit() public { ( uint256 rootId, @@ -436,6 +453,7 @@ contract Hierarchies is DeployHelper { } } + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit and Exceed the Max Limit function testRevertifUpdateLimitAndExceedMaxDepthTreeLimit() public { ( uint256 rootId, @@ -517,6 +535,7 @@ contract Hierarchies is DeployHelper { } } + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit and Update Super function testRevertifExceedMaxDepthTreeLimitAndUpdateSuper() public { ( uint256 rootIdA, @@ -581,6 +600,7 @@ contract Hierarchies is DeployHelper { } } + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit and Exceed the Max Limit and Update Super function testRevertifUpdateLimitAndExceedMaxDepthTreeLimitAndUpdateSuper() public { @@ -676,6 +696,7 @@ contract Hierarchies is DeployHelper { } } + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit and Update Super to Another Org function testRevertifUpdateSuperToAnotherOrg() public { ( uint256 rootId, @@ -733,6 +754,7 @@ contract Hierarchies is DeployHelper { } } + /// @notice Test Reverted Expected if Try to Update Depth Tree Limit and Exceed the Max Limit and Update Super to Another Org function testRevertifUpdateDepthTreeLimitAndUpdateSuperToAnotherOrg() public { diff --git a/test/KeyperRoles.t.sol b/test/KeyperRoles.t.sol index 0252ba3..cb84e68 100644 --- a/test/KeyperRoles.t.sol +++ b/test/KeyperRoles.t.sol @@ -168,7 +168,7 @@ contract KeyperRolesTest is DeployHelper { keyperModule.setRole(DataTypes.Role.SUPER_SAFE, user, safeSquadA1, true); } - // Caller Info: Role-> ROOT_SAFE, Type -> SAFE, Hierarchy -> Root, Name -> rootA + // Caller Info: Role-> ROOT_SAFE, Type -> SAFE, Hierarchy -> Root, Name -> rootA // Target Info: Type-> EOA, Name -> SquadA, Hierarchy related to caller -> N/A function testCannot_ROOT_SAFE_SetRole_ROOT_SAFE_to_EOA_DifferentTree_Safe() public diff --git a/test/deploy.t.sol b/test/deploy.t.sol index 97a9cdf..8a743e4 100644 --- a/test/deploy.t.sol +++ b/test/deploy.t.sol @@ -10,10 +10,12 @@ import "./helpers/DeployHelper.t.sol"; contract TestDeploy is DeployHelper { DeployModuleWithMockedSafe deploy; + /// @notice Deploy Libraries function setUp() public { deploy = new DeployModuleWithMockedSafe(); } + /// @notice Deploy Libraries function testDeploy() public { // Deplot Libraries ( diff --git a/test/helpers/DeployHelper.t.sol b/test/helpers/DeployHelper.t.sol index bbe6489..fa8193d 100644 --- a/test/helpers/DeployHelper.t.sol +++ b/test/helpers/DeployHelper.t.sol @@ -53,7 +53,7 @@ contract DeployHelper is Test { function deployAllContracts(uint256 initOwners) public { CREATE3Factory factory = new CREATE3Factory(); bytes32 salt = keccak256(abi.encode(0xafff)); - + /// get address of deployed libraries ( address constantsAddr, address dataTypesAddr, diff --git a/test/helpers/GnosisSafeHelper.t.sol b/test/helpers/GnosisSafeHelper.t.sol index f666b32..ab81342 100644 --- a/test/helpers/GnosisSafeHelper.t.sol +++ b/test/helpers/GnosisSafeHelper.t.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-3.0-only +/// SPDX-License-Identifier: LGPL-3.0-only pragma solidity ^0.8.15; import "forge-std/Test.sol"; @@ -10,7 +10,7 @@ import {GnosisSafe} from "@safe-contracts/GnosisSafe.sol"; import {DataTypes} from "../../libraries/DataTypes.sol"; import {Random} from "../../libraries/Random.sol"; -// Helper contract handling deployment Gnosis Safe contracts +/// Helper contract handling deployment Gnosis Safe contracts contract GnosisSafeHelper is Test, SigningUtils, @@ -27,10 +27,11 @@ contract GnosisSafeHelper is uint256 public salt; - // Create new gnosis safe test environment - // Deploy main safe contracts (GnosisSafeProxyFactory, GnosisSafe mastercopy) - // Init signers - // Deploy a new safe proxy + /// Create new gnosis safe test environment + /// Deploy main safe contracts (GnosisSafeProxyFactory, GnosisSafe mastercopy) + /// Init signers + /// Deploy a new safe proxy + /// @return address of the new safe function setupSafeEnv() public returns (address) { safeFactory = new DeploySafeFactory(); safeFactory.run(); @@ -40,12 +41,12 @@ contract GnosisSafeHelper is gnosisSafe = GnosisSafe(payable(gnosisSafeProxy)); initOnwers(30); - // Setup gnosis safe with 3 owners, 1 threshold + /// Setup gnosis safe with 3 owners, 1 threshold address[] memory owners = new address[](3); owners[0] = vm.addr(privateKeyOwners[0]); owners[1] = vm.addr(privateKeyOwners[1]); owners[2] = vm.addr(privateKeyOwners[2]); - // Update privateKeyOwners used + /// Update privateKeyOwners used updateCount(3); gnosisSafe.setup( @@ -62,11 +63,13 @@ contract GnosisSafeHelper is return address(gnosisSafe); } - // Create new gnosis safe test environment - // Deploy main safe contracts (GnosisSafeProxyFactory, GnosisSafe mastercopy) - // Init signers - // Permit create a specific numbers of owners - // Deploy a new safe proxy + /// Create new gnosis safe test environment + /// Deploy main safe contracts (GnosisSafeProxyFactory, GnosisSafe mastercopy) + /// Init signers + /// Permit create a specific numbers of owners + /// Deploy a new safe proxy + /// @param initOwners number of owners to initialize + /// @return address of the new safe function setupSeveralSafeEnv(uint256 initOwners) public virtual @@ -81,12 +84,12 @@ contract GnosisSafeHelper is gnosisSafe = GnosisSafe(payable(gnosisSafeProxy)); initOnwers(initOwners); - // Setup gnosis safe with 3 owners, 1 threshold + /// Setup gnosis safe with 3 owners, 1 threshold address[] memory owners = new address[](3); owners[0] = vm.addr(privateKeyOwners[0]); owners[1] = vm.addr(privateKeyOwners[1]); owners[2] = vm.addr(privateKeyOwners[2]); - // Update privateKeyOwners used + /// Update privateKeyOwners used updateCount(3); gnosisSafe.setup( @@ -103,19 +106,28 @@ contract GnosisSafeHelper is return address(gnosisSafe); } + /// function to set keyperRoles address + /// @param keyperRoles keyperRoles address function setKeyperRoles(address keyperRoles) public { keyperRolesAddr = keyperRoles; } + /// function to set keyperModule address + /// @param keyperModule keyperModule address function setKeyperModule(address keyperModule) public virtual { keyperModuleAddr = keyperModule; } + /// function to set keyperGuard address + /// @param keyperGuard keyperGuard address function setKeyperGuard(address keyperGuard) public { keyperGuardAddr = keyperGuard; } - // Create GnosisSafe with Keyper and send module enabled tx + /// function to create Safe with Keyper and send module enabled tx + /// @param numberOwners number of owners + /// @param threshold threshold + /// @return address of the new safe function newKeyperSafe(uint256 numberOwners, uint256 threshold) public virtual @@ -151,17 +163,20 @@ contract GnosisSafeHelper is address gnosisSafeProxy = safeFactory.newSafeProxy(initializer); gnosisSafe = GnosisSafe(payable(address(gnosisSafeProxy))); - // Enable module + /// Enable module bool result = enableModuleTx(address(gnosisSafe)); require(result == true, "failed enable module"); - // Enable Guard + /// Enable Guard result = enableGuardTx(address(gnosisSafe)); require(result == true, "failed enable guard"); return address(gnosisSafe); } - // Create GnosisSafe with Keyper and send module enabled tx + /// fucntion to create Safe with Keyper and send module enabled tx + /// @param numberOwners number of owners + /// @param threshold threshold + /// @return address of the new safe function newKeyperSafeWithPKOwners(uint256 numberOwners, uint256 threshold) public virtual @@ -199,29 +214,26 @@ contract GnosisSafeHelper is address gnosisSafeProxy = safeFactory.newSafeProxy(initializer); gnosisSafe = GnosisSafe(payable(address(gnosisSafeProxy))); - // Enable module + /// Enable module bool result = enableModuleTx(address(gnosisSafe)); require(result == true, "failed enable module"); - // Enable Guard + /// Enable Guard result = enableGuardTx(address(gnosisSafe)); require(result == true, "failed enable guard"); return (address(gnosisSafe), ownersPK); } - function testNewKeyperSafe() public { - setupSafeEnv(); - setKeyperModule(address(0x678)); - newKeyperSafe(4, 2); - address[] memory owners = gnosisSafe.getOwners(); - assertEq(owners.length, 4); - assertEq(gnosisSafe.getThreshold(), 2); - } - + /// function to update Safe Interface + /// @param safe address of the Safe function updateSafeInterface(address safe) public { gnosisSafe = GnosisSafe(payable(address(safe))); } + /// function to get transaction hash of a Safe transaction + /// @param safeTx Safe transaction + /// @param nonce Safe nonce + /// @return bytes32 hash of the transaction function createSafeTxHash(Transaction memory safeTx, uint256 nonce) public view @@ -243,6 +255,10 @@ contract GnosisSafeHelper is return txHashed; } + /// function to create a default Safe transaction + /// @param to address of Safe + /// @param data data of the transaction + /// @return Transaction function createDefaultTx(address to, bytes memory data) public pure @@ -264,58 +280,75 @@ contract GnosisSafeHelper is return defaultTx; } + /// function to enable module + /// @param safe address of the Safe + /// @return bool function enableModuleTx(address safe) public returns (bool) { - // Create enableModule calldata + /// Create enableModule calldata bytes memory data = abi.encodeWithSignature("enableModule(address)", keyperModuleAddr); - // Create enable module safe tx + /// Create enable module safe tx Transaction memory mockTx = createDefaultTx(safe, data); bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to enable guard + /// @param safe address of the Safe + /// @return bool function enableGuardTx(address safe) public returns (bool) { - // Create enableModule calldata + /// Create enableModule calldata bytes memory data = abi.encodeWithSignature("setGuard(address)", keyperGuardAddr); - // Create enable module safe tx + /// Create enable module safe tx Transaction memory mockTx = createDefaultTx(safe, data); bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to disable module + /// @param prevModule address of the previous module + /// @param safe address of the Safe + /// @return bool function disableModuleTx(address prevModule, address safe) public returns (bool) { - // Create enableModule calldata + /// Create enableModule calldata bytes memory data = abi.encodeWithSignature( "disableModule(address,address)", prevModule, keyperModuleAddr ); - // Create enable module safe tx + /// Create enable module safe tx Transaction memory mockTx = createDefaultTx(safe, data); bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to disable guard + /// @param safe address of the Safe + /// @return bool function disableGuardTx(address safe) public returns (bool) { - // Create enableModule calldata + /// Create enableModule calldata bytes memory data = abi.encodeWithSignature("setGuard(address)", address(0)); - // Create enable module safe tx + /// Create enable module safe tx Transaction memory mockTx = createDefaultTx(safe, data); bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to execute Safe transaction + /// @param mockTx Safe transaction + /// @param signatures signatures of the transaction + /// @return bool function executeSafeTx(Transaction memory mockTx, bytes memory signatures) internal returns (bool) @@ -336,34 +369,45 @@ contract GnosisSafeHelper is return result; } + /// function to register organization + /// @param orgName name of the organization + /// @return bool function registerOrgTx(string memory orgName) public returns (bool) { - // Create enableModule calldata + /// Create enableModule calldata bytes memory data = abi.encodeWithSignature("registerOrg(string)", orgName); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to create a new squad + /// @param superSafe super safe + /// @param name name of the Organization + /// @return bool function createAddSquadTx(uint256 superSafe, string memory name) public returns (bool) { bytes memory data = abi.encodeWithSignature("addSquad(uint256,string)", superSafe, name); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to create a new Root Safe + /// @param newRootSafe address of the new Root Safe + /// @param name name of the Organization + /// @return bool function createRootSafeTx(address newRootSafe, string memory name) public returns (bool) @@ -371,46 +415,60 @@ contract GnosisSafeHelper is bytes memory data = abi.encodeWithSignature( "createRootSafeSquad(address,string)", newRootSafe, name ); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to remove a squad + /// @param squad squad to remove + /// @return bool function createRemoveSquadTx(uint256 squad) public returns (bool) { bytes memory data = abi.encodeWithSignature("removeSquad(uint256)", squad); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to remove a whole tree of squads + /// @return bool function createRemoveWholeTreeTx() public returns (bool) { bytes memory data = abi.encodeWithSignature("removeWholeTree()"); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to promote a squad to root safe + /// @param squad squad to promote + /// @return bool function createPromoteToRootTx(uint256 squad) public returns (bool) { bytes memory data = abi.encodeWithSignature("promoteRoot(uint256)", squad); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to set role + /// @param role role to set + /// @param user user to set role + /// @param squad squad to set role + /// @param enabled enable or disable role + /// @return bool function createSetRoleTx( uint8 role, address user, @@ -420,25 +478,38 @@ contract GnosisSafeHelper is bytes memory data = abi.encodeWithSignature( "setRole(uint8,address,uint256,bool)", role, user, squad, enabled ); - // Create module tx + /// Create module tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to disconnect a safe + /// @param squad squad to disconnect + /// @return bool function createDisconnectSafeTx(uint256 squad) public returns (bool) { bytes memory data = abi.encodeWithSignature("disconnectSafe(uint256)", squad); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to execute a transaction on behalf another safe in the organization, child from the super safe + /// @param org organization + /// @param superSafe super safe + /// @param targetSafe target safe + /// @param to receiver + /// @param value value + /// @param data data + /// @param operation operation + /// @param signaturesExec signatures + /// @return bool function execTransactionOnBehalfTx( bytes32 org, address superSafe, @@ -460,15 +531,22 @@ contract GnosisSafeHelper is operation, signaturesExec ); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, internalData); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to remove a owner of a safe, into the keyper module + /// @param prevOwner previous owner + /// @param ownerRemoved owner to remove + /// @param threshold threshold + /// @param targetSafe target safe + /// @param org organization + /// @return bool function removeOwnerTx( address prevOwner, address ownerRemoved, @@ -484,14 +562,20 @@ contract GnosisSafeHelper is targetSafe, org ); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to add a owner of a safe, into the keyper module + /// @param ownerAdded owner to add + /// @param threshold threshold + /// @param targetSafe target safe + /// @param org organization + /// @return bool function addOwnerWithThresholdTx( address ownerAdded, uint256 threshold, @@ -505,29 +589,32 @@ contract GnosisSafeHelper is targetSafe, org ); - // Create module safe tx + /// Create module safe tx Transaction memory mockTx = createDefaultTx(keyperModuleAddr, data); - // Sign tx + /// Sign tx bytes memory signatures = encodeSignaturesModuleSafeTx(mockTx); bool result = executeSafeTx(mockTx, signatures); return result; } + /// function to encode signatures of a Safe transaction to enable a keyper module + /// @param mockTx Safe transaction + /// @return bytes signatures function encodeSignaturesModuleSafeTx(Transaction memory mockTx) public view returns (bytes memory) { - // Create encoded tx to be signed + /// Create encoded tx to be signed uint256 nonce = gnosisSafe.nonce(); bytes32 enableModuleSafeTx = createSafeTxHash(mockTx, nonce); address[] memory owners = gnosisSafe.getOwners(); - // Order owners + /// Order owners address[] memory sortedOwners = sortAddresses(owners); uint256 threshold = gnosisSafe.getThreshold(); - // Get pk for the signing threshold + /// Get pk for the signing threshold uint256[] memory privateKeySafeOwners = new uint256[](threshold); for (uint256 i = 0; i < threshold; i++) { privateKeySafeOwners[i] = ownersPK[sortedOwners[i]]; diff --git a/test/helpers/KeyperModuleHelper.t.sol b/test/helpers/KeyperModuleHelper.t.sol index d54fe3f..f58132e 100644 --- a/test/helpers/KeyperModuleHelper.t.sol +++ b/test/helpers/KeyperModuleHelper.t.sol @@ -9,6 +9,7 @@ import {Enum} from "@safe-contracts/common/Enum.sol"; import {GnosisSafe} from "@safe-contracts/GnosisSafe.sol"; import {DeploySafeFactory} from "../../script/DeploySafeFactory.t.sol"; +/// Helper contract handling KeyperModule contract KeyperModuleHelper is Test, SignDigestHelper, SignersHelper { struct KeyperTransaction { address org; @@ -22,16 +23,29 @@ contract KeyperModuleHelper is Test, SignDigestHelper, SignersHelper { KeyperModule public keyper; GnosisSafe public safeHelper; + /// function to initialize the helper + /// @param _keyper instance of KeyperModule + /// @param numberOwners number of owners to initialize function initHelper(KeyperModule _keyper, uint256 numberOwners) public { keyper = _keyper; initOnwers(numberOwners); } + /// fucntion to set the Safe instance + /// @param safe address of the Safe instance function setGnosisSafe(address safe) public { safeHelper = GnosisSafe(payable(safe)); } - /// @notice Encode signatures for a keypertx + /// function Encode signatures for a keypertx + /// @param org Organization address + /// @param superSafe Super Safe address + /// @param targetSafe Target Safe address + /// @param to Address to send the transaction + /// @param value Value to send + /// @param data Data payload + /// @param operation Operation type + /// @return signatures Packed signatures data (v, r, s) function encodeSignaturesKeyperTx( bytes32 org, address superSafe, @@ -63,7 +77,15 @@ contract KeyperModuleHelper is Test, SignDigestHelper, SignersHelper { return signatures; } - /// @notice Sign keyperTx with invalid signatures (do not belong to any safe owner) + /// function Sign keyperTx with invalid signatures (do not belong to any safe owner) + /// @param org Organization address + /// @param superSafe Super Safe address + /// @param targetSafe Target Safe address + /// @param to Address to send the transaction + /// @param value Value to send + /// @param data Data payload + /// @param operation Operation type + /// @return signatures Packed signatures data (v, r, s) function encodeInvalidSignaturesKeyperTx( bytes32 org, address superSafe, @@ -91,6 +113,16 @@ contract KeyperModuleHelper is Test, SignDigestHelper, SignersHelper { return signatures; } + /// function to create a keyperTx hash + /// @param org Organization address + /// @param superSafe Super Safe address + /// @param targetSafe Target Safe address + /// @param to Address to send the transaction + /// @param value Value to send + /// @param data Data payload + /// @param operation Operation type + /// @param nonce Nonce of the transaction + /// @return txHashed Hash of the transaction function createKeyperTxHash( bytes32 org, address superSafe, diff --git a/test/helpers/ReentrancyAttackHelper.t.sol b/test/helpers/ReentrancyAttackHelper.t.sol index 5ece6c1..20a7f41 100644 --- a/test/helpers/ReentrancyAttackHelper.t.sol +++ b/test/helpers/ReentrancyAttackHelper.t.sol @@ -10,6 +10,7 @@ import {Attacker} from "../../src/ReentrancyAttack.sol"; import {Enum} from "@safe-contracts/common/Enum.sol"; import {DataTypes} from "../../libraries/DataTypes.sol"; +/// Helper contract handling ReentrancyAttack contract AttackerHelper is Test, SignDigestHelper, SignersHelper { KeyperModule public keyper; GnosisSafeHelper public gnosisHelper; @@ -17,6 +18,11 @@ contract AttackerHelper is Test, SignDigestHelper, SignersHelper { mapping(string => address) public keyperSafes; + /// function to initialize the helper + /// @param keyperArg instance of KeyperModule + /// @param attackerArg instance of Attacker + /// @param gnosisHelperArg instance of GnosisSafeHelper + /// @param numberOwners number of owners to initialize function initHelper( KeyperModule keyperArg, Attacker attackerArg, @@ -29,6 +35,15 @@ contract AttackerHelper is Test, SignDigestHelper, SignersHelper { initOnwers(numberOwners); } + /// function to encode signatures for Attack KeyperTx + /// @param org Organization address + /// @param superSafe Super Safe address + /// @param targetSafe Target Safe address + /// @param to Address to send the transaction + /// @param value Value to send + /// @param data Data payload + /// @param operation Operation type + /// @return signatures Packed signatures data (v, r, s) function encodeSignaturesForAttackKeyperTx( bytes32 org, address superSafe, @@ -57,6 +72,9 @@ contract AttackerHelper is Test, SignDigestHelper, SignersHelper { return signatures; } + /// function to set Attacker Tree for the organization + /// @param _orgName Name of the organization + /// @return orgHash, orgAddr, attackerSafe, victim function setAttackerTree(string memory _orgName) public returns (bytes32, address, address, address) diff --git a/test/helpers/SignersHelper.t.sol b/test/helpers/SignersHelper.t.sol index d236f38..66e5aba 100644 --- a/test/helpers/SignersHelper.t.sol +++ b/test/helpers/SignersHelper.t.sol @@ -18,11 +18,15 @@ contract SignersHelper is Test { // CountUsed uint256 public countUsed; + /// function to initialize the owners + /// @param numberOwners number of owners to initialize function initOnwers(uint256 numberOwners) public { initValidOnwers(numberOwners); initInvalidOnwers(30); } + /// function to initialize the valid owners + /// @param numberOwners number of valid owners to initialize function initValidOnwers(uint256 numberOwners) internal { privateKeyOwners = new uint256[](numberOwners); for (uint256 i = 0; i < numberOwners; i++) { @@ -37,6 +41,8 @@ contract SignersHelper is Test { } } + /// function to initialize the invalid owners + /// @param numberOwners number of invalid owners to initialize function initInvalidOnwers(uint256 numberOwners) internal { invalidPrivateKeyOwners = new uint256[](numberOwners); for (uint256 i = 0; i < numberOwners; i++) { @@ -48,10 +54,14 @@ contract SignersHelper is Test { } } + /// function to get the owners + /// @return amount of owners initialized function getOwnersUsed() public view returns (uint256) { return countUsed; } + /// function to update the count of owners + /// @param used amount of owners used function updateCount(uint256 used) public { countUsed = used; } diff --git a/test/helpers/SkipGnosisSafeHelper.t.sol b/test/helpers/SkipGnosisSafeHelper.t.sol index 72f5757..da0767c 100644 --- a/test/helpers/SkipGnosisSafeHelper.t.sol +++ b/test/helpers/SkipGnosisSafeHelper.t.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.15; import "./GnosisSafeHelper.t.sol"; import "./KeyperModuleHelper.t.sol"; import {KeyperModule} from "../../src/KeyperModule.sol"; -// Helper contract handling deployment Gnosis Safe contracts +// Helper contract handling deployment Gnosis Safe contracts contract SkipGnosisSafeHelper is GnosisSafeHelper, KeyperModuleHelper { GnosisSafeProxyFactory public proxyFactory; GnosisSafe public gnosisSafeContract; @@ -52,6 +52,7 @@ contract SkipGnosisSafeHelper is GnosisSafeHelper, KeyperModuleHelper { return address(gnosisSafe); } + /// @notice Setup the environment for the test function start() public { proxyFactory = GnosisSafeProxyFactory(vm.envAddress("PROXY_FACTORY_ADDRESS")); @@ -59,11 +60,17 @@ contract SkipGnosisSafeHelper is GnosisSafeHelper, KeyperModuleHelper { GnosisSafe(payable(vm.envAddress("MASTER_COPY_ADDRESS"))); } + /// function to set the KeyperModule address + /// @param keyperModule address of the KeyperModule function setKeyperModule(address keyperModule) public override { keyperModuleAddr = keyperModule; keyper = KeyperModule(keyperModuleAddr); } + /// function to create a new Keyper Safe + /// @param numberOwners amount of owners to initialize + /// @param threshold amount of signatures required to execute a transaction + /// @return address of the new Keyper Safe function newKeyperSafe(uint256 numberOwners, uint256 threshold) public override @@ -109,6 +116,9 @@ contract SkipGnosisSafeHelper is GnosisSafeHelper, KeyperModuleHelper { return address(gnosisSafe); } + /// function to create a new Safe Proxy + /// @param initializer bytes data to initialize the Safe + /// @return address of the new Safe Proxy function newSafeProxy(bytes memory initializer) public returns (address) { safeProxy = proxyFactory.createProxyWithNonce( address(gnosisSafeContract), initializer, nonce diff --git a/test/helpers/SkipSetupEnv.s.sol b/test/helpers/SkipSetupEnv.s.sol index 7d98271..721be0c 100644 --- a/test/helpers/SkipSetupEnv.s.sol +++ b/test/helpers/SkipSetupEnv.s.sol @@ -10,6 +10,7 @@ import {KeyperRoles} from "../../src/KeyperRoles.sol"; import {KeyperGuard} from "../../src/KeyperGuard.sol"; import {SafeMath} from "@openzeppelin/utils/math/SafeMath.sol"; +/// Script to setup the environment contract SkipSetupEnv is Script, SkipGnosisSafeHelper { using SafeMath for uint256;