From eed36d3102957236c53164d06ff67000a5ee2e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8r=E2=88=82=C2=A1?= Date: Tue, 7 Jan 2025 16:57:05 +0100 Subject: [PATCH] Adding permission and new tests --- src/factory/TaikoDaoFactory.sol | 9 ++ test/integration/TaikoDaoFactory.t.sol | 199 ++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 1 deletion(-) diff --git a/src/factory/TaikoDaoFactory.sol b/src/factory/TaikoDaoFactory.sol index c47e369..cf47543 100644 --- a/src/factory/TaikoDaoFactory.sol +++ b/src/factory/TaikoDaoFactory.sol @@ -209,6 +209,9 @@ contract TaikoDaoFactory { // Revoke the remporary permission dao.revoke(address(signerList), address(this), UPDATE_SIGNER_LIST_SETTINGS_PERMISSION_ID); } + + // Make the DAO own the signers list + dao.grant(address(signerList), address(dao), UPDATE_SIGNER_LIST_SETTINGS_PERMISSION_ID); } function prepareMultisig(DAO dao, SignerList signerList) @@ -219,6 +222,8 @@ contract TaikoDaoFactory { PluginRepo pluginRepo = PluginRepoFactory(settings.pluginRepoFactory).createPluginRepoWithFirstVersion( settings.stdMultisigEnsDomain, address(settings.multisigPluginSetup), address(dao), " ", " " ); + dao.grant(address(pluginRepo), address(dao), pluginRepo.MAINTAINER_PERMISSION_ID()); + // UPGRADE_REPO_PERMISSION_ID can be granted eventually bytes memory settingsData = settings.multisigPluginSetup.encodeInstallationParameters( Multisig.MultisigSettings( @@ -250,6 +255,8 @@ contract TaikoDaoFactory { PluginRepo pluginRepo = PluginRepoFactory(settings.pluginRepoFactory).createPluginRepoWithFirstVersion( settings.emergencyMultisigEnsDomain, address(settings.emergencyMultisigPluginSetup), address(dao), " ", " " ); + dao.grant(address(pluginRepo), address(dao), pluginRepo.MAINTAINER_PERMISSION_ID()); + // UPGRADE_REPO_PERMISSION_ID can be granted eventually bytes memory settingsData = settings.emergencyMultisigPluginSetup.encodeInstallationParameters( EmergencyMultisig.MultisigSettings( @@ -284,6 +291,8 @@ contract TaikoDaoFactory { " ", " " ); + dao.grant(address(pluginRepo), address(dao), pluginRepo.MAINTAINER_PERMISSION_ID()); + // UPGRADE_REPO_PERMISSION_ID can be granted eventually // Plugin settings bytes memory settingsData; diff --git a/test/integration/TaikoDaoFactory.t.sol b/test/integration/TaikoDaoFactory.t.sol index 6870b7c..8b84d1b 100644 --- a/test/integration/TaikoDaoFactory.t.sol +++ b/test/integration/TaikoDaoFactory.t.sol @@ -22,7 +22,7 @@ import {createProxyAndCall} from "../../src/helpers/proxy.sol"; import {MultisigPluginSetup} from "../../src/setup/MultisigPluginSetup.sol"; import {EmergencyMultisigPluginSetup} from "../../src/setup/EmergencyMultisigPluginSetup.sol"; import {OptimisticTokenVotingPluginSetup} from "../../src/setup/OptimisticTokenVotingPluginSetup.sol"; -import {SignerList} from "../../src/SignerList.sol"; +import {SignerList, UPDATE_SIGNER_LIST_SETTINGS_PERMISSION_ID} from "../../src/SignerList.sol"; contract TaikoDaoFactoryTest is AragonTest { function test_ShouldStoreTheSettings_1() public { @@ -781,6 +781,203 @@ contract TaikoDaoFactoryTest is AragonTest { ); } + function test_TheDaoShouldOwnTheSignerList() public { + DAO tempMgmtDao = DAO( + payable( + createProxyAndCall( + address(DAO_BASE), abi.encodeCall(DAO.initialize, ("", address(this), address(0x0), "")) + ) + ) + ); + + GovernanceERC20Mock tokenAddress = new GovernanceERC20Mock(address(tempMgmtDao)); + TaikoL1Mock taikoL1ContractAddress = new TaikoL1Mock(); + address taikoBridgeAddress = address(0x5678); + address[] memory multisigMembers = new address[](16); + for (uint256 i = 0; i < 16; i++) { + multisigMembers[i] = address(uint160(i + 1)); + } + + MultisigPluginSetup multisigPluginSetup = new MultisigPluginSetup(); + EmergencyMultisigPluginSetup emergencyMultisigPluginSetup = new EmergencyMultisigPluginSetup(); + GovernanceERC20.MintSettings memory mintSettings = + GovernanceERC20.MintSettings({receivers: new address[](0), amounts: new uint256[](0)}); + OptimisticTokenVotingPluginSetup optimisticTokenVotingPluginSetup = new OptimisticTokenVotingPluginSetup( + new GovernanceERC20(tempMgmtDao, "", "", mintSettings), new GovernanceWrappedERC20(tokenAddress, "", "") + ); + + PluginRepoFactory pRefoFactory; + MockPluginSetupProcessor psp; + { + MockPluginRepoRegistry pRepoRegistry = new MockPluginRepoRegistry(); + pRefoFactory = new PluginRepoFactory(PluginRepoRegistry(address(pRepoRegistry))); + + address[] memory setups = new address[](3); + // adding in reverse order (stack) + setups[2] = address(multisigPluginSetup); + setups[1] = address(emergencyMultisigPluginSetup); + setups[0] = address(optimisticTokenVotingPluginSetup); + psp = new MockPluginSetupProcessor(setups); + } + MockDaoFactory daoFactory = new MockDaoFactory(psp); + + TaikoDaoFactory.DeploymentSettings memory creationSettings = TaikoDaoFactory.DeploymentSettings({ + // Taiko contract settings + tokenAddress: tokenAddress, + taikoL1ContractAddress: address(taikoL1ContractAddress), // address + taikoBridgeAddress: taikoBridgeAddress, // address + timelockPeriod: 9 days, // uint32 + l2InactivityPeriod: 27 minutes, // uint32 + l2AggregationGracePeriod: 3 days, // uint32 + skipL2: true, + // Voting settings + minVetoRatio: 456_000, // uint32 + minStdProposalDuration: 21 days, // uint32 + minStdApprovals: 9, // uint16 + minEmergencyApprovals: 15, // uint16 + // OSx contracts + osxDaoFactory: address(daoFactory), + pluginSetupProcessor: PluginSetupProcessor(address(psp)), // PluginSetupProcessor + pluginRepoFactory: PluginRepoFactory(address(pRefoFactory)), // PluginRepoFactory + // Plugin setup's + multisigPluginSetup: multisigPluginSetup, + emergencyMultisigPluginSetup: emergencyMultisigPluginSetup, + optimisticTokenVotingPluginSetup: optimisticTokenVotingPluginSetup, + // Multisig + multisigMembers: multisigMembers, // address[] + multisigExpirationPeriod: 22 days, + // ENS + stdMultisigEnsDomain: "multisig", // string + emergencyMultisigEnsDomain: "eMultisig", // string + optimisticTokenVotingEnsDomain: "optimistic" // string + }); + + // Deploy + TaikoDaoFactory factory = new TaikoDaoFactory(creationSettings); + + factory.deployOnce(); + TaikoDaoFactory.Deployment memory deployment = factory.getDeployment(); + + bool hasPerm = deployment.dao.hasPermission( + address(deployment.signerList), + address(deployment.dao), + UPDATE_SIGNER_LIST_SETTINGS_PERMISSION_ID, + bytes("") + ); + assertEq(hasPerm, true, "DAO should have UPDATE_SIGNER_LIST_SETTINGS_PERMISSION_ID"); + } + + function test_AllContractsPointToTheDao() public { + DAO tempMgmtDao = DAO( + payable( + createProxyAndCall( + address(DAO_BASE), abi.encodeCall(DAO.initialize, ("", address(this), address(0x0), "")) + ) + ) + ); + + GovernanceERC20Mock tokenAddress = new GovernanceERC20Mock(address(tempMgmtDao)); + TaikoL1Mock taikoL1ContractAddress = new TaikoL1Mock(); + address taikoBridgeAddress = address(0x5678); + address[] memory multisigMembers = new address[](16); + for (uint256 i = 0; i < 16; i++) { + multisigMembers[i] = address(uint160(i + 1)); + } + + MultisigPluginSetup multisigPluginSetup = new MultisigPluginSetup(); + EmergencyMultisigPluginSetup emergencyMultisigPluginSetup = new EmergencyMultisigPluginSetup(); + GovernanceERC20.MintSettings memory mintSettings = + GovernanceERC20.MintSettings({receivers: new address[](0), amounts: new uint256[](0)}); + OptimisticTokenVotingPluginSetup optimisticTokenVotingPluginSetup = new OptimisticTokenVotingPluginSetup( + new GovernanceERC20(tempMgmtDao, "", "", mintSettings), new GovernanceWrappedERC20(tokenAddress, "", "") + ); + + PluginRepoFactory pRefoFactory; + MockPluginSetupProcessor psp; + { + MockPluginRepoRegistry pRepoRegistry = new MockPluginRepoRegistry(); + pRefoFactory = new PluginRepoFactory(PluginRepoRegistry(address(pRepoRegistry))); + + address[] memory setups = new address[](3); + // adding in reverse order (stack) + setups[2] = address(multisigPluginSetup); + setups[1] = address(emergencyMultisigPluginSetup); + setups[0] = address(optimisticTokenVotingPluginSetup); + psp = new MockPluginSetupProcessor(setups); + } + MockDaoFactory daoFactory = new MockDaoFactory(psp); + + TaikoDaoFactory.DeploymentSettings memory creationSettings = TaikoDaoFactory.DeploymentSettings({ + // Taiko contract settings + tokenAddress: tokenAddress, + taikoL1ContractAddress: address(taikoL1ContractAddress), // address + taikoBridgeAddress: taikoBridgeAddress, // address + timelockPeriod: 9 days, // uint32 + l2InactivityPeriod: 27 minutes, // uint32 + l2AggregationGracePeriod: 3 days, // uint32 + skipL2: true, + // Voting settings + minVetoRatio: 456_000, // uint32 + minStdProposalDuration: 21 days, // uint32 + minStdApprovals: 9, // uint16 + minEmergencyApprovals: 15, // uint16 + // OSx contracts + osxDaoFactory: address(daoFactory), + pluginSetupProcessor: PluginSetupProcessor(address(psp)), // PluginSetupProcessor + pluginRepoFactory: PluginRepoFactory(address(pRefoFactory)), // PluginRepoFactory + // Plugin setup's + multisigPluginSetup: multisigPluginSetup, + emergencyMultisigPluginSetup: emergencyMultisigPluginSetup, + optimisticTokenVotingPluginSetup: optimisticTokenVotingPluginSetup, + // Multisig + multisigMembers: multisigMembers, // address[] + multisigExpirationPeriod: 22 days, + // ENS + stdMultisigEnsDomain: "multisig", // string + emergencyMultisigEnsDomain: "eMultisig", // string + optimisticTokenVotingEnsDomain: "optimistic" // string + }); + + // Deploy + TaikoDaoFactory factory = new TaikoDaoFactory(creationSettings); + + factory.deployOnce(); + TaikoDaoFactory.Deployment memory deployment = factory.getDeployment(); + + // DAO linked + assertEq(address(deployment.multisigPlugin.dao()), address(deployment.dao), "Incorrect DAO address"); + assertEq(address(deployment.emergencyMultisigPlugin.dao()), address(deployment.dao), "Incorrect DAO address"); + assertEq( + address(deployment.optimisticTokenVotingPlugin.dao()), address(deployment.dao), "Incorrect DAO address" + ); + assertEq(address(deployment.signerList.dao()), address(deployment.dao), "Incorrect DAO address"); + + // DAO with permission + bool hasPerm = deployment.dao.hasPermission( + address(deployment.multisigPluginRepo), + address(deployment.dao), + deployment.multisigPluginRepo.MAINTAINER_PERMISSION_ID(), + bytes("") + ); + assertEq(hasPerm, true, "Incorrect hasPermission"); + + hasPerm = deployment.dao.hasPermission( + address(deployment.emergencyMultisigPluginRepo), + address(deployment.dao), + deployment.emergencyMultisigPluginRepo.MAINTAINER_PERMISSION_ID(), + bytes("") + ); + assertEq(hasPerm, true, "Incorrect hasPermission"); + + hasPerm = deployment.dao.hasPermission( + address(deployment.optimisticTokenVotingPluginRepo), + address(deployment.dao), + deployment.optimisticTokenVotingPluginRepo.MAINTAINER_PERMISSION_ID(), + bytes("") + ); + assertEq(hasPerm, true, "Incorrect hasPermission"); + } + function test_MultipleDeploysDoNothing() public { DAO tempMgmtDao = DAO( payable(