From 3c9ee90ac7799d91100251094320f89536f5b565 Mon Sep 17 00:00:00 2001 From: paps Date: Tue, 30 Dec 2025 16:10:53 +0100 Subject: [PATCH] Add tests for proposal description restriction feature - Add testFuzz_RevertIf_DescriptionRestrictsProposer to test that proposals with restricted descriptions revert for unauthorized proposers - Add testFuzz_ProposeSucceedsIfDescriptionRestrictsCorrectProposer to test that proposals succeed when the description restricts to the correct proposer - Add _toHexString helper function for address formatting in tests This covers the previously uncovered _isValidDescriptionForProposer check in the propose function, ensuring frontrunning protection is tested. --- contracts/test/CompoundGovernor.t.sol | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/contracts/test/CompoundGovernor.t.sol b/contracts/test/CompoundGovernor.t.sol index f50328b..07c6cef 100644 --- a/contracts/test/CompoundGovernor.t.sol +++ b/contracts/test/CompoundGovernor.t.sol @@ -177,6 +177,38 @@ contract Propose is CompoundGovernorTest { ); _submitProposal(_proposer, _proposal); } + + function testFuzz_RevertIf_DescriptionRestrictsProposer(address _proposer, address _wrongProposer) public { + vm.assume(_proposer != _wrongProposer); + vm.assume(_wrongProposer != address(0)); + Proposal memory _proposal = _buildAnEmptyProposal(); + _proposal.description = string(abi.encodePacked(_proposal.description, "#proposer=0x", _toHexString(_proposer))); + vm.prank(_wrongProposer); + vm.expectRevert(abi.encodeWithSelector(IGovernor.GovernorRestrictedProposer.selector, _wrongProposer)); + governor.propose(_proposal.targets, _proposal.values, _proposal.calldatas, _proposal.description); + } + + function testFuzz_ProposeSucceedsIfDescriptionRestrictsCorrectProposer(address _proposer) public { + vm.assume(_proposer != address(0)); + Proposal memory _proposal = _buildAnEmptyProposal(); + _proposal.description = string(abi.encodePacked(_proposal.description, "#proposer=0x", _toHexString(_proposer))); + _setWhitelistedProposer(_proposer); + vm.prank(_proposer); + uint256 _proposalId = governor.propose(_proposal.targets, _proposal.values, _proposal.calldatas, _proposal.description); + vm.roll(vm.getBlockNumber() + INITIAL_VOTING_DELAY + 1); + vm.assertEq(uint8(governor.state(_proposalId)), uint8(IGovernor.ProposalState.Active)); + } + + function _toHexString(address addr) internal pure returns (string memory) { + bytes memory alphabet = "0123456789abcdef"; + bytes memory data = abi.encodePacked(addr); + bytes memory str = new bytes(40); + for (uint256 i = 0; i < 20; i++) { + str[i*2] = alphabet[uint8(data[i] >> 4)]; + str[i*2+1] = alphabet[uint8(data[i] & 0x0f)]; + } + return string(str); + } } abstract contract Queue is CompoundGovernorTest {