From 12804795e753262c2e39123b1db4207320b5cc0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8r=E2=88=82=C2=A1?= Date: Fri, 26 Jul 2024 17:28:41 +0200 Subject: [PATCH] Adding a global setting to skip L2 votes --- .env.example | 1 + script/Deploy.s.sol | 2 + src/OptimisticTokenVotingPlugin.sol | 6 +- src/factory/TaikoDaoFactory.sol | 4 +- test/OptimisticTokenVotingPlugin.t.sol | 135 +++++++++++++++----- test/OptimisticTokenVotingPluginSetup.t.sol | 53 ++++++-- test/helpers/DaoBuilder.sol | 9 +- 7 files changed, 161 insertions(+), 49 deletions(-) diff --git a/.env.example b/.env.example index 946ce1f..fb7fe5d 100644 --- a/.env.example +++ b/.env.example @@ -9,6 +9,7 @@ DEPLOY_AS_PRODUCTION=true # With false, the script will deploy mock helpers MIN_VETO_RATIO="300000" # 30% L2_INACTIVITY_PERIOD="600" # in seconds (10 minutes) L2_AGGREGATION_GRACE_PERIOD="172800" # in seconds (2 days) +SKIP_L2=true MIN_STD_PROPOSAL_DELAY="8864000" # in seconds (10 days) MIN_STD_APPROVALS="5" # How many multisig approvals are required MIN_EMERGENCY_APPROVALS="10" # How many emergency multisig approvals are required diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index dff469e..e379036 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -91,6 +91,7 @@ contract Deploy is Script { taikoBridgeAddress: vm.envAddress("TAIKO_BRIDGE_ADDRESS"), l2InactivityPeriod: uint64(vm.envUint("L2_INACTIVITY_PERIOD")), l2AggregationGracePeriod: uint64(vm.envUint("L2_AGGREGATION_GRACE_PERIOD")), + skipL2: bool(vm.envBool("SKIP_L2")), // Voting settings minVetoRatio: uint32(vm.envUint("MIN_VETO_RATIO")), minStdProposalDelay: uint64(vm.envUint("MIN_STD_PROPOSAL_DELAY")), @@ -127,6 +128,7 @@ contract Deploy is Script { taikoBridgeAddress: taikoBridgeAddress, l2InactivityPeriod: uint64(vm.envUint("L2_INACTIVITY_PERIOD")), l2AggregationGracePeriod: uint64(vm.envUint("L2_AGGREGATION_GRACE_PERIOD")), + skipL2: bool(vm.envBool("SKIP_L2")), // Voting settings minVetoRatio: uint32(vm.envUint("MIN_VETO_RATIO")), minStdProposalDelay: uint64(vm.envUint("MIN_STD_PROPOSAL_DELAY")), diff --git a/src/OptimisticTokenVotingPlugin.sol b/src/OptimisticTokenVotingPlugin.sol index 5e49401..cf3fd18 100644 --- a/src/OptimisticTokenVotingPlugin.sol +++ b/src/OptimisticTokenVotingPlugin.sol @@ -42,6 +42,7 @@ contract OptimisticTokenVotingPlugin is uint64 minDuration; uint64 l2InactivityPeriod; uint64 l2AggregationGracePeriod; + bool skipL2; } /// @notice A container for proposal-related information. @@ -203,7 +204,8 @@ contract OptimisticTokenVotingPlugin is /// @notice Determines whether the L2 is currently available function isL2Available() public view returns (bool) { - if (taikoL1.paused()) return false; + if (governanceSettings.skipL2) return false; + else if (taikoL1.paused()) return false; uint64 _id = taikoL1.slotB().numBlocks; // No L2 blocks yet @@ -342,7 +344,7 @@ contract OptimisticTokenVotingPlugin is } // Checks - bool _enableL2 = votingToken.getPastVotes(taikoBridge, snapshotTimestamp) > 0 && isL2Available(); + bool _enableL2 = isL2Available() && votingToken.getPastVotes(taikoBridge, snapshotTimestamp) > 0; if (effectiveVotingPower(snapshotTimestamp, _enableL2) == 0) { revert NoVotingPower(); } diff --git a/src/factory/TaikoDaoFactory.sol b/src/factory/TaikoDaoFactory.sol index a911f2e..c2d8a54 100644 --- a/src/factory/TaikoDaoFactory.sol +++ b/src/factory/TaikoDaoFactory.sol @@ -29,6 +29,7 @@ contract TaikoDaoFactory { address taikoBridgeAddress; uint64 l2InactivityPeriod; uint64 l2AggregationGracePeriod; + bool skipL2; // Voting settings uint32 minVetoRatio; uint64 minStdProposalDelay; @@ -227,7 +228,8 @@ contract TaikoDaoFactory { settings.minVetoRatio, 0, // minDuration (the condition contract will enforce it) settings.l2InactivityPeriod, - settings.l2AggregationGracePeriod + settings.l2AggregationGracePeriod, + settings.skipL2 ); OptimisticTokenVotingPluginSetup.TokenSettings memory existingTokenSettings = diff --git a/test/OptimisticTokenVotingPlugin.t.sol b/test/OptimisticTokenVotingPlugin.t.sol index c57b141..771d4c8 100644 --- a/test/OptimisticTokenVotingPlugin.t.sol +++ b/test/OptimisticTokenVotingPlugin.t.sol @@ -63,7 +63,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert(bytes("Initializable: contract is already initialized")); @@ -77,7 +78,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 7 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); optimisticPlugin = OptimisticTokenVotingPlugin( createProxyAndCall( @@ -87,13 +89,19 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ) ); - (uint32 minVetoRatio, uint64 minDuration, uint64 l2InactivityPeriod, uint64 l2AggregationGracePeriod) = - optimisticPlugin.governanceSettings(); + ( + uint32 minVetoRatio, + uint64 minDuration, + uint64 l2InactivityPeriod, + uint64 l2AggregationGracePeriod, + bool skipL2 + ) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 10), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 10), "Incorrect minVetoRatio"); assertEq(minDuration, 7 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 10 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 2 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, false, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); @@ -110,13 +118,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); assertEq(minDuration, 7 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 10 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 2 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, false, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); @@ -134,13 +143,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); assertEq(minDuration, 25 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 10 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 2 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, false, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); @@ -158,13 +168,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); assertEq(minDuration, 25 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 30 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 2 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, false, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); @@ -182,13 +193,39 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = + optimisticPlugin.governanceSettings(); + assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); + assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); + assertEq(minDuration, 25 days, "Incorrect minDuration"); + assertEq(l2InactivityPeriod, 30 minutes, "Incorrect l2InactivityPeriod"); + assertEq(l2AggregationGracePeriod, 5 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, false, "Incorrect skipL2"); + + assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); + assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); + assertEq(address(optimisticPlugin.taikoL1()), address(taikoL1), "Incorrect taikoL1"); + assertEq(address(optimisticPlugin.taikoBridge()), address(taikoBridge), "Incorrect taikoBridge"); + + // Different skipL2 + settings.skipL2 = true; + optimisticPlugin = OptimisticTokenVotingPlugin( + createProxyAndCall( + address(OPTIMISTIC_BASE), + abi.encodeCall( + OptimisticTokenVotingPlugin.initialize, (dao, settings, votingToken, address(taikoL1), taikoBridge) + ) + ) + ); + + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); assertEq(minDuration, 25 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 30 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 5 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, true, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 10 ether, "Incorrect token supply"); @@ -209,13 +246,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); assertEq(minDuration, 25 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 30 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 5 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, true, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 23 ether, "Incorrect token supply"); @@ -233,13 +271,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); assertEq(minDuration, 25 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 30 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 5 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, true, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 23 ether, "Incorrect token supply"); @@ -258,13 +297,14 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(optimisticPlugin.minVetoRatio(), uint32(RATIO_BASE / 5), "Incorrect minVetoRatio()"); assertEq(minVetoRatio, uint32(RATIO_BASE / 5), "Incorrect minVetoRatio"); assertEq(minDuration, 25 days, "Incorrect minDuration"); assertEq(l2InactivityPeriod, 30 minutes, "Incorrect l2InactivityPeriod"); assertEq(l2AggregationGracePeriod, 5 days, "Incorrect l2AggregationGracePeriod"); + assertEq(skipL2, true, "Incorrect skipL2"); assertEq(address(optimisticPlugin.votingToken()), address(votingToken), "Incorrect votingToken"); assertEq(optimisticPlugin.totalVotingPower(block.timestamp - 1), 23 ether, "Incorrect token supply"); @@ -278,7 +318,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectEmit(); @@ -341,7 +382,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); optimisticPlugin = OptimisticTokenVotingPlugin( @@ -488,7 +530,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); optimisticPlugin = OptimisticTokenVotingPlugin( @@ -826,7 +869,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); optimisticPlugin = OptimisticTokenVotingPlugin( createProxyAndCall( @@ -1942,7 +1986,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert( abi.encodeWithSelector( @@ -1972,7 +2017,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: 0, minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert(abi.encodeWithSelector(RatioOutOfBounds.selector, 1, 0)); optimisticPlugin.updateOptimisticGovernanceSettings(newSettings); @@ -1988,7 +2034,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE + 1), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert(abi.encodeWithSelector(RatioOutOfBounds.selector, RATIO_BASE, uint32(RATIO_BASE + 1))); optimisticPlugin.updateOptimisticGovernanceSettings(newSettings); @@ -2007,7 +2054,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 4 days - 1, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 4 days, 4 days - 1) @@ -2019,7 +2067,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 10 hours, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 4 days, 10 hours) @@ -2031,7 +2080,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 0 ether, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert(abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 4 days, 0)); optimisticPlugin.updateOptimisticGovernanceSettings(newSettings); @@ -2047,7 +2097,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 365 days + 1, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 365 days, 365 days + 1) @@ -2059,7 +2110,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 500 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 365 days, 500 days) @@ -2071,7 +2123,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 1000 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectRevert( abi.encodeWithSelector(OptimisticTokenVotingPlugin.MinDurationOutOfBounds.selector, 365 days, 1000 days) @@ -2089,7 +2142,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); vm.expectEmit(); @@ -2108,7 +2162,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 19 days, l2InactivityPeriod: 50 minutes, - l2AggregationGracePeriod: 20 days + l2AggregationGracePeriod: 20 days, + skipL2: false }); vm.warp(block.timestamp + 1); @@ -2125,13 +2180,19 @@ contract OptimisticTokenVotingPluginTest is AragonTest { } function test_GovernanceSettingsReturnsTheRightValues() public { - (uint32 minVetoRatio, uint64 minDuration, uint64 l2InactivityPeriod, uint64 l2AggregationGracePeriod) = - optimisticPlugin.governanceSettings(); + ( + uint32 minVetoRatio, + uint64 minDuration, + uint64 l2InactivityPeriod, + uint64 l2AggregationGracePeriod, + bool skipL2 + ) = optimisticPlugin.governanceSettings(); assertEq(minVetoRatio, uint32(RATIO_BASE / 10)); assertEq(minDuration, 4 days); assertEq(l2InactivityPeriod, 10 minutes); assertEq(l2AggregationGracePeriod, 2 days); + assertEq(skipL2, false); // Deploy a new optimisticPlugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory newSettings = OptimisticTokenVotingPlugin @@ -2139,7 +2200,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 2), minDuration: 0, l2InactivityPeriod: 15 minutes, - l2AggregationGracePeriod: 73 days + l2AggregationGracePeriod: 73 days, + skipL2: true }); optimisticPlugin = OptimisticTokenVotingPlugin( @@ -2152,12 +2214,13 @@ contract OptimisticTokenVotingPluginTest is AragonTest { ) ); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(minVetoRatio, uint32(RATIO_BASE / 2)); assertEq(minDuration, 0); assertEq(l2InactivityPeriod, 15 minutes); assertEq(l2AggregationGracePeriod, 73 days); + assertEq(skipL2, true); // updated settings dao.grant( @@ -2168,17 +2231,19 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days, l2InactivityPeriod: 0, - l2AggregationGracePeriod: 1234 minutes + l2AggregationGracePeriod: 1234 minutes, + skipL2: false }); optimisticPlugin.updateOptimisticGovernanceSettings(newSettings); - (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod) = + (minVetoRatio, minDuration, l2InactivityPeriod, l2AggregationGracePeriod, skipL2) = optimisticPlugin.governanceSettings(); assertEq(minVetoRatio, uint32(RATIO_BASE / 5)); assertEq(minDuration, 15 days); assertEq(l2InactivityPeriod, 0); assertEq(l2AggregationGracePeriod, 1234 minutes); + assertEq(skipL2, false); } // Upgrade optimisticPlugin @@ -2214,7 +2279,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); address _newImplementation = address(new OptimisticTokenVotingPlugin()); @@ -2264,7 +2330,8 @@ contract OptimisticTokenVotingPluginTest is AragonTest { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 15 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); optimisticPlugin.upgradeToAndCall( _newImplementation, diff --git a/test/OptimisticTokenVotingPluginSetup.t.sol b/test/OptimisticTokenVotingPluginSetup.t.sol index c320ddb..6ae8608 100644 --- a/test/OptimisticTokenVotingPluginSetup.t.sol +++ b/test/OptimisticTokenVotingPluginSetup.t.sol @@ -59,7 +59,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { minVetoRatio: uint32(RATIO_BASE / 10), minDuration: 5 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceERC20Base), @@ -100,7 +101,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes memory expected = - hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000066666666000000000000000000000000000000000000000000000000000000005555555500000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000066666666000000000000000000000000000000000000000000000000000000005555555500000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -110,7 +111,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 60 * 60 * 24 * 5, l2InactivityPeriod: 20 minutes, - l2AggregationGracePeriod: 20 days + l2AggregationGracePeriod: 20 days, + skipL2: false }); bytes memory output = pluginSetup.encodeInstallationParams( OptimisticTokenVotingPluginSetup.InstallationParameters( @@ -126,7 +128,32 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes memory expected = - hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000030d40000000000000000000000000000000000000000000000000000000000006978000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000001a5e00000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000066666666000000000000000000000000000000000000000000000000000000005555555500000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000030d40000000000000000000000000000000000000000000000000000000000006978000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000001a5e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000066666666000000000000000000000000000000000000000000000000000000005555555500000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + assertEq(output, expected, "Incorrect encoded bytes"); + + // Custom 2 (skip L2) + votingSettings = OptimisticTokenVotingPlugin.OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 5), + minDuration: 60 * 60 * 24 * 5, + l2InactivityPeriod: 20 minutes, + l2AggregationGracePeriod: 20 days, + skipL2: true + }); + output = pluginSetup.encodeInstallationParams( + OptimisticTokenVotingPluginSetup.InstallationParameters( + votingSettings, + tokenSettings, + mintSettings, + address(taikoL1), + taikoBridge, + stdProposalMinDuration, + stdProposer, + emergencyProposer + ) + ); + + expected = + hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000030d40000000000000000000000000000000000000000000000000000000000006978000000000000000000000000000000000000000000000000000000000000004b000000000000000000000000000000000000000000000000000000000001a5e000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000066666666000000000000000000000000000000000000000000000000000000005555555500000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -151,7 +178,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes memory expected = - hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000066666666000000000000000000000000000000000000000000000000000000005555555500000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000000000000000000000000000000000000000005678000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001057726170706564204e657720436f696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004774e434e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000066666666000000000000000000000000000000000000000000000000000000005555555500000000000000000000000000000000000000000000000000000000000d2f00000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000000000000000000000000000000000000000005678000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001057726170706564204e657720436f696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004774e434e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -177,7 +204,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes memory expected = - hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a30000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000123400000000000000000000000000000000000000000000000000000000000056780000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000006789000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d2"; + hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000123400000000000000000000000000000000000000000000000000000000000056780000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000006789000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d2"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -199,7 +226,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes memory expected = - hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a3000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000011110000000000000000000000000000000000000000000000000000000000002222000000000000000000000000000000000000000000000000000000000013c680000000000000000000000000000000000000000000000000000000000056789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000697800000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000002a30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000011110000000000000000000000000000000000000000000000000000000000002222000000000000000000000000000000000000000000000000000000000013c680000000000000000000000000000000000000000000000000000000000056789000000000000000000000000000000000000000000000000000000023456789010000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -208,7 +235,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { minVetoRatio: uint32(RATIO_BASE / 4), minDuration: 10 days, l2InactivityPeriod: 22 minutes, - l2AggregationGracePeriod: 24 days + l2AggregationGracePeriod: 24 days, + skipL2: false }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceWrappedERC20Base), @@ -290,7 +318,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { minVetoRatio: uint32(RATIO_BASE / 5), minDuration: 12 days, l2InactivityPeriod: 44 minutes, - l2AggregationGracePeriod: 45 days + l2AggregationGracePeriod: 45 days, + skipL2: true }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceWrappedERC20Base), @@ -462,7 +491,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { minVetoRatio: uint32(RATIO_BASE / 4), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(governanceWrappedERC20Base), @@ -558,7 +588,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { minVetoRatio: uint32(RATIO_BASE / 4), minDuration: 10 days, l2InactivityPeriod: 10 minutes, - l2AggregationGracePeriod: 2 days + l2AggregationGracePeriod: 2 days, + skipL2: false }); tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ addr: address(0x0), diff --git a/test/helpers/DaoBuilder.sol b/test/helpers/DaoBuilder.sol index 5078362..bdeeb44 100644 --- a/test/helpers/DaoBuilder.sol +++ b/test/helpers/DaoBuilder.sol @@ -42,6 +42,7 @@ contract DaoBuilder is Test { uint64 public minDuration = 4 days; uint64 public l2InactivityPeriod = 10 minutes; uint64 public l2AggregationGracePeriod = 2 days; + bool public skipL2 = false; bool public onlyListed = true; uint16 public minApprovals = 1; @@ -98,6 +99,11 @@ contract DaoBuilder is Test { return this; } + function withSkipL2() public returns (DaoBuilder) { + skipL2 = true; + return this; + } + function withTaikoBridge(address newTaikoBridge) public returns (DaoBuilder) { taikoBridge = newTaikoBridge; return this; @@ -177,7 +183,8 @@ contract DaoBuilder is Test { minVetoRatio: minVetoRatio, minDuration: minDuration, l2InactivityPeriod: l2InactivityPeriod, - l2AggregationGracePeriod: l2AggregationGracePeriod + l2AggregationGracePeriod: l2AggregationGracePeriod, + skipL2: skipL2 }); optimisticPlugin = OptimisticTokenVotingPlugin(