From c61a28f8eeff3fdac306a8cbf7c09b46e5085f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8r=E2=88=82=C2=A1?= Date: Tue, 14 May 2024 17:01:04 +0200 Subject: [PATCH] Optimistic WIP --- script/Deploy.s.sol | 19 +- script/_alternate_deploy.s.sol | 2 +- src/OptimisticTokenVotingPlugin.sol | 2 +- src/interfaces/ITaikoEssentialContract.sol | 2 +- .../OptimisticTokenVotingPluginSetup.sol | 126 ++-- test/OptimisticTokenVotingPlugin.t.sol | 420 ++++------- test/OptimisticTokenVotingPluginSetup.t.sol | 709 +++++------------- test/base/AragonTest.sol | 42 +- test/mocks/TaikoL1Mock.sol | 36 + 9 files changed, 486 insertions(+), 872 deletions(-) create mode 100644 test/mocks/TaikoL1Mock.sol diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 4edccf9..c5cb701 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -21,6 +21,7 @@ import {PluginSetupProcessor} from "@aragon/osx/framework/plugin/setup/PluginSet import {IDAO} from "@aragon/osx/core/dao/IDAO.sol"; import {DAO} from "@aragon/osx/core/dao/DAO.sol"; import {createERC1967Proxy} from "@aragon/osx/utils/Proxy.sol"; +import {ITaikoEssentialContract} from "../src/interfaces/ITaikoEssentialContract.sol"; contract Deploy is Script { DAO immutable daoImplementation; @@ -32,6 +33,8 @@ contract Deploy is Script { address immutable tokenAddress; address[] multisigMembers; + address immutable taikoL1; + address immutable taikoBridge; uint64 immutable minStdProposalDelay; // Minimum delay of proposals on the optimistic voting plugin uint16 immutable minStdApprovals; uint16 immutable minEmergencyApprovals; @@ -48,6 +51,8 @@ contract Deploy is Script { pluginSetupProcessor = PluginSetupProcessor(vm.envAddress("PLUGIN_SETUP_PROCESSOR")); pluginRepoFactory = vm.envAddress("PLUGIN_REPO_FACTORY"); tokenAddress = vm.envAddress("TOKEN_ADDRESS"); + taikoL1 = vm.envAddress("TAIKO_L1_ADDRESS"); + taikoBridge = vm.envAddress("TAIKO_BRIDGE_ADDRESS"); minStdProposalDelay = uint64(vm.envUint("MIN_STD_PROPOSAL_DELAY")); minStdApprovals = uint16(vm.envUint("MIN_STD_APPROVALS")); @@ -221,9 +226,8 @@ contract Deploy is Script { { OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory votingSettings = OptimisticTokenVotingPlugin .OptimisticGovernanceSettings( - 200000, // minVetoRatio - 20% - 0, // minDuration (the condition will enforce it) - 0 // minProposerVotingPower + 200_000, // minVetoRatio - 20% + 0 // minDuration (the condition will enforce it) ); OptimisticTokenVotingPluginSetup.TokenSettings memory tokenSettings = @@ -233,7 +237,14 @@ contract Deploy is Script { GovernanceERC20.MintSettings(new address[](0), new uint256[](0)); settingsData = pluginSetup.encodeInstallationParams( - votingSettings, tokenSettings, mintSettings, minStdProposalDelay, stdProposer, emergencyProposer + votingSettings, + tokenSettings, + mintSettings, + ITaikoEssentialContract(taikoL1), + taikoBridge, + minStdProposalDelay, + stdProposer, + emergencyProposer ); } diff --git a/script/_alternate_deploy.s.sol b/script/_alternate_deploy.s.sol index 44b1262..ce62243 100644 --- a/script/_alternate_deploy.s.sol +++ b/script/_alternate_deploy.s.sol @@ -123,7 +123,7 @@ contract Deploy is Script { ) public view returns (DAOFactory.PluginSettings[] memory pluginSettings) { OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory votingSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings(200000, 60 * 60 * 24 * 6, 0); + .OptimisticGovernanceSettings(200000, 60 * 60 * 24 * 6); OptimisticTokenVotingPluginSetup.TokenSettings memory tokenSettings = OptimisticTokenVotingPluginSetup .TokenSettings(tokenAddress, "", ""); diff --git a/src/OptimisticTokenVotingPlugin.sol b/src/OptimisticTokenVotingPlugin.sol index 1b249b3..b6e0f7d 100644 --- a/src/OptimisticTokenVotingPlugin.sol +++ b/src/OptimisticTokenVotingPlugin.sol @@ -14,7 +14,7 @@ import {ProposalUpgradeable} from "@aragon/osx/core/plugin/proposal/ProposalUpgr import {PluginUUPSUpgradeable} from "@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol"; import {RATIO_BASE, _applyRatioCeiled, RatioOutOfBounds} from "@aragon/osx/plugins/utils/Ratio.sol"; import {IDAO} from "@aragon/osx/core/dao/IDAO.sol"; -import {IEssentialContract as ITaikoEssentialContract} from "./interfaces/ITaikoEssentialContract.sol"; +import {ITaikoEssentialContract} from "./interfaces/ITaikoEssentialContract.sol"; // import {EssentialContract as TaikoEssentialContract} from "@taikoxyz/taiko-mono/common/EssentialContract.sol"; uint64 constant L2_AGGREGATION_PERIOD = 3 days; diff --git a/src/interfaces/ITaikoEssentialContract.sol b/src/interfaces/ITaikoEssentialContract.sol index 3890642..1a8d478 100644 --- a/src/interfaces/ITaikoEssentialContract.sol +++ b/src/interfaces/ITaikoEssentialContract.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.17; -interface IEssentialContract { +interface ITaikoEssentialContract { /// @notice Pauses the contract. function pause() external; diff --git a/src/setup/OptimisticTokenVotingPluginSetup.sol b/src/setup/OptimisticTokenVotingPluginSetup.sol index bb18feb..440b5e1 100644 --- a/src/setup/OptimisticTokenVotingPluginSetup.sol +++ b/src/setup/OptimisticTokenVotingPluginSetup.sol @@ -17,6 +17,8 @@ import {GovernanceWrappedERC20} from "@aragon/osx/token/ERC20/governance/Governa import {IGovernanceWrappedERC20} from "@aragon/osx/token/ERC20/governance/IGovernanceWrappedERC20.sol"; import {OptimisticTokenVotingPlugin} from "../OptimisticTokenVotingPlugin.sol"; import {StandardProposalCondition} from "../conditions/StandardProposalCondition.sol"; +import {ITaikoEssentialContract} from "../interfaces/ITaikoEssentialContract.sol"; +// import {EssentialContract as TaikoEssentialContract} from "@taikoxyz/taiko-mono/common/EssentialContract.sol"; /// @title OptimisticTokenVotingPluginSetup /// @author Aragon Association - 2022-2023 @@ -28,8 +30,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { using ERC165Checker for address; /// @notice The address of the `OptimisticTokenVotingPlugin` base contract. - OptimisticTokenVotingPlugin - private immutable optimisticTokenVotingPluginBase; + OptimisticTokenVotingPlugin private immutable optimisticTokenVotingPluginBase; /// @notice The address of the `GovernanceERC20` base contract. address public immutable governanceERC20Base; @@ -62,31 +63,26 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { /// @notice The contract constructor deploying the plugin implementation contract and receiving the governance token base contracts to clone from. /// @param _governanceERC20Base The base `GovernanceERC20` contract to create clones from. /// @param _governanceWrappedERC20Base The base `GovernanceWrappedERC20` contract to create clones from. - constructor( - GovernanceERC20 _governanceERC20Base, - GovernanceWrappedERC20 _governanceWrappedERC20Base - ) { + constructor(GovernanceERC20 _governanceERC20Base, GovernanceWrappedERC20 _governanceWrappedERC20Base) { optimisticTokenVotingPluginBase = new OptimisticTokenVotingPlugin(); governanceERC20Base = address(_governanceERC20Base); governanceWrappedERC20Base = address(_governanceWrappedERC20Base); } /// @inheritdoc IPluginSetup - function prepareInstallation( - address _dao, - bytes calldata _installParameters - ) + function prepareInstallation(address _dao, bytes calldata _installParameters) external returns (address plugin, PreparedSetupData memory preparedSetupData) { // Decode `_installParameters` to extract the params needed for deploying and initializing `OptimisticTokenVoting` plugin, // and the required helpers ( - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings - memory votingSettings, + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory votingSettings, TokenSettings memory tokenSettings, // only used for GovernanceERC20 (when token is not passed) GovernanceERC20.MintSettings memory mintSettings, + ITaikoEssentialContract _taikoL1, + address _taikoBridge, uint64 stdProposalMinDelay, address stdProposer, address emergencyProposer @@ -113,30 +109,23 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { // If token supports none of them // it's simply ERC20 which gets checked by _isERC20 // Currently, not a satisfiable check. - (!supportedIds[0] && !supportedIds[1] && !supportedIds[2]) || + (!supportedIds[0] && !supportedIds[1] && !supportedIds[2]) // If token supports IERC20, but neither // IVotes nor IGovernanceWrappedERC20, it needs wrapping. - (supportedIds[0] && !supportedIds[1] && !supportedIds[2]) + || (supportedIds[0] && !supportedIds[1] && !supportedIds[2]) ) { token = governanceWrappedERC20Base.clone(); // User already has a token. We need to wrap it in // GovernanceWrappedERC20 in order to make the token // include governance functionality. GovernanceWrappedERC20(token).initialize( - IERC20Upgradeable(tokenSettings.addr), - tokenSettings.name, - tokenSettings.symbol + IERC20Upgradeable(tokenSettings.addr), tokenSettings.name, tokenSettings.symbol ); } } else { // Clone a `GovernanceERC20`. token = governanceERC20Base.clone(); - GovernanceERC20(token).initialize( - IDAO(_dao), - tokenSettings.name, - tokenSettings.symbol, - mintSettings - ); + GovernanceERC20(token).initialize(IDAO(_dao), tokenSettings.name, tokenSettings.symbol, mintSettings); } helpers[0] = token; @@ -146,15 +135,13 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { address(optimisticTokenVotingPluginBase), abi.encodeCall( OptimisticTokenVotingPlugin.initialize, - (IDAO(_dao), votingSettings, IVotesUpgradeable(token)) + (IDAO(_dao), votingSettings, IVotesUpgradeable(token), _taikoL1, _taikoBridge) ) ); // Prepare permissions - PermissionLib.MultiTargetPermission[] - memory permissions = new PermissionLib.MultiTargetPermission[]( - tokenSettings.addr != address(0) ? 5 : 6 - ); + PermissionLib.MultiTargetPermission[] memory permissions = + new PermissionLib.MultiTargetPermission[](tokenSettings.addr != address(0) ? 5 : 6); // Request the permissions to be granted @@ -164,8 +151,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { where: plugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: optimisticTokenVotingPluginBase - .UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() + permissionId: optimisticTokenVotingPluginBase.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() }); // The DAO can upgrade the plugin implementation @@ -174,8 +160,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { where: plugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: optimisticTokenVotingPluginBase - .UPGRADE_PLUGIN_PERMISSION_ID() + permissionId: optimisticTokenVotingPluginBase.UPGRADE_PLUGIN_PERMISSION_ID() }); // The plugin can make the DAO execute actions @@ -188,10 +173,8 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { }); { // Deploy the Std proposal condition - StandardProposalCondition stdProposalCondition = new StandardProposalCondition( - address(_dao), - stdProposalMinDelay - ); + StandardProposalCondition stdProposalCondition = + new StandardProposalCondition(address(_dao), stdProposalMinDelay); // Proposer plugins can create proposals permissions[3] = PermissionLib.MultiTargetPermission({ @@ -199,8 +182,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { where: plugin, who: stdProposer, condition: address(stdProposalCondition), - permissionId: optimisticTokenVotingPluginBase - .PROPOSER_PERMISSION_ID() + permissionId: optimisticTokenVotingPluginBase.PROPOSER_PERMISSION_ID() }); } permissions[4] = PermissionLib.MultiTargetPermission({ @@ -208,8 +190,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { where: plugin, who: emergencyProposer, condition: PermissionLib.NO_CONDITION, - permissionId: optimisticTokenVotingPluginBase - .PROPOSER_PERMISSION_ID() + permissionId: optimisticTokenVotingPluginBase.PROPOSER_PERMISSION_ID() }); if (tokenSettings.addr == address(0x0)) { @@ -228,10 +209,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { } /// @inheritdoc IPluginSetup - function prepareUninstallation( - address _dao, - SetupPayload calldata _payload - ) + function prepareUninstallation(address _dao, SetupPayload calldata _payload) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) @@ -248,13 +226,9 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { bool[] memory supportedIds = _getTokenInterfaceIds(token); - bool isGovernanceERC20 = supportedIds[0] && - supportedIds[1] && - !supportedIds[2]; + bool isGovernanceERC20 = supportedIds[0] && supportedIds[1] && !supportedIds[2]; - permissions = new PermissionLib.MultiTargetPermission[]( - isGovernanceERC20 ? 4 : 3 - ); + permissions = new PermissionLib.MultiTargetPermission[](isGovernanceERC20 ? 4 : 3); // Set permissions to be Revoked. permissions[0] = PermissionLib.MultiTargetPermission({ @@ -262,8 +236,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { where: _payload.plugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: optimisticTokenVotingPluginBase - .UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() + permissionId: optimisticTokenVotingPluginBase.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID() }); permissions[1] = PermissionLib.MultiTargetPermission({ @@ -271,8 +244,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { where: _payload.plugin, who: _dao, condition: PermissionLib.NO_CONDITION, - permissionId: optimisticTokenVotingPluginBase - .UPGRADE_PLUGIN_PERMISSION_ID() + permissionId: optimisticTokenVotingPluginBase.UPGRADE_PLUGIN_PERMISSION_ID() }); permissions[2] = PermissionLib.MultiTargetPermission({ @@ -306,38 +278,39 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { /// @notice Encodes the given installation parameters into a byte array function encodeInstallationParams( - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings - calldata _votingSettings, + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings calldata _votingSettings, TokenSettings calldata _tokenSettings, // only used for GovernanceERC20 (when a token is not passed) GovernanceERC20.MintSettings calldata _mintSettings, + ITaikoEssentialContract _taikoL1, + address _taikoBridge, uint64 _stdProposalMinDelay, address _stdProposer, address _emergencyProposer ) external pure returns (bytes memory) { - return - abi.encode( - _votingSettings, - _tokenSettings, - _mintSettings, - _stdProposalMinDelay, - _stdProposer, - _emergencyProposer - ); + return abi.encode( + _votingSettings, + _tokenSettings, + _mintSettings, + _taikoL1, + _taikoBridge, + _stdProposalMinDelay, + _stdProposer, + _emergencyProposer + ); } /// @notice Decodes the given byte array into the original installation parameters - function decodeInstallationParams( - bytes memory _data - ) + function decodeInstallationParams(bytes memory _data) public pure returns ( - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings - memory votingSettings, + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory votingSettings, TokenSettings memory tokenSettings, // only used for GovernanceERC20 (when token is not passed) GovernanceERC20.MintSettings memory mintSettings, + ITaikoEssentialContract _taikoL1, + address _taikoBridge, uint64 _stdProposalMinDelay, address _stdProposer, address _emergencyProposer @@ -347,6 +320,8 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { votingSettings, tokenSettings, mintSettings, + _taikoL1, + _taikoBridge, _stdProposalMinDelay, _stdProposer, _emergencyProposer @@ -356,6 +331,8 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { OptimisticTokenVotingPlugin.OptimisticGovernanceSettings, TokenSettings, GovernanceERC20.MintSettings, + ITaikoEssentialContract, + address, uint64, address, address @@ -366,9 +343,7 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { /// @notice Retrieves the interface identifiers supported by the token contract. /// @dev It is crucial to verify if the provided token address represents a valid contract before using the below. /// @param token The token address - function _getTokenInterfaceIds( - address token - ) private view returns (bool[] memory) { + function _getTokenInterfaceIds(address token) private view returns (bool[] memory) { bytes4[] memory interfaceIds = new bytes4[](3); interfaceIds[0] = type(IERC20Upgradeable).interfaceId; interfaceIds[1] = type(IVotesUpgradeable).interfaceId; @@ -380,9 +355,8 @@ contract OptimisticTokenVotingPluginSetup is PluginSetup { /// @dev It's important to first check whether token is a contract prior to this call. /// @param token The token address function _isERC20(address token) private view returns (bool) { - (bool success, bytes memory data) = token.staticcall( - abi.encodeCall(IERC20Upgradeable.balanceOf, (address(this))) - ); + (bool success, bytes memory data) = + token.staticcall(abi.encodeCall(IERC20Upgradeable.balanceOf, (address(this)))); return success && data.length == 0x20; } } diff --git a/test/OptimisticTokenVotingPlugin.t.sol b/test/OptimisticTokenVotingPlugin.t.sol index abdd69e..886270f 100644 --- a/test/OptimisticTokenVotingPlugin.t.sol +++ b/test/OptimisticTokenVotingPlugin.t.sol @@ -12,6 +12,7 @@ import {IMembership} from "@aragon/osx/core/plugin/membership/IMembership.sol"; import {RATIO_BASE, RatioOutOfBounds} from "@aragon/osx/plugins/utils/Ratio.sol"; import {DaoUnauthorized} from "@aragon/osx/core/utils/auth.sol"; import {ERC20VotesMock} from "./mocks/ERC20VotesMock.sol"; +import {ITaikoEssentialContract} from "../src/interfaces/ITaikoEssentialContract.sol"; import {IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol"; import {IERC1822ProxiableUpgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol"; @@ -21,6 +22,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { DAO public dao; OptimisticTokenVotingPlugin public plugin; ERC20VotesMock votingToken; + ITaikoEssentialContract taikoL1; // Events from external contracts event Initialized(uint8 version); @@ -35,53 +37,48 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ); event VetoCast(uint256 indexed proposalId, address indexed voter, uint256 votingPower); event ProposalExecuted(uint256 indexed proposalId); - event OptimisticGovernanceSettingsUpdated(uint32 minVetoRatio, uint64 minDuration, uint256 minProposerVotingPower); + event OptimisticGovernanceSettingsUpdated(uint32 minVetoRatio, uint64 minDuration); event Upgraded(address indexed implementation); function setUp() public { vm.startPrank(alice); - (dao, plugin, votingToken) = makeDaoWithOptimisticTokenVoting(alice); + (dao, plugin, votingToken, taikoL1) = makeDaoWithOptimisticTokenVoting(alice); } // Initialize function test_InitializeRevertsIfInitialized() public { OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); vm.expectRevert(bytes("Initializable: contract is already initialized")); - plugin.initialize(dao, settings, votingToken); + plugin.initialize(dao, settings, votingToken, taikoL1, taikoBridge); } function test_InitializeSetsTheProperValues() public { // Initial settings OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); - assertEq(plugin.totalVotingPower(block.number - 1), 10 ether, "Incorrect token supply"); + assertEq(plugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); assertEq(plugin.minVetoRatio(), uint32(RATIO_BASE / 10), "Incorrect minVetoRatio"); assertEq(plugin.minDuration(), 10 days, "Incorrect minDuration"); - assertEq(plugin.minProposerVotingPower(), 0, "Incorrect minProposerVotingPower"); // Different minVetoRatio settings.minVetoRatio = uint32(RATIO_BASE / 5); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); assertEq(plugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); @@ -91,7 +88,9 @@ contract OptimisticTokenVotingPluginTest is AragonTest { plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); assertEq(plugin.minDuration(), 25 days, "Incorrect minDuration"); @@ -106,29 +105,17 @@ contract OptimisticTokenVotingPluginTest is AragonTest { plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); - assertEq(plugin.totalVotingPower(block.number - 1), 10 ether, "Incorrect token supply"); - - // Different minProposerVotingPower - settings.minProposerVotingPower = 1 ether; - plugin = OptimisticTokenVotingPlugin( - createProxyAndCall( - address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) - ) - ); - assertEq(plugin.minProposerVotingPower(), 1 ether, "Incorrect minProposerVotingPower"); + assertEq(plugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); } function test_InitializeEmitsEvent() public { OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); vm.expectEmit(); emit Initialized(uint8(1)); @@ -136,7 +123,9 @@ contract OptimisticTokenVotingPluginTest is AragonTest { plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); } @@ -186,16 +175,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // Deploy a new plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); @@ -205,40 +192,38 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_TotalVotingPowerReturnsTheRightSupply() public { assertEq( - plugin.totalVotingPower(block.number - 1), + plugin.totalVotingPower(block.timestamp - 1), votingToken.getPastTotalSupply(block.number - 1), "Incorrect total voting power" ); - assertEq(plugin.totalVotingPower(block.number - 1), 10 ether, "Incorrect total voting power"); + assertEq(plugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect total voting power"); // New token votingToken = ERC20VotesMock( createProxyAndCall(address(VOTING_TOKEN_BASE), abi.encodeCall(ERC20VotesMock.initialize, ())) ); votingToken.mint(alice, 15 ether); - vm.roll(block.number + 1); + blockForward(1); // Deploy a new plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); assertEq( - plugin.totalVotingPower(block.number - 1), + plugin.totalVotingPower(block.timestamp - 1), votingToken.getPastTotalSupply(block.number - 1), "Incorrect total voting power" ); - assertEq(plugin.totalVotingPower(block.number - 1), 15 ether, "Incorrect total voting power"); + assertEq(plugin.totalVotingPower(block.timestamp - 1), 15 ether, "Incorrect total voting power"); } function test_MinVetoRatioReturnsTheRightValue() public { @@ -246,16 +231,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // New plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); @@ -267,50 +250,20 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // New plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 25 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 25 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); assertEq(plugin.minDuration(), 25 days, "Incorrect minDuration"); } - function test_MinProposerVotingPowerReturnsTheRightValue() public { - assertEq(plugin.minProposerVotingPower(), 0, "Incorrect minProposerVotingPower"); - - // New token - votingToken = ERC20VotesMock( - createProxyAndCall(address(VOTING_TOKEN_BASE), abi.encodeCall(ERC20VotesMock.initialize, ())) - ); - votingToken.mint(alice, 10 ether); - vm.roll(block.number + 1); - - // Deploy a new plugin instance - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 1 ether - }); - - plugin = OptimisticTokenVotingPlugin( - createProxyAndCall( - address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) - ) - ); - - assertEq(plugin.minProposerVotingPower(), 1 ether, "Incorrect minProposerVotingPower"); - } - function test_TokenHoldersAreMembers() public { assertEq(plugin.isMember(alice), true, "Alice should not be a member"); assertEq(plugin.isMember(bob), false, "Bob should not be a member"); @@ -322,20 +275,18 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ); votingToken.mint(alice, 10 ether); votingToken.mint(bob, 5 ether); - vm.roll(block.number + 1); + blockForward(1); // Deploy a new plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 1 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); @@ -375,29 +326,6 @@ contract OptimisticTokenVotingPluginTest is AragonTest { assertEq(proposalId1 + 1, proposalId2, "Should be +1"); } - function test_CreateProposalRevertsWhenTheCallerOwnsLessThanTheMinimumVotingPower() public { - vm.stopPrank(); - vm.startPrank(alice); - - IDAO.Action[] memory actions = new IDAO.Action[](0); - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 5 ether - }); - dao.grant(address(plugin), bob, plugin.PROPOSER_PERMISSION_ID()); - dao.grant(address(plugin), alice, plugin.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID()); - plugin.updateOptimisticGovernanceSettings(newSettings); - - vm.stopPrank(); - vm.startPrank(bob); - - // Bob holds no tokens - vm.expectRevert(abi.encodeWithSelector(OptimisticTokenVotingPlugin.ProposalCreationForbidden.selector, bob)); - plugin.createProposal("", actions, 0, 0, 0); - } - function test_CreateProposalRevertsIfThereIsNoVotingPower() public { vm.stopPrank(); vm.startPrank(alice); @@ -410,15 +338,13 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // Deploy a new plugin instance IDAO.Action[] memory actions = new IDAO.Action[](0); OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); dao.grant(address(plugin), alice, plugin.PROPOSER_PERMISSION_ID()); @@ -439,7 +365,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { } function test_CreateProposalRevertsIfStartDateIsInThePast() public { - vm.warp(10); // timestamp = 10 + setTime(10); // timestamp = 10 IDAO.Action[] memory actions = new IDAO.Action[](0); vm.expectRevert( @@ -450,7 +376,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { } function test_CreateProposalRevertsIfEndDateIsEarlierThanMinDuration() public { - vm.warp(500); // timestamp = 500 + setTime(500); // timestamp = 500 IDAO.Action[] memory actions = new IDAO.Action[](0); uint32 startDate = 1000; @@ -463,7 +389,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { } function test_CreateProposalStartsNowWhenStartDateIsZero() public { - vm.warp(500); + setTime(500); IDAO.Action[] memory actions = new IDAO.Action[](0); uint32 startDate = 0; @@ -474,7 +400,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { } function test_CreateProposalEndsAfterMinDurationWhenEndDateIsZero() public { - vm.warp(500); + setTime(500); IDAO.Action[] memory actions = new IDAO.Action[](0); uint32 startDate = 0; @@ -490,26 +416,24 @@ contract OptimisticTokenVotingPluginTest is AragonTest { uint256 proposalId = plugin.createProposal("", actions, 0, 0, 0); (,, OptimisticTokenVotingPlugin.ProposalParameters memory parameters,,,) = plugin.getProposal(proposalId); - assertEq(parameters.minVetoVotingPower, 1 ether, "Incorrect minVetoVotingPower"); + assertEq(parameters.minVetoRatio, 100_000, "Incorrect minVetoRatio"); // Now with a different value OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); dao.grant(address(plugin), alice, plugin.PROPOSER_PERMISSION_ID()); proposalId = plugin.createProposal("", actions, 0, 0, 0); (,, parameters,,,) = plugin.getProposal(proposalId); - assertEq(parameters.minVetoVotingPower, 2 ether, "Incorrect minVetoVotingPower"); + assertEq(parameters.minVetoRatio, 200_000, "Incorrect minVetoRatio"); } function test_CreateProposalReturnsTheProposalId() public { @@ -552,7 +476,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { } function test_GetProposalReturnsTheRightValues() public { - vm.warp(500); + setTime(500); uint32 startDate = 600; uint32 endDate = startDate + 15 days; @@ -568,7 +492,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { assertEq(open0, false, "The proposal should not be open"); // Move on - vm.warp(startDate); + setTime(startDate); ( bool open, @@ -583,18 +507,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { assertEq(executed, false, "The proposal should not be executed"); assertEq(parameters.startDate, startDate, "Incorrect startDate"); assertEq(parameters.endDate, endDate, "Incorrect endDate"); - assertEq(parameters.snapshotBlock, 1, "Incorrect snapshotBlock"); - assertEq( - parameters.minVetoVotingPower, - plugin.totalVotingPower(block.number - 1) / 10, - "Incorrect minVetoVotingPower" - ); + assertEq(parameters.snapshotTimestamp, 499, "Incorrect snapshotTimestamp"); + assertEq(parameters.minVetoRatio, plugin.totalVotingPower(block.timestamp - 1) / 10, "Incorrect minVetoRatio"); assertEq(vetoTally, 0, "The tally should be zero"); assertEq(actualActions.length, 1, "Actions should have one item"); assertEq(actualFailSafeBitmap, failSafeBitmap, "Incorrect failsafe bitmap"); // Move on - vm.warp(endDate); + setTime(endDate); (bool open1,,,,,) = plugin.getProposal(proposalId); assertEq(open1, false, "The proposal should not be open anymore"); @@ -618,7 +538,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_CanVetoReturnsFalseWhenAProposalHasNotStarted() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); @@ -627,17 +547,17 @@ contract OptimisticTokenVotingPluginTest is AragonTest { assertEq(plugin.canVeto(proposalId, alice), false, "Alice should not be able to veto"); // Started - vm.warp(startDate + 1); + setTime(startDate + 1); assertEq(plugin.canVeto(proposalId, alice), true, "Alice should be able to veto"); } function test_CanVetoReturnsFalseWhenAVoterAlreadyVetoed() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); plugin.veto(proposalId); @@ -647,23 +567,23 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_CanVetoReturnsFalseWhenAVoterAlreadyEnded() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(endDate + 1); + setTime(endDate + 1); assertEq(plugin.canVeto(proposalId, alice), false, "Alice should not be able to veto"); } function test_CanVetoReturnsFalseWhenNoVotingPower() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); // Alice owns tokens assertEq(plugin.canVeto(proposalId, alice), true, "Alice should be able to veto"); @@ -674,11 +594,11 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_CanVetoReturnsTrueOtherwise() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); assertEq(plugin.canVeto(proposalId, alice), true, "Alice should be able to veto"); } @@ -687,7 +607,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_VetoRevertsWhenAProposalDoesntExist() public { vm.roll(10); uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); @@ -704,7 +624,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_VetoRevertsWhenAProposalHasNotStarted() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); @@ -717,18 +637,18 @@ contract OptimisticTokenVotingPluginTest is AragonTest { assertEq(plugin.hasVetoed(proposalId, alice), false, "Alice should not have vetoed"); // Started - vm.warp(startDate + 1); + setTime(startDate + 1); plugin.veto(proposalId); assertEq(plugin.hasVetoed(proposalId, alice), true, "Alice should have vetoed"); } function test_VetoRevertsWhenAVoterAlreadyVetoed() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); assertEq(plugin.hasVetoed(proposalId, alice), false, "Alice should not have vetoed"); plugin.veto(proposalId); @@ -744,11 +664,11 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_VetoRevertsWhenAVoterAlreadyEnded() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(endDate + 1); + setTime(endDate + 1); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.ProposalVetoingForbidden.selector, proposalId, alice) @@ -759,12 +679,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_VetoRevertsWhenNoVotingPower() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); vm.stopPrank(); vm.startPrank(bob); @@ -786,11 +706,11 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_VetoRegistersAVetoForTheTokenHolderAndIncreasesTheTally() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); (,,, uint256 tally1,,) = plugin.getProposal(proposalId); assertEq(tally1, 0, "Tally should be zero"); @@ -804,11 +724,11 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_VetoEmitsAnEvent() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); vm.expectEmit(); emit VetoCast(proposalId, alice, 10 ether); @@ -818,11 +738,11 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // Has vetoed function test_HasVetoedReturnsTheRightValues() public { uint64 startDate = 50; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, 0); - vm.warp(startDate + 1); + setTime(startDate + 1); assertEq(plugin.hasVetoed(proposalId, alice), false, "Alice should not have vetoed"); plugin.veto(proposalId); @@ -833,14 +753,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_CanExecuteReturnsFalseWhenNotEnded() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); assertEq(plugin.canExecute(proposalId), false, "The proposal shouldn't be executable"); - vm.warp(startDate + 1); + setTime(startDate + 1); assertEq(plugin.canExecute(proposalId), false, "The proposal shouldn't be executable"); plugin.veto(proposalId); @@ -851,19 +771,19 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_CanExecuteReturnsFalseWhenDefeated() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); assertEq(plugin.canExecute(proposalId), false, "The proposal shouldn't be executable"); - vm.warp(startDate + 1); + setTime(startDate + 1); plugin.veto(proposalId); assertEq(plugin.canExecute(proposalId), false, "The proposal shouldn't be executable yet"); - vm.warp(endDate + 1); + setTime(endDate + 1); assertEq(plugin.canExecute(proposalId), false, "The proposal shouldn't be executable"); } @@ -871,12 +791,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_CanExecuteReturnsFalseWhenAlreadyExecuted() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(endDate + 1); + setTime(endDate + 1); assertEq(plugin.canExecute(proposalId), true, "The proposal should be executable"); plugin.execute(proposalId); @@ -887,18 +807,18 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_CanExecuteReturnsTrueOtherwise() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); assertEq(plugin.canExecute(proposalId), false, "The proposal shouldn't be executable"); - vm.warp(startDate + 1); + setTime(startDate + 1); assertEq(plugin.canExecute(proposalId), false, "The proposal shouldn't be executable yet"); - vm.warp(endDate + 1); + setTime(endDate + 1); assertEq(plugin.canExecute(proposalId), true, "The proposal should be executable"); } @@ -923,20 +843,18 @@ contract OptimisticTokenVotingPluginTest is AragonTest { vm.startPrank(randomWallet); votingToken.delegate(randomWallet); - vm.roll(block.number + 1); + blockForward(1); // Deploy a new plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32((RATIO_BASE * 25) / 100), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32((RATIO_BASE * 25) / 100), minDuration: 10 days}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); @@ -949,12 +867,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(startDate + 1); + setTime(startDate + 1); assertEq(plugin.isMinVetoRatioReached(proposalId), false, "The veto threshold shouldn't be met"); // Alice vetoes 24% @@ -983,7 +901,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_ExecuteRevertsWhenNotEnded() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); @@ -993,14 +911,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ); plugin.execute(proposalId); - vm.warp(startDate + 1); + setTime(startDate + 1); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.ProposalExecutionForbidden.selector, proposalId) ); plugin.execute(proposalId); - vm.warp(endDate); + setTime(endDate); plugin.execute(proposalId); (, bool executed,,,,) = plugin.getProposal(proposalId); @@ -1010,12 +928,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_ExecuteRevertsWhenDefeated() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(startDate + 1); + setTime(startDate + 1); plugin.veto(proposalId); @@ -1024,7 +942,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ); plugin.execute(proposalId); - vm.warp(endDate + 1); + setTime(endDate + 1); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.ProposalExecutionForbidden.selector, proposalId) @@ -1038,12 +956,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_ExecuteRevertsWhenAlreadyExecuted() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(endDate + 1); + setTime(endDate + 1); plugin.execute(proposalId); @@ -1062,12 +980,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_ExecuteSucceedsOtherwise() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(endDate + 1); + setTime(endDate + 1); plugin.execute(proposalId); } @@ -1075,12 +993,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_ExecuteMarksTheProposalAsExecuted() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(endDate + 1); + setTime(endDate + 1); plugin.execute(proposalId); @@ -1091,12 +1009,12 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_ExecuteEmitsAnEvent() public { uint64 startDate = 50; uint64 endDate = startDate + 10 days; - vm.warp(startDate - 1); + setTime(startDate - 1); IDAO.Action[] memory actions = new IDAO.Action[](0); uint256 proposalId = plugin.createProposal("ipfs://", actions, 0, startDate, endDate); - vm.warp(endDate + 1); + setTime(endDate + 1); vm.expectEmit(); emit ProposalExecuted(proposalId); @@ -1106,11 +1024,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // Update settings function test_UpdateOptimisticGovernanceSettingsRevertsWhenNoPermission() public { OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 15 days, - minProposerVotingPower: 1 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days}); vm.expectRevert( abi.encodeWithSelector( DaoUnauthorized.selector, @@ -1130,8 +1044,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { function test_UpdateOptimisticGovernanceSettingsRevertsWhenTheMinVetoRatioIsZero() public { dao.grant(address(plugin), alice, plugin.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID()); - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({minVetoRatio: 0, minDuration: 10 days, minProposerVotingPower: 0 ether}); + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({minVetoRatio: 0, minDuration: 10 days}); vm.expectRevert(abi.encodeWithSelector(RatioOutOfBounds.selector, 1, 0)); plugin.updateOptimisticGovernanceSettings(newSettings); } @@ -1140,11 +1054,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { dao.grant(address(plugin), alice, plugin.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID()); OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE + 1), - minDuration: 10 days, - minProposerVotingPower: 0 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE + 1), minDuration: 10 days}); vm.expectRevert(abi.encodeWithSelector(RatioOutOfBounds.selector, RATIO_BASE, uint32(RATIO_BASE + 1))); plugin.updateOptimisticGovernanceSettings(newSettings); } @@ -1156,11 +1066,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { dao.grant(address(plugin), alice, plugin.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID()); OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 4 days - 1, - minProposerVotingPower: 0 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 4 days - 1}); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 4 days, 4 days - 1) ); @@ -1169,8 +1075,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // 2 newSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 hours, - minProposerVotingPower: 0 ether + minDuration: 10 hours }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 4 days, 10 hours) @@ -1180,8 +1085,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // 3 newSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 0, - minProposerVotingPower: 0 ether + minDuration: 0 ether }); vm.expectRevert(abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 4 days, 0)); plugin.updateOptimisticGovernanceSettings(newSettings); @@ -1191,11 +1095,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { dao.grant(address(plugin), alice, plugin.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID()); OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 365 days + 1, - minProposerVotingPower: 0 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 365 days + 1 ether}); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 365 days, 365 days + 1) ); @@ -1204,8 +1104,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // 2 newSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 500 days, - minProposerVotingPower: 0 ether + minDuration: 500 days }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 365 days, 500 days) @@ -1215,8 +1114,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { // 3 newSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 1000 days, - minProposerVotingPower: 0 ether + minDuration: 1000 days }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 365 days, 1000 days) @@ -1228,64 +1126,50 @@ contract OptimisticTokenVotingPluginTest is AragonTest { dao.grant(address(plugin), alice, plugin.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID()); OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 15 days, - minProposerVotingPower: 1 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days}); vm.expectEmit(); - emit OptimisticGovernanceSettingsUpdated({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 15 days, - minProposerVotingPower: 1 ether - }); + emit OptimisticGovernanceSettingsUpdated({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days}); plugin.updateOptimisticGovernanceSettings(newSettings); } function test_GovernanceSettingsReturnsTheRightValues() public { - (uint32 minVetoRatio, uint64 minDuration, uint256 minProposerVotingPower) = plugin.governanceSettings(); + (uint32 minVetoRatio, uint64 minDuration) = plugin.governanceSettings(); assertEq(minVetoRatio, uint32(RATIO_BASE / 10)); assertEq(minDuration, 10 days); - assertEq(minProposerVotingPower, 0); // Deploy a new plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 2), - minDuration: 0, - minProposerVotingPower: 1234 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 2), minDuration: 0}); plugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, newSettings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, newSettings, votingToken, taikoL1, taikoBridge) + ) ) ); - (minVetoRatio, minDuration, minProposerVotingPower) = plugin.governanceSettings(); + (minVetoRatio, minDuration) = plugin.governanceSettings(); assertEq(minVetoRatio, uint32(RATIO_BASE / 2)); assertEq(minDuration, 0); - assertEq(minProposerVotingPower, 1234); // updated settings dao.grant(address(plugin), alice, plugin.UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION_ID()); newSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 15 days, - minProposerVotingPower: 5 ether + minDuration: 15 days }); plugin.updateOptimisticGovernanceSettings(newSettings); - (minVetoRatio, minDuration, minProposerVotingPower) = plugin.governanceSettings(); + (minVetoRatio, minDuration) = plugin.governanceSettings(); assertEq(minVetoRatio, uint32(RATIO_BASE / 5)); assertEq(minDuration, 15 days); - assertEq(minProposerVotingPower, 5 ether); } // Upgrade plugin @@ -1309,11 +1193,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { address _newImplementation = address(new OptimisticTokenVotingPlugin()); OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 15 days, - minProposerVotingPower: 1 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days}); vm.expectRevert( abi.encodeWithSelector( @@ -1352,11 +1232,7 @@ contract OptimisticTokenVotingPluginTest is AragonTest { emit Upgraded(_newImplementation); OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 15 days, - minProposerVotingPower: 1 ether - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days}); plugin.upgradeToAndCall( _newImplementation, abi.encodeCall(OptimisticTokenVotingPlugin.updateOptimisticGovernanceSettings, (settings)) diff --git a/test/OptimisticTokenVotingPluginSetup.t.sol b/test/OptimisticTokenVotingPluginSetup.t.sol index d7a5f86..9cdb02b 100644 --- a/test/OptimisticTokenVotingPluginSetup.t.sol +++ b/test/OptimisticTokenVotingPluginSetup.t.sol @@ -14,6 +14,7 @@ import {IPluginSetup} from "@aragon/osx/framework/plugin/setup/PluginSetup.sol"; import {PermissionLib} from "@aragon/osx/core/permission/PermissionLib.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {ERC20Mock} from "./mocks/ERC20Mock.sol"; +import {ITaikoEssentialContract} from "../src/interfaces/ITaikoEssentialContract.sol"; contract OptimisticTokenVotingPluginSetupTest is Test { OptimisticTokenVotingPluginSetup public pluginSetup; @@ -26,6 +27,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { OptimisticTokenVotingPlugin.OptimisticGovernanceSettings votingSettings; OptimisticTokenVotingPluginSetup.TokenSettings tokenSettings; GovernanceERC20.MintSettings mintSettings; + ITaikoEssentialContract taikoL1; + address taikoBridge; uint64 stdProposalMinDuration; address stdProposer; address emergencyProposer; @@ -37,54 +40,33 @@ contract OptimisticTokenVotingPluginSetupTest is Test { function setUp() public { if (address(governanceERC20Base) == address(0x0)) { // Base - GovernanceERC20.MintSettings memory _mintSettings = GovernanceERC20 - .MintSettings(new address[](0), new uint256[](0)); - governanceERC20Base = new GovernanceERC20( - IDAO(address(0x0)), - "", - "", - _mintSettings - ); + GovernanceERC20.MintSettings memory _mintSettings = + GovernanceERC20.MintSettings(new address[](0), new uint256[](0)); + governanceERC20Base = new GovernanceERC20(IDAO(address(0x0)), "", "", _mintSettings); // Base - governanceWrappedERC20Base = new GovernanceWrappedERC20( - IERC20Upgradeable(address(0x0)), - "", - "" - ); + governanceWrappedERC20Base = new GovernanceWrappedERC20(IERC20Upgradeable(address(0x0)), "", ""); dao = DAO( payable( - createProxyAndCall( - address(daoBase), - abi.encodeCall( - DAO.initialize, - ("", alice, address(0x0), "") - ) - ) + createProxyAndCall(address(daoBase), abi.encodeCall(DAO.initialize, ("", alice, address(0x0), ""))) ) ); } - pluginSetup = new OptimisticTokenVotingPluginSetup( - governanceERC20Base, - governanceWrappedERC20Base - ); + pluginSetup = new OptimisticTokenVotingPluginSetup(governanceERC20Base, governanceWrappedERC20Base); // Default params - votingSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 5 days, - minProposerVotingPower: 0 - }); + votingSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 10), + minDuration: 5 days + }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceERC20Base), name: "Wrapped Token", symbol: "wTK" }); - mintSettings = GovernanceERC20.MintSettings({ - receivers: new address[](0), - amounts: new uint256[](0) - }); + mintSettings = GovernanceERC20.MintSettings({receivers: new address[](0), amounts: new uint256[](0)}); + taikoL1 = ITaikoEssentialContract(address(0x66666666)); + taikoBridge = address(0x55555555); stdProposalMinDuration = 10 days; stdProposer = address(0x1234567890); emergencyProposer = address(0x2345678901); @@ -96,35 +78,37 @@ contract OptimisticTokenVotingPluginSetupTest is Test { votingSettings, tokenSettings, mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory expected = + hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } function test_ShouldEncodeInstallationParams_1() public { // Custom 1 - votingSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 60 * 60 * 24 * 5, - minProposerVotingPower: 123456 - }); + votingSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 5), + minDuration: 60 * 60 * 24 * 5 + }); bytes memory output = pluginSetup.encodeInstallationParams( votingSettings, tokenSettings, mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - bytes - memory expected = hex"0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000001e240000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory expected = + hex"0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000001e240000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -139,13 +123,15 @@ contract OptimisticTokenVotingPluginSetupTest is Test { votingSettings, tokenSettings, mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000000000000000000000000000000000000000005678000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001057726170706564204e657720436f696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004774e434e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory expected = + hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000000000000000000000000000000000000000005678000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001057726170706564204e657720436f696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004774e434e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -156,21 +142,20 @@ contract OptimisticTokenVotingPluginSetupTest is Test { uint256[] memory amounts = new uint256[](1); amounts[0] = 1234567890; - mintSettings = GovernanceERC20.MintSettings({ - receivers: receivers, - amounts: amounts - }); + mintSettings = GovernanceERC20.MintSettings({receivers: receivers, amounts: amounts}); bytes memory output = pluginSetup.encodeInstallationParams( votingSettings, tokenSettings, mintSettings, - stdProposalMinDuration, + ITaikoEssentialContract(address(0x1234)), + address(0x5678), // taikoBridge + 5 days, // stdProposalMinDuration stdProposer, emergencyProposer ); - bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000006789000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d2"; + bytes memory expected = + hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000006789000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d2"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -182,23 +167,23 @@ contract OptimisticTokenVotingPluginSetupTest is Test { votingSettings, tokenSettings, mintSettings, - stdProposalMinDuration, + ITaikoEssentialContract(address(0x1111)), + address(0x2222), // taikoBridge + 15 days, // stdProposalMinDuration stdProposer, emergencyProposer ); - bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000000056789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory expected = + hex"00000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000000056789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } function test_ShouldDecodeInstallationParams_1() public { - votingSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 4), - minDuration: 10 days, - minProposerVotingPower: 55555555 - }); + votingSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 4), + minDuration: 10 days + }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceWrappedERC20Base), name: "Super wToken", @@ -210,115 +195,67 @@ contract OptimisticTokenVotingPluginSetupTest is Test { uint256[] memory amounts = new uint256[](2); amounts[0] = 2000; amounts[1] = 5000; - mintSettings = GovernanceERC20.MintSettings({ - receivers: receivers, - amounts: amounts - }); + mintSettings = GovernanceERC20.MintSettings({receivers: receivers, amounts: amounts}); stdProposalMinDuration = 6 days; stdProposer = address(0x3456); emergencyProposer = address(0x7890); bytes memory _installationParams = pluginSetup.encodeInstallationParams( - votingSettings, - tokenSettings, - // only used for GovernanceERC20 (when a token is not passed) - mintSettings, - stdProposalMinDuration, - stdProposer, - emergencyProposer - ); + votingSettings, + tokenSettings, + // only used for GovernanceERC20 (when a token is not passed) + mintSettings, + ITaikoEssentialContract(address(0x9999)), + address(0xaaaa), + stdProposalMinDuration, + stdProposer, + emergencyProposer + ); // Decode ( - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings - memory _votingSettings, - OptimisticTokenVotingPluginSetup.TokenSettings - memory _tokenSettings, + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory _votingSettings, + OptimisticTokenVotingPluginSetup.TokenSettings memory _tokenSettings, GovernanceERC20.MintSettings memory _mintSettings, + ITaikoEssentialContract _taikoL1, + address _taikoBridge, uint64 _stdMinDuration, address _stdProposer, address _emergencyProposer ) = pluginSetup.decodeInstallationParams(_installationParams); // Voting - assertEq( - _votingSettings.minVetoRatio, - uint32(RATIO_BASE / 4), - "Incorrect ratio" - ); - assertEq( - _votingSettings.minDuration, - 10 days, - "Incorrect min duration" - ); - assertEq( - _votingSettings.minProposerVotingPower, - 55555555, - "Incorrect min voting power" - ); + assertEq(_votingSettings.minVetoRatio, uint32(RATIO_BASE / 4), "Incorrect ratio"); + assertEq(_votingSettings.minDuration, 10 days, "Incorrect min duration"); // Token - assertEq( - _tokenSettings.addr, - address(governanceWrappedERC20Base), - "Incorrect token address" - ); - assertEq( - _tokenSettings.name, - "Super wToken", - "Incorrect token address" - ); + assertEq(_tokenSettings.addr, address(governanceWrappedERC20Base), "Incorrect token address"); + assertEq(_tokenSettings.name, "Super wToken", "Incorrect token address"); assertEq(_tokenSettings.symbol, "SwTK", "Incorrect token address"); // Mint - assertEq( - _mintSettings.receivers.length, - 2, - "Incorrect receivers.length" - ); - assertEq( - _mintSettings.receivers[0], - address(0x1234), - "Incorrect receivers[0]" - ); - assertEq( - _mintSettings.receivers[1], - address(0x5678), - "Incorrect receivers[1]" - ); + assertEq(_mintSettings.receivers.length, 2, "Incorrect receivers.length"); + assertEq(_mintSettings.receivers[0], address(0x1234), "Incorrect receivers[0]"); + assertEq(_mintSettings.receivers[1], address(0x5678), "Incorrect receivers[1]"); assertEq(_mintSettings.amounts.length, 2, "Incorrect amounts.length"); assertEq(_mintSettings.amounts[0], 2000, "Incorrect amounts[0]"); assertEq(_mintSettings.amounts[1], 5000, "Incorrect amounts[1]"); // Proposals - assertEq( - _stdMinDuration, - stdProposalMinDuration, - "Incorrect stdMinDuration" - ); + assertEq(_stdMinDuration, stdProposalMinDuration, "Incorrect stdMinDuration"); assertEq(_stdProposer, stdProposer, "Incorrect standard proposer"); - assertEq( - _emergencyProposer, - emergencyProposer, - "Incorrect emergency proposer" - ); + assertEq(_emergencyProposer, emergencyProposer, "Incorrect emergency proposer"); assertEq(_stdMinDuration, 6 days, "Incorrect stdMinDuration"); assertEq(stdProposer, address(0x3456), "Incorrect stdProposer"); - assertEq( - emergencyProposer, - address(0x7890), - "Incorrect emergencyProposer" - ); + assertEq(emergencyProposer, address(0x7890), "Incorrect emergencyProposer"); } function test_ShouldDecodeInstallationParams_2() public { - votingSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 5), - minDuration: 12 days, - minProposerVotingPower: 44444444 - }); + votingSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 5), + minDuration: 12 days + }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceWrappedERC20Base), name: "Mega wToken", @@ -334,88 +271,50 @@ contract OptimisticTokenVotingPluginSetupTest is Test { amounts[1] = 2000; amounts[2] = 3000; amounts[3] = 4000; - mintSettings = GovernanceERC20.MintSettings({ - receivers: receivers, - amounts: amounts - }); + mintSettings = GovernanceERC20.MintSettings({receivers: receivers, amounts: amounts}); stdProposalMinDuration = 9 days; stdProposer = address(0x6666); emergencyProposer = address(0x8888); bytes memory _installationParams = pluginSetup.encodeInstallationParams( - votingSettings, - tokenSettings, - // only used for GovernanceERC20 (when a token is not passed) - mintSettings, - stdProposalMinDuration, - stdProposer, - emergencyProposer - ); + votingSettings, + tokenSettings, + // only used for GovernanceERC20 (when a token is not passed) + mintSettings, + ITaikoEssentialContract(address(0xbbbb)), + address(0xcccc), + stdProposalMinDuration, + stdProposer, + emergencyProposer + ); // Decode ( - OptimisticTokenVotingPlugin.OptimisticGovernanceSettings - memory _votingSettings, - OptimisticTokenVotingPluginSetup.TokenSettings - memory _tokenSettings, + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory _votingSettings, + OptimisticTokenVotingPluginSetup.TokenSettings memory _tokenSettings, GovernanceERC20.MintSettings memory _mintSettings, + ITaikoEssentialContract _taikoL1, + address _taikoBridge, uint64 _stdMinDuration, address _stdProposer, address _emergencyProposer ) = pluginSetup.decodeInstallationParams(_installationParams); // Voting - assertEq( - _votingSettings.minVetoRatio, - uint32(RATIO_BASE / 5), - "Incorrect ratio" - ); - assertEq( - _votingSettings.minDuration, - 12 days, - "Incorrect min duration" - ); - assertEq( - _votingSettings.minProposerVotingPower, - 44444444, - "Incorrect min voting power" - ); + assertEq(_votingSettings.minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect ratio"); + assertEq(_votingSettings.minDuration, 12 days, "Incorrect min duration"); // Token - assertEq( - _tokenSettings.addr, - address(governanceWrappedERC20Base), - "Incorrect token address" - ); + assertEq(_tokenSettings.addr, address(governanceWrappedERC20Base), "Incorrect token address"); assertEq(_tokenSettings.name, "Mega wToken", "Incorrect token address"); assertEq(_tokenSettings.symbol, "MwTK", "Incorrect token address"); // Mint - assertEq( - _mintSettings.receivers.length, - 4, - "Incorrect receivers.length" - ); - assertEq( - _mintSettings.receivers[0], - address(0x1111), - "Incorrect receivers[0]" - ); - assertEq( - _mintSettings.receivers[1], - address(0x2222), - "Incorrect receivers[1]" - ); - assertEq( - _mintSettings.receivers[2], - address(0x3333), - "Incorrect receivers[2]" - ); - assertEq( - _mintSettings.receivers[3], - address(0x4444), - "Incorrect receivers[3]" - ); + assertEq(_mintSettings.receivers.length, 4, "Incorrect receivers.length"); + assertEq(_mintSettings.receivers[0], address(0x1111), "Incorrect receivers[0]"); + assertEq(_mintSettings.receivers[1], address(0x2222), "Incorrect receivers[1]"); + assertEq(_mintSettings.receivers[2], address(0x3333), "Incorrect receivers[2]"); + assertEq(_mintSettings.receivers[3], address(0x4444), "Incorrect receivers[3]"); assertEq(_mintSettings.amounts.length, 4, "Incorrect amounts.length"); assertEq(_mintSettings.amounts[0], 1000, "Incorrect amounts[0]"); assertEq(_mintSettings.amounts[1], 2000, "Incorrect amounts[1]"); @@ -423,50 +322,32 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_mintSettings.amounts[3], 4000, "Incorrect amounts[3]"); // Proposal - assertEq( - _stdMinDuration, - stdProposalMinDuration, - "Incorrect stdMinDuration" - ); + assertEq(_stdMinDuration, stdProposalMinDuration, "Incorrect stdMinDuration"); assertEq(_stdProposer, stdProposer, "Incorrect standard proposer"); - assertEq( - _emergencyProposer, - emergencyProposer, - "Incorrect emergency proposer" - ); + assertEq(_emergencyProposer, emergencyProposer, "Incorrect emergency proposer"); assertEq(_stdMinDuration, 9 days, "Incorrect stdMinDuration"); assertEq(stdProposer, address(0x6666), "Incorrect stdProposer"); - assertEq( - emergencyProposer, - address(0x8888), - "Incorrect emergencyProposer" - ); + assertEq(emergencyProposer, address(0x8888), "Incorrect emergencyProposer"); } - function test_PrepareInstallationReturnsTheProperPermissions_Default() - public - { + function test_PrepareInstallationReturnsTheProperPermissions_Default() public { bytes memory installationParams = pluginSetup.encodeInstallationParams( votingSettings, tokenSettings, // only used for GovernanceERC20 (when a token is not passed) mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - address _plugin, - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (address _plugin, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); - assertEq( - _plugin != address(0), - true, - "Plugin address should not be zero" - ); + assertEq(_plugin != address(0), true, "Plugin address should not be zero"); assertEq(_preparedSetupData.helpers.length, 1, "One helper expected"); assertEq( _preparedSetupData.permissions.length, @@ -495,10 +376,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[1].where, _plugin); assertEq(_preparedSetupData.permissions[1].who, address(dao)); assertEq(_preparedSetupData.permissions[1].condition, address(0)); - assertEq( - _preparedSetupData.permissions[1].permissionId, - keccak256("UPGRADE_PLUGIN_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[1].permissionId, keccak256("UPGRADE_PLUGIN_PERMISSION")); // 3 assertEq( uint256(_preparedSetupData.permissions[2].operation), @@ -508,10 +386,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[2].where, address(dao)); assertEq(_preparedSetupData.permissions[2].who, _plugin); assertEq(_preparedSetupData.permissions[2].condition, address(0)); - assertEq( - _preparedSetupData.permissions[2].permissionId, - keccak256("EXECUTE_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[2].permissionId, keccak256("EXECUTE_PERMISSION")); // proposer 1 assertEq( uint256(_preparedSetupData.permissions[3].operation), @@ -521,10 +396,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[3].where, _plugin); assertEq(_preparedSetupData.permissions[3].who, address(stdProposer)); assertNotEq(_preparedSetupData.permissions[3].condition, address(0)); - assertEq( - _preparedSetupData.permissions[3].permissionId, - keccak256("PROPOSER_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[3].permissionId, keccak256("PROPOSER_PERMISSION")); // proposer 2 assertEq( uint256(_preparedSetupData.permissions[4].operation), @@ -532,28 +404,18 @@ contract OptimisticTokenVotingPluginSetupTest is Test { "Incorrect operation" ); assertEq(_preparedSetupData.permissions[4].where, _plugin); - assertEq( - _preparedSetupData.permissions[4].who, - address(emergencyProposer) - ); + assertEq(_preparedSetupData.permissions[4].who, address(emergencyProposer)); assertEq(_preparedSetupData.permissions[4].condition, address(0)); - assertEq( - _preparedSetupData.permissions[4].permissionId, - keccak256("PROPOSER_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[4].permissionId, keccak256("PROPOSER_PERMISSION")); // no more: no minted token } - function test_PrepareInstallationReturnsTheProperPermissions_UseToken() - public - { - votingSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 4), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + function test_PrepareInstallationReturnsTheProperPermissions_UseToken() public { + votingSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 4), + minDuration: 10 days + }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceWrappedERC20Base), name: "", @@ -567,21 +429,17 @@ contract OptimisticTokenVotingPluginSetupTest is Test { tokenSettings, // only used for GovernanceERC20 (when a token is not passed) mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - address _plugin, - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (address _plugin, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); - assertEq( - _plugin != address(0), - true, - "Plugin address should not be zero" - ); + assertEq(_plugin != address(0), true, "Plugin address should not be zero"); assertEq(_preparedSetupData.helpers.length, 1, "One helper expected"); assertEq( _preparedSetupData.permissions.length, @@ -610,10 +468,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[1].where, _plugin); assertEq(_preparedSetupData.permissions[1].who, address(dao)); assertEq(_preparedSetupData.permissions[1].condition, address(0)); - assertEq( - _preparedSetupData.permissions[1].permissionId, - keccak256("UPGRADE_PLUGIN_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[1].permissionId, keccak256("UPGRADE_PLUGIN_PERMISSION")); // 3 assertEq( uint256(_preparedSetupData.permissions[2].operation), @@ -623,10 +478,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[2].where, address(dao)); assertEq(_preparedSetupData.permissions[2].who, _plugin); assertEq(_preparedSetupData.permissions[2].condition, address(0)); - assertEq( - _preparedSetupData.permissions[2].permissionId, - keccak256("EXECUTE_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[2].permissionId, keccak256("EXECUTE_PERMISSION")); // proposer 1 assertEq( uint256(_preparedSetupData.permissions[3].operation), @@ -636,10 +488,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[3].where, _plugin); assertEq(_preparedSetupData.permissions[3].who, address(stdProposer)); assertNotEq(_preparedSetupData.permissions[3].condition, address(0)); - assertEq( - _preparedSetupData.permissions[3].permissionId, - keccak256("PROPOSER_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[3].permissionId, keccak256("PROPOSER_PERMISSION")); // proposer 2 assertEq( uint256(_preparedSetupData.permissions[4].operation), @@ -647,28 +496,18 @@ contract OptimisticTokenVotingPluginSetupTest is Test { "Incorrect operation" ); assertEq(_preparedSetupData.permissions[4].where, _plugin); - assertEq( - _preparedSetupData.permissions[4].who, - address(emergencyProposer) - ); + assertEq(_preparedSetupData.permissions[4].who, address(emergencyProposer)); assertEq(_preparedSetupData.permissions[4].condition, address(0)); - assertEq( - _preparedSetupData.permissions[4].permissionId, - keccak256("PROPOSER_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[4].permissionId, keccak256("PROPOSER_PERMISSION")); // no more: no minted token } - function test_PrepareInstallationReturnsTheProperPermissions_MintToken() - public - { - votingSettings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 4), - minDuration: 10 days, - minProposerVotingPower: 4000 - }); + function test_PrepareInstallationReturnsTheProperPermissions_MintToken() public { + votingSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 4), + minDuration: 10 days + }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(0x0), name: "Wrapped Super New Token", @@ -680,10 +519,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { uint256[] memory amounts = new uint256[](2); amounts[0] = 2000; amounts[1] = 5000; - mintSettings = GovernanceERC20.MintSettings({ - receivers: receivers, - amounts: amounts - }); + mintSettings = GovernanceERC20.MintSettings({receivers: receivers, amounts: amounts}); stdProposer = address(0x3456); emergencyProposer = address(0x7890); @@ -692,21 +528,17 @@ contract OptimisticTokenVotingPluginSetupTest is Test { tokenSettings, // only used for GovernanceERC20 (when a token is not passed) mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - address _plugin, - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (address _plugin, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); - assertEq( - _plugin != address(0), - true, - "Plugin address should not be zero" - ); + assertEq(_plugin != address(0), true, "Plugin address should not be zero"); assertEq(_preparedSetupData.helpers.length, 1, "One helper expected"); assertEq( _preparedSetupData.permissions.length, @@ -735,10 +567,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[1].where, _plugin); assertEq(_preparedSetupData.permissions[1].who, address(dao)); assertEq(_preparedSetupData.permissions[1].condition, address(0)); - assertEq( - _preparedSetupData.permissions[1].permissionId, - keccak256("UPGRADE_PLUGIN_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[1].permissionId, keccak256("UPGRADE_PLUGIN_PERMISSION")); // 3 assertEq( uint256(_preparedSetupData.permissions[2].operation), @@ -748,10 +577,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[2].where, address(dao)); assertEq(_preparedSetupData.permissions[2].who, _plugin); assertEq(_preparedSetupData.permissions[2].condition, address(0)); - assertEq( - _preparedSetupData.permissions[2].permissionId, - keccak256("EXECUTE_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[2].permissionId, keccak256("EXECUTE_PERMISSION")); // proposer 1 assertEq( uint256(_preparedSetupData.permissions[3].operation), @@ -761,10 +587,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.permissions[3].where, _plugin); assertEq(_preparedSetupData.permissions[3].who, address(stdProposer)); assertNotEq(_preparedSetupData.permissions[3].condition, address(0)); - assertEq( - _preparedSetupData.permissions[3].permissionId, - keccak256("PROPOSER_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[3].permissionId, keccak256("PROPOSER_PERMISSION")); // proposer 2 assertEq( uint256(_preparedSetupData.permissions[4].operation), @@ -772,15 +595,9 @@ contract OptimisticTokenVotingPluginSetupTest is Test { "Incorrect operation" ); assertEq(_preparedSetupData.permissions[4].where, _plugin); - assertEq( - _preparedSetupData.permissions[4].who, - address(emergencyProposer) - ); + assertEq(_preparedSetupData.permissions[4].who, address(emergencyProposer)); assertEq(_preparedSetupData.permissions[4].condition, address(0)); - assertEq( - _preparedSetupData.permissions[4].permissionId, - keccak256("PROPOSER_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[4].permissionId, keccak256("PROPOSER_PERMISSION")); // minting assertEq( @@ -788,16 +605,10 @@ contract OptimisticTokenVotingPluginSetupTest is Test { uint256(PermissionLib.Operation.Grant), "Incorrect operation" ); - assertEq( - _preparedSetupData.permissions[5].where, - _preparedSetupData.helpers[0] - ); + assertEq(_preparedSetupData.permissions[5].where, _preparedSetupData.helpers[0]); assertEq(_preparedSetupData.permissions[5].who, address(dao)); assertEq(_preparedSetupData.permissions[5].condition, address(0)); - assertEq( - _preparedSetupData.permissions[5].permissionId, - keccak256("MINT_PERMISSION") - ); + assertEq(_preparedSetupData.permissions[5].permissionId, keccak256("MINT_PERMISSION")); } function test_PrepareUninstallationReturnsTheProperPermissions_1() public { @@ -806,228 +617,139 @@ contract OptimisticTokenVotingPluginSetupTest is Test { votingSettings, tokenSettings, mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - address _dummyPlugin, - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (address _dummyPlugin, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); - OptimisticTokenVotingPluginSetup.SetupPayload - memory _payload = IPluginSetup.SetupPayload({ - plugin: _dummyPlugin, - currentHelpers: _preparedSetupData.helpers, - data: hex"" - }); + OptimisticTokenVotingPluginSetup.SetupPayload memory _payload = + IPluginSetup.SetupPayload({plugin: _dummyPlugin, currentHelpers: _preparedSetupData.helpers, data: hex""}); // Check uninstall - PermissionLib.MultiTargetPermission[] - memory _permissionChanges = pluginSetup.prepareUninstallation( - address(dao), - _payload - ); + PermissionLib.MultiTargetPermission[] memory _permissionChanges = + pluginSetup.prepareUninstallation(address(dao), _payload); - assertEq( - _permissionChanges.length, - 4, - "Incorrect permission changes length" - ); + assertEq(_permissionChanges.length, 4, "Incorrect permission changes length"); // 1 assertEq( - uint256(_permissionChanges[0].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" + uint256(_permissionChanges[0].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); assertEq(_permissionChanges[0].where, _dummyPlugin); assertEq(_permissionChanges[0].who, address(dao)); assertEq(_permissionChanges[0].condition, address(0)); - assertEq( - _permissionChanges[0].permissionId, - keccak256("UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION") - ); + assertEq(_permissionChanges[0].permissionId, keccak256("UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION")); // 2 assertEq( - uint256(_permissionChanges[1].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" + uint256(_permissionChanges[1].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); assertEq(_permissionChanges[1].where, _dummyPlugin); assertEq(_permissionChanges[1].who, address(dao)); assertEq(_permissionChanges[1].condition, address(0)); - assertEq( - _permissionChanges[1].permissionId, - keccak256("UPGRADE_PLUGIN_PERMISSION") - ); + assertEq(_permissionChanges[1].permissionId, keccak256("UPGRADE_PLUGIN_PERMISSION")); // 3 assertEq( - uint256(_permissionChanges[2].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" + uint256(_permissionChanges[2].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); assertEq(_permissionChanges[2].where, address(dao)); assertEq(_permissionChanges[2].who, _dummyPlugin); assertEq(_permissionChanges[2].condition, address(0)); - assertEq( - _permissionChanges[2].permissionId, - keccak256("EXECUTE_PERMISSION") - ); + assertEq(_permissionChanges[2].permissionId, keccak256("EXECUTE_PERMISSION")); // minting 1 assertEq( - uint256(_permissionChanges[3].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" - ); - assertEq( - _permissionChanges[3].where, - address(governanceERC20Base), - "Incorrect where" + uint256(_permissionChanges[3].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); + assertEq(_permissionChanges[3].where, address(governanceERC20Base), "Incorrect where"); assertEq(_permissionChanges[3].who, address(dao), "Incorrect who"); - assertEq( - _permissionChanges[3].condition, - address(0), - "Incorrect condition" - ); - assertEq( - _permissionChanges[3].permissionId, - keccak256("MINT_PERMISSION"), - "Incorrect permission" - ); + assertEq(_permissionChanges[3].condition, address(0), "Incorrect condition"); + assertEq(_permissionChanges[3].permissionId, keccak256("MINT_PERMISSION"), "Incorrect permission"); } function test_PrepareUninstallationReturnsTheProperPermissions_2() public { // Prepare a dummy install - tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ - addr: address(0x0), - name: "Dummy Token", - symbol: "DTK" - }); + tokenSettings = + OptimisticTokenVotingPluginSetup.TokenSettings({addr: address(0x0), name: "Dummy Token", symbol: "DTK"}); bytes memory installationParams = pluginSetup.encodeInstallationParams( votingSettings, tokenSettings, mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - address _dummyPlugin, - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (address _dummyPlugin, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); - OptimisticTokenVotingPluginSetup.SetupPayload - memory _payload = IPluginSetup.SetupPayload({ - plugin: _dummyPlugin, - currentHelpers: _preparedSetupData.helpers, - data: hex"" - }); + OptimisticTokenVotingPluginSetup.SetupPayload memory _payload = + IPluginSetup.SetupPayload({plugin: _dummyPlugin, currentHelpers: _preparedSetupData.helpers, data: hex""}); // Check uninstall - PermissionLib.MultiTargetPermission[] - memory _permissionChanges = pluginSetup.prepareUninstallation( - address(dao), - _payload - ); + PermissionLib.MultiTargetPermission[] memory _permissionChanges = + pluginSetup.prepareUninstallation(address(dao), _payload); - assertEq( - _permissionChanges.length, - 4, - "Incorrect permission changes length" - ); + assertEq(_permissionChanges.length, 4, "Incorrect permission changes length"); // 1 assertEq( - uint256(_permissionChanges[0].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" + uint256(_permissionChanges[0].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); assertEq(_permissionChanges[0].where, _dummyPlugin); assertEq(_permissionChanges[0].who, address(dao)); assertEq(_permissionChanges[0].condition, address(0)); - assertEq( - _permissionChanges[0].permissionId, - keccak256("UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION") - ); + assertEq(_permissionChanges[0].permissionId, keccak256("UPDATE_OPTIMISTIC_GOVERNANCE_SETTINGS_PERMISSION")); // 2 assertEq( - uint256(_permissionChanges[1].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" + uint256(_permissionChanges[1].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); assertEq(_permissionChanges[1].where, _dummyPlugin); assertEq(_permissionChanges[1].who, address(dao)); assertEq(_permissionChanges[1].condition, address(0)); - assertEq( - _permissionChanges[1].permissionId, - keccak256("UPGRADE_PLUGIN_PERMISSION") - ); + assertEq(_permissionChanges[1].permissionId, keccak256("UPGRADE_PLUGIN_PERMISSION")); // 3 assertEq( - uint256(_permissionChanges[2].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" + uint256(_permissionChanges[2].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); assertEq(_permissionChanges[2].where, address(dao)); assertEq(_permissionChanges[2].who, _dummyPlugin); assertEq(_permissionChanges[2].condition, address(0)); - assertEq( - _permissionChanges[2].permissionId, - keccak256("EXECUTE_PERMISSION") - ); + assertEq(_permissionChanges[2].permissionId, keccak256("EXECUTE_PERMISSION")); // minting 1 assertEq( - uint256(_permissionChanges[3].operation), - uint256(PermissionLib.Operation.Revoke), - "Incorrect operation" - ); - assertEq( - _permissionChanges[3].where, - _preparedSetupData.helpers[0], - "Incorrect where" + uint256(_permissionChanges[3].operation), uint256(PermissionLib.Operation.Revoke), "Incorrect operation" ); + assertEq(_permissionChanges[3].where, _preparedSetupData.helpers[0], "Incorrect where"); assertEq(_permissionChanges[3].who, address(dao), "Incorrect who"); - assertEq( - _permissionChanges[3].condition, - address(0), - "Incorrect condition" - ); - assertEq( - _permissionChanges[3].permissionId, - keccak256("MINT_PERMISSION"), - "Incorrect permission" - ); + assertEq(_permissionChanges[3].condition, address(0), "Incorrect condition"); + assertEq(_permissionChanges[3].permissionId, keccak256("MINT_PERMISSION"), "Incorrect permission"); } function test_CreatesANewERC20Token() public { // new Token - tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ - addr: address(0x0), - name: "New Token", - symbol: "NTK" - }); + tokenSettings = + OptimisticTokenVotingPluginSetup.TokenSettings({addr: address(0x0), name: "New Token", symbol: "NTK"}); address[] memory receivers = new address[](1); receivers[0] = address(0x1234); uint256[] memory amounts = new uint256[](1); amounts[0] = 100; - mintSettings = GovernanceERC20.MintSettings({ - receivers: receivers, - amounts: amounts - }); + mintSettings = GovernanceERC20.MintSettings({receivers: receivers, amounts: amounts}); bytes memory installationParams = pluginSetup.encodeInstallationParams( votingSettings, tokenSettings, // only used for GovernanceERC20 (when a token is not passed) mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - , - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); GovernanceERC20 _token = GovernanceERC20(_preparedSetupData.helpers[0]); assertEq(_token.balanceOf(address(0x1234)), 100); @@ -1055,18 +777,16 @@ contract OptimisticTokenVotingPluginSetupTest is Test { votingSettings, tokenSettings, mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - , - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); - GovernanceWrappedERC20 _wrappedToken = GovernanceWrappedERC20( - _preparedSetupData.helpers[0] - ); + GovernanceWrappedERC20 _wrappedToken = GovernanceWrappedERC20(_preparedSetupData.helpers[0]); assertEq(_wrappedToken.balanceOf(address(0x1234)), 0); assertEq(_wrappedToken.balanceOf(address(0x5678)), 0); assertEq(_wrappedToken.balanceOf(address(0x0)), 0); @@ -1097,42 +817,30 @@ contract OptimisticTokenVotingPluginSetupTest is Test { uint256[] memory amounts = new uint256[](2); amounts[0] = 100; amounts[1] = 200; - mintSettings = GovernanceERC20.MintSettings({ - receivers: receivers, - amounts: amounts - }); + mintSettings = GovernanceERC20.MintSettings({receivers: receivers, amounts: amounts}); GovernanceERC20 _token = GovernanceERC20( payable( createProxyAndCall( address(governanceERC20Base), - abi.encodeCall( - GovernanceERC20.initialize, - (IDAO(dao), "My Token", "MTK", mintSettings) - ) + abi.encodeCall(GovernanceERC20.initialize, (IDAO(dao), "My Token", "MTK", mintSettings)) ) ) ); - tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ - addr: address(_token), - name: "", - symbol: "" - }); + tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({addr: address(_token), name: "", symbol: ""}); bytes memory installationParams = pluginSetup.encodeInstallationParams( votingSettings, tokenSettings, mintSettings, + taikoL1, + taikoBridge, stdProposalMinDuration, stdProposer, emergencyProposer ); - ( - , - IPluginSetup.PreparedSetupData memory _preparedSetupData - ) = pluginSetup.prepareInstallation(address(dao), installationParams); + (, IPluginSetup.PreparedSetupData memory _preparedSetupData) = + pluginSetup.prepareInstallation(address(dao), installationParams); - GovernanceWrappedERC20 _wrappedToken = GovernanceWrappedERC20( - _preparedSetupData.helpers[0] - ); + GovernanceWrappedERC20 _wrappedToken = GovernanceWrappedERC20(_preparedSetupData.helpers[0]); assertEq(_wrappedToken.name(), "My Token"); assertEq(_wrappedToken.symbol(), "MTK"); @@ -1142,10 +850,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { } // HELPERS - function createProxyAndCall( - address _logic, - bytes memory _data - ) private returns (address) { + function createProxyAndCall(address _logic, bytes memory _data) private returns (address) { return address(new ERC1967Proxy(_logic, _data)); } } diff --git a/test/base/AragonTest.sol b/test/base/AragonTest.sol index 75e7efb..0425ffc 100644 --- a/test/base/AragonTest.sol +++ b/test/base/AragonTest.sol @@ -10,6 +10,8 @@ import {ERC20VotesMock} from "../mocks/ERC20VotesMock.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {createProxyAndCall} from "../helpers.sol"; import {RATIO_BASE} from "@aragon/osx/plugins/utils/Ratio.sol"; +import {TaikoL1UnpausedMock} from "../mocks/TaikoL1Mock.sol"; +import {ITaikoEssentialContract} from "../../src/interfaces/ITaikoEssentialContract.sol"; import {Test} from "forge-std/Test.sol"; @@ -18,6 +20,7 @@ contract AragonTest is Test { address immutable bob = address(0xB0B); address immutable carol = address(0xc4601); address immutable david = address(0xd471d); + address immutable taikoBridge = address(0xb61d6e); address immutable randomWallet = vm.addr(1234567890); address immutable DAO_BASE = address(new DAO()); @@ -33,12 +36,13 @@ contract AragonTest is Test { vm.label(bob, "Bob"); vm.label(carol, "Carol"); vm.label(david, "David"); + vm.label(taikoBridge, "Bridge"); vm.label(randomWallet, "Random wallet"); } function makeDaoWithOptimisticTokenVoting(address owner) internal - returns (DAO, OptimisticTokenVotingPlugin, ERC20VotesMock) + returns (DAO, OptimisticTokenVotingPlugin, ERC20VotesMock, ITaikoEssentialContract) { // Deploy a DAO with owner as root DAO dao = DAO( @@ -53,20 +57,20 @@ contract AragonTest is Test { ); votingToken.mint(alice, 10 ether); votingToken.delegate(alice); - vm.roll(block.number + 1); + blockForward(1); // Deploy a new plugin instance + TaikoL1UnpausedMock taikoL1 = new TaikoL1UnpausedMock(); + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin - .OptimisticGovernanceSettings({ - minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 10 days, - minProposerVotingPower: 0 - }); + .OptimisticGovernanceSettings({minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days}); OptimisticTokenVotingPlugin optimisticPlugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, taikoL1, taikoBridge) + ) ) ); @@ -79,7 +83,7 @@ contract AragonTest is Test { vm.label(address(dao), "dao"); vm.label(address(optimisticPlugin), "optimisticPlugin"); - return (dao, optimisticPlugin, votingToken); + return (dao, optimisticPlugin, votingToken, ITaikoEssentialContract(taikoL1)); } /// @notice Creates a mock DAO with a multisig and an optimistic token voting plugin. @@ -108,17 +112,21 @@ contract AragonTest is Test { votingToken.mint(); // Deploy a target contract for passed proposals to be created in + TaikoL1UnpausedMock taikoL1 = new TaikoL1UnpausedMock(); + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory targetContractSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 4 days, - minProposerVotingPower: 0 + minDuration: 4 days }); optimisticPlugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, targetContractSettings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, + (dao, targetContractSettings, votingToken, taikoL1, taikoBridge) + ) ) ); } @@ -174,17 +182,21 @@ contract AragonTest is Test { votingToken.mint(); // Deploy a target contract for passed proposals to be created in + TaikoL1UnpausedMock taikoL1 = new TaikoL1UnpausedMock(); + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory targetContractSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 10), - minDuration: 0, - minProposerVotingPower: 0 + minDuration: 0 }); optimisticPlugin = OptimisticTokenVotingPlugin( createProxyAndCall( address(OPTIMISTIC_BASE), - abi.encodeCall(OptimisticTokenVotingPlugin.initialize, (dao, targetContractSettings, votingToken)) + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, + (dao, targetContractSettings, votingToken, taikoL1, taikoBridge) + ) ) ); } diff --git a/test/mocks/TaikoL1Mock.sol b/test/mocks/TaikoL1Mock.sol new file mode 100644 index 0000000..0975df4 --- /dev/null +++ b/test/mocks/TaikoL1Mock.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.17 <0.9.0; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +import {ITaikoEssentialContract} from "../../src/interfaces/ITaikoEssentialContract.sol"; + +contract TaikoL1UnpausedMock is ITaikoEssentialContract { + function pause() external {} + function unpause() external {} + + function impl() external view returns (address) { + return address(this); + } + + function paused() external pure returns (bool) { + return false; + } + + function inNonReentrant() external view returns (bool) {} +} + +contract TaikoL1PausedMock is ITaikoEssentialContract { + function pause() external {} + function unpause() external {} + + function impl() external view returns (address) { + return address(this); + } + + function paused() external pure returns (bool) { + return true; + } + + function inNonReentrant() external view returns (bool) {} +}