diff --git a/test/OptimisticTokenVotingPlugin.t.sol b/test/OptimisticTokenVotingPlugin.t.sol index 8dd2764..891c8d0 100644 --- a/test/OptimisticTokenVotingPlugin.t.sol +++ b/test/OptimisticTokenVotingPlugin.t.sol @@ -13,12 +13,11 @@ import {DaoUnauthorized} from "@aragon/osx/core/utils/auth.sol"; import {ERC20VotesMock} from "./mocks/ERC20VotesMock.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol"; -import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; contract OptimisticTokenVotingPluginTest is Test { address immutable daoBase = address(new DAO()); address immutable pluginBase = address(new OptimisticTokenVotingPlugin()); - address votingTokenBase = address(new ERC20VotesMock()); + address immutable votingTokenBase = address(new ERC20VotesMock()); DAO public dao; OptimisticTokenVotingPlugin public plugin; @@ -54,8 +53,6 @@ contract OptimisticTokenVotingPluginTest is Test { function setUp() public { vm.startPrank(alice); - vm.deal(alice, 1000 ether); - vm.deal(bob, 1000 ether); // Deploy a DAO with Alice as root dao = DAO( @@ -148,6 +145,22 @@ contract OptimisticTokenVotingPluginTest is Test { ) ) ); + assertEq( + plugin.totalVotingPower(block.number - 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); @@ -162,6 +175,11 @@ contract OptimisticTokenVotingPluginTest is Test { ) ) ); + assertEq( + plugin.minVetoRatio(), + uint32(RATIO_BASE / 5), + "Incorrect minVetoRatio" + ); // Different minDuration settings.minDuration = 25 days; @@ -176,6 +194,7 @@ contract OptimisticTokenVotingPluginTest is Test { ) ) ); + assertEq(plugin.minDuration(), 25 days, "Incorrect minDuration"); // A token with 10 eth supply votingToken = ERC20VotesMock( @@ -198,6 +217,11 @@ contract OptimisticTokenVotingPluginTest is Test { ) ) ); + assertEq( + plugin.totalVotingPower(block.number - 1), + 10 ether, + "Incorrect token supply" + ); // Different minProposerVotingPower settings.minProposerVotingPower = 1 ether; @@ -212,6 +236,11 @@ contract OptimisticTokenVotingPluginTest is Test { ) ) ); + assertEq( + plugin.minProposerVotingPower(), + 1 ether, + "Incorrect minProposerVotingPower" + ); } function test_InitializeEmitsEvent() public { @@ -286,6 +315,13 @@ contract OptimisticTokenVotingPluginTest is Test { supported = plugin.supportsInterface(bytes4(0xffffffff)); assertEq(supported, false, "Should not support any other interface"); + // Some fuzzing values are expected to be true + if (_randomInterfaceId == bytes4(0x52d1902d)) { + supported = plugin.supportsInterface(_randomInterfaceId); + assertEq(supported, true, "proxiableUUID should be supported"); + return; + } + supported = plugin.supportsInterface(_randomInterfaceId); assertEq(supported, false, "Should not support any other interface"); } @@ -340,7 +376,68 @@ contract OptimisticTokenVotingPluginTest is Test { ); } + function test_TotalVotingPowerReturnsTheRightSupply() public { + assertEq( + plugin.totalVotingPower(block.number - 1), + votingToken.getPastTotalSupply(block.number - 1), + "Incorrect total voting power" + ); + assertEq( + plugin.totalVotingPower(block.number - 1), + 10 ether, + "Incorrect total voting power" + ); + + // New token + votingToken = ERC20VotesMock( + createProxyAndCall( + address(votingTokenBase), + abi.encodeWithSelector(ERC20VotesMock.initialize.selector) + ) + ); + votingToken.mint(alice, 15 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: 0 + }); + + plugin = OptimisticTokenVotingPlugin( + createProxyAndCall( + address(pluginBase), + abi.encodeWithSelector( + OptimisticTokenVotingPlugin.initialize.selector, + dao, + settings, + votingToken + ) + ) + ); + + assertEq( + plugin.totalVotingPower(block.number - 1), + votingToken.getPastTotalSupply(block.number - 1), + "Incorrect total voting power" + ); + assertEq( + plugin.totalVotingPower(block.number - 1), + 15 ether, + "Incorrect total voting power" + ); + } + function test_MinVetoRatioReturnsTheRightValue() public { + assertEq( + plugin.minVetoRatio(), + uint32(RATIO_BASE / 10), + "Incorrect minVetoRatio" + ); + // New plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin @@ -361,9 +458,17 @@ contract OptimisticTokenVotingPluginTest is Test { ) ) ); + + assertEq( + plugin.minVetoRatio(), + uint32(RATIO_BASE / 5), + "Incorrect minVetoRatio" + ); } function test_MinDurationReturnsTheRightValue() public { + assertEq(plugin.minDuration(), 10 days, "Incorrect minDuration"); + // New plugin instance OptimisticTokenVotingPlugin.OptimisticGovernanceSettings memory settings = OptimisticTokenVotingPlugin @@ -384,6 +489,103 @@ contract OptimisticTokenVotingPluginTest is Test { ) ) ); + + assertEq(plugin.minDuration(), 25 days, "Incorrect minDuration"); + } + + function test_MinProposerVotingPowerReturnsTheRightValue() public { + assertEq( + plugin.minProposerVotingPower(), + 0, + "Incorrect minProposerVotingPower" + ); + + // New token + votingToken = ERC20VotesMock( + createProxyAndCall( + address(votingTokenBase), + abi.encodeWithSelector(ERC20VotesMock.initialize.selector) + ) + ); + 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(pluginBase), + abi.encodeWithSelector( + OptimisticTokenVotingPlugin.initialize.selector, + 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"); + assertEq( + plugin.isMember(randomWallet), + false, + "Random wallet should not be a member" + ); + + // New token + votingToken = ERC20VotesMock( + createProxyAndCall( + address(votingTokenBase), + abi.encodeWithSelector(ERC20VotesMock.initialize.selector) + ) + ); + votingToken.mint(alice, 10 ether); + votingToken.mint(bob, 5 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(pluginBase), + abi.encodeWithSelector( + OptimisticTokenVotingPlugin.initialize.selector, + dao, + settings, + votingToken + ) + ) + ); + + assertEq(plugin.isMember(alice), true, "Alice should be a member"); + assertEq(plugin.isMember(bob), true, "Bob should be a member"); + assertEq( + plugin.isMember(randomWallet), + false, + "Random wallet should not be a member" + ); } // Create proposal @@ -675,6 +877,68 @@ contract OptimisticTokenVotingPluginTest is Test { plugin.createProposal("", actions, 0, 0, 0); } + function test_GetProposalReturnsTheRightValues() public { + vm.warp(500); + uint32 startDate = 600; + uint32 endDate = startDate + 15 days; + + IDAO.Action[] memory actions = new IDAO.Action[](1); + actions[0].to = address(plugin); + actions[0].value = 1 wei; + actions[0].data = abi.encodeWithSelector( + OptimisticTokenVotingPlugin.totalVotingPower.selector, + 0 + ); + uint256 failSafeBitmap = 1; + + uint256 proposalId = plugin.createProposal( + "ipfs://", + actions, + failSafeBitmap, + startDate, + endDate + ); + + (bool open0, , , , , ) = plugin.getProposal(proposalId); + assertEq(open0, false, "The proposal should not be open"); + + // Move on + vm.warp(startDate); + + ( + bool open, + bool executed, + OptimisticTokenVotingPlugin.ProposalParameters memory parameters, + uint256 vetoTally, + IDAO.Action[] memory actualActions, + uint256 actualFailSafeBitmap + ) = plugin.getProposal(proposalId); + + assertEq(open, true, "The proposal should be open"); + 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(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); + + (bool open1, , , , , ) = plugin.getProposal(proposalId); + assertEq(open1, false, "The proposal should not be open anymore"); + } + // Can Veto function test_CanVetoReturnsFalseWhenAProposalDoesntExist() public { vm.roll(10); diff --git a/test/OptimisticTokenVotingPluginSetup.t.sol b/test/OptimisticTokenVotingPluginSetup.t.sol index 0b31e44..6e2c5ae 100644 --- a/test/OptimisticTokenVotingPluginSetup.t.sol +++ b/test/OptimisticTokenVotingPluginSetup.t.sol @@ -101,7 +101,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000b41d5e00000000000000000000000000000000000000000000000000000000001f1d5e0000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000001234567890"; + memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -122,7 +122,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes - memory expected = hex"0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000001e24000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000b41d5e00000000000000000000000000000000000000000000000000000000001f1d5e0000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000001234567890"; + memory expected = hex"0000000000000000000000000000000000000000000000000000000000030d400000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000001e24000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -142,7 +142,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000b41d5e00000000000000000000000000000000000000000000000000000000001f1d5e0000000000000000000000000000000000000000000000000000000000005678000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001057726170706564204e657720436f696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004774e434e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000001234567890"; + memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005678000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001057726170706564204e657720436f696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004774e434e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -166,7 +166,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000006978000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000b41d5e00000000000000000000000000000000000000000000000000000000001f1d5e0000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000006789000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000001234567890"; + memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000123456789000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000006789000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000499602d2"; assertEq(output, expected, "Incorrect encoded bytes"); } @@ -183,11 +183,11 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); bytes - memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000b41d5e00000000000000000000000000000000000000000000000000000000001f1d5e0000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000567890"; + memory expected = hex"00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000069780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000056789000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000d5772617070656420546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000377544b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; assertEq(output, expected, "Incorrect encoded bytes"); } - function test_ShouldDecodeInstallationParams() public { + function test_ShouldDecodeInstallationParams_1() public { votingSettings = OptimisticTokenVotingPlugin .OptimisticGovernanceSettings({ minVetoRatio: uint32(RATIO_BASE / 4), @@ -228,8 +228,8 @@ contract OptimisticTokenVotingPluginSetupTest is Test { OptimisticTokenVotingPluginSetup.TokenSettings memory _tokenSettings, GovernanceERC20.MintSettings memory _mintSettings, - address stdProposer, - address emergencyProposer + address _stdProposer, + address _emergencyProposer ) = pluginSetup.decodeInstallationParams(_installationParams); // Voting @@ -282,6 +282,14 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_mintSettings.amounts[0], 2000, "Incorrect amounts[0]"); assertEq(_mintSettings.amounts[1], 5000, "Incorrect amounts[1]"); + // Proposers + assertEq(_stdProposer, stdProposer, "Incorrect standard proposer"); + assertEq( + _emergencyProposer, + emergencyProposer, + "Incorrect emergency proposer" + ); + // Proposers assertEq(stdProposer, address(0x3456), "Incorrect stdProposer"); assertEq( @@ -291,6 +299,130 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); } + function test_ShouldDecodeInstallationParams_2() public { + votingSettings = OptimisticTokenVotingPlugin + .OptimisticGovernanceSettings({ + minVetoRatio: uint32(RATIO_BASE / 5), + minDuration: 12 days, + minProposerVotingPower: 44444444 + }); + tokenSettings = OptimisticTokenVotingPluginSetup.TokenSettings({ + addr: address(governanceWrappedERC20Base), + name: "Mega wToken", + symbol: "MwTK" + }); + address[] memory receivers = new address[](4); + receivers[0] = address(0x1111); + receivers[1] = address(0x2222); + receivers[2] = address(0x3333); + receivers[3] = address(0x4444); + uint256[] memory amounts = new uint256[](4); + amounts[0] = 1000; + amounts[1] = 2000; + amounts[2] = 3000; + amounts[3] = 4000; + mintSettings = GovernanceERC20.MintSettings({ + receivers: receivers, + amounts: amounts + }); + stdProposer = address(0x6666); + emergencyProposer = address(0x8888); + + bytes memory _installationParams = pluginSetup.encodeInstallationParams( + votingSettings, + tokenSettings, + // only used for GovernanceERC20 (when a token is not passed) + mintSettings, + stdProposer, + emergencyProposer + ); + + // Decode + ( + OptimisticTokenVotingPlugin.OptimisticGovernanceSettings + memory _votingSettings, + OptimisticTokenVotingPluginSetup.TokenSettings + memory _tokenSettings, + GovernanceERC20.MintSettings memory _mintSettings, + 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" + ); + + // Token + 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.amounts.length, 4, "Incorrect amounts.length"); + assertEq(_mintSettings.amounts[0], 1000, "Incorrect amounts[0]"); + assertEq(_mintSettings.amounts[1], 2000, "Incorrect amounts[1]"); + assertEq(_mintSettings.amounts[2], 3000, "Incorrect amounts[2]"); + assertEq(_mintSettings.amounts[3], 4000, "Incorrect amounts[3]"); + + // Proposers + assertEq(_stdProposer, stdProposer, "Incorrect standard proposer"); + assertEq( + _emergencyProposer, + emergencyProposer, + "Incorrect emergency proposer" + ); + + // Proposers + assertEq(stdProposer, address(0x6666), "Incorrect stdProposer"); + assertEq( + emergencyProposer, + address(0x8888), + "Incorrect emergencyProposer" + ); + } + function test_PrepareInstallationReturnsTheProperPermissions_Default() public { @@ -316,7 +448,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.helpers.length, 1, "One helper expected"); assertEq( _preparedSetupData.permissions.length, - 3 + 1, // base + proposers + 5, // base + 2 proposers "Incorrect permission length" ); // 1 @@ -366,11 +498,27 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); assertEq(_preparedSetupData.permissions[3].where, _plugin); assertEq(_preparedSetupData.permissions[3].who, address(stdProposer)); - assertEq(_preparedSetupData.permissions[3].condition, address(0)); + assertNotEq(_preparedSetupData.permissions[3].condition, address(0)); assertEq( _preparedSetupData.permissions[3].permissionId, keccak256("PROPOSER_PERMISSION") ); + // proposer 2 + assertEq( + uint256(_preparedSetupData.permissions[4].operation), + uint256(PermissionLib.Operation.Grant), + "Incorrect operation" + ); + assertEq(_preparedSetupData.permissions[4].where, _plugin); + assertEq( + _preparedSetupData.permissions[4].who, + address(emergencyProposer) + ); + assertEq(_preparedSetupData.permissions[4].condition, address(0)); + assertEq( + _preparedSetupData.permissions[4].permissionId, + keccak256("PROPOSER_PERMISSION") + ); // no more: no minted token } @@ -414,7 +562,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { assertEq(_preparedSetupData.helpers.length, 1, "One helper expected"); assertEq( _preparedSetupData.permissions.length, - 3 + 2, // base + proposers + 3 + 2, // base + 2 proposers "Incorrect permission length" ); // 1 @@ -464,7 +612,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); assertEq(_preparedSetupData.permissions[3].where, _plugin); assertEq(_preparedSetupData.permissions[3].who, address(stdProposer)); - assertEq(_preparedSetupData.permissions[3].condition, address(0)); + assertNotEq(_preparedSetupData.permissions[3].condition, address(0)); assertEq( _preparedSetupData.permissions[3].permissionId, keccak256("PROPOSER_PERMISSION") @@ -588,7 +736,7 @@ contract OptimisticTokenVotingPluginSetupTest is Test { ); assertEq(_preparedSetupData.permissions[3].where, _plugin); assertEq(_preparedSetupData.permissions[3].who, address(stdProposer)); - assertEq(_preparedSetupData.permissions[3].condition, address(0)); + assertNotEq(_preparedSetupData.permissions[3].condition, address(0)); assertEq( _preparedSetupData.permissions[3].permissionId, keccak256("PROPOSER_PERMISSION")