From aef31cc5e0f1bde53c27612c222c22c20511b632 Mon Sep 17 00:00:00 2001 From: Noel <103109678+ny-alt@users.noreply.github.com> Date: Wed, 15 May 2024 11:33:05 +0900 Subject: [PATCH] test: negative cases for confirmAlert (#135) --- contracts/.gitignore | 4 +- contracts/test/MachServiceManager.t.sol | 338 +++++++++++++++++++++++- 2 files changed, 331 insertions(+), 11 deletions(-) diff --git a/contracts/.gitignore b/contracts/.gitignore index 8ff2d74..b4f3946 100644 --- a/contracts/.gitignore +++ b/contracts/.gitignore @@ -2,4 +2,6 @@ cache/ out/ -data/ \ No newline at end of file +data/ +report/ +lcov.info \ No newline at end of file diff --git a/contracts/test/MachServiceManager.t.sol b/contracts/test/MachServiceManager.t.sol index b034fc3..fd471c7 100644 --- a/contracts/test/MachServiceManager.t.sol +++ b/contracts/test/MachServiceManager.t.sol @@ -17,6 +17,12 @@ contract MachServiceManagerTest is BLSAVSDeployer { event QuorumThresholdPercentageChanged(uint8 thresholdPercentages); event RollupChainIdUpdated(uint256 previousRollupChainId, uint256 newRollupChainId); event AlertConfirmed(bytes32 indexed alertHeaderHash, bytes32 messageHash); + event AlertRemoved(bytes32 messageHash, address sender); + + uint256 nonRandomNumber = 111; + uint256 numNonSigners = 1; + uint256 quorumBitmap = 1; + bytes quorumNumbers = BitmapUtils.bitmapToBytesArray(quorumBitmap); function setUp() public virtual { _deployMockEigenLayerAndAVS(); @@ -28,6 +34,38 @@ contract MachServiceManagerTest is BLSAVSDeployer { _setAggregatePublicKeysAndSignature(); } + function test_SetConfirmer() public { + address newConfirmer = address(42); + vm.startPrank(proxyAdminOwner); + assertTrue(serviceManager.alertConfirmer() == proxyAdminOwner, "mismatch"); + vm.expectEmit(); + emit AlertConfirmerChanged(proxyAdminOwner, newConfirmer); + serviceManager.setConfirmer(newConfirmer); + assertTrue(serviceManager.alertConfirmer() == newConfirmer, "mismatch"); + vm.stopPrank(); + } + + function test_SetConfirmer_RevertIfNotOwner() public { + vm.expectRevert("Ownable: caller is not the owner"); + serviceManager.setConfirmer(address(42)); + } + + function test_SetWhitelister() public { + address newWhitelister = address(42); + vm.startPrank(proxyAdminOwner); + assertTrue(serviceManager.whitelister() == proxyAdminOwner, "mismatch"); + vm.expectEmit(); + emit WhitelisterChanged(proxyAdminOwner, newWhitelister); + serviceManager.setWhitelister(newWhitelister); + assertTrue(serviceManager.whitelister() == newWhitelister, "mismatch"); + vm.stopPrank(); + } + + function test_SetWhitelister_RevertIfNotOwner() public { + vm.expectRevert("Ownable: caller is not the owner"); + serviceManager.setWhitelister(address(42)); + } + function test_AddToAllowlist() public { vm.startPrank(proxyAdminOwner); assertFalse(serviceManager.allowlist(defaultOperator), "mismatch"); @@ -38,6 +76,11 @@ contract MachServiceManagerTest is BLSAVSDeployer { vm.stopPrank(); } + function test_AddToAllowlist_RevertIfNotWhitelister() public { + vm.expectRevert(NotWhitelister.selector); + serviceManager.addToAllowlist(defaultOperator); + } + function test_AddToAllowlist_RevertIfZeroAddress() public { vm.startPrank(proxyAdminOwner); vm.expectRevert(ZeroAddress.selector); @@ -67,6 +110,11 @@ contract MachServiceManagerTest is BLSAVSDeployer { vm.stopPrank(); } + function test_RemoveFromAllowlist_RevertIfNotWhitelister() public { + vm.expectRevert(NotWhitelister.selector); + serviceManager.removeFromAllowlist(defaultOperator); + } + function test_RemoveFromAllowlist_RevertIfNotInAllowlist() public { address nonListedOperator = address(0xdead); @@ -91,6 +139,11 @@ contract MachServiceManagerTest is BLSAVSDeployer { vm.stopPrank(); } + function test_DisableAllowlist_RevertIfNotOwner() public { + vm.expectRevert("Ownable: caller is not the owner"); + serviceManager.disableAllowlist(); + } + function test_DisableAllowlist_RevertIfAlreadyDisabled() public { vm.startPrank(proxyAdminOwner); @@ -120,6 +173,11 @@ contract MachServiceManagerTest is BLSAVSDeployer { vm.stopPrank(); } + function test_EnableAllowlist_RevertIfNotOwner() public { + vm.expectRevert("Ownable: caller is not the owner"); + serviceManager.enableAllowlist(); + } + function test_EnableAllowlist_RevertIfAlreadyEnabled() public { vm.startPrank(proxyAdminOwner); vm.expectRevert(AlreadyEnabled.selector); // Expect the specific revert for trying to enable an already enabled allowlist @@ -127,26 +185,53 @@ contract MachServiceManagerTest is BLSAVSDeployer { vm.stopPrank(); } + function test_UpdateQuorumThresholdPercentage() public { + vm.startPrank(proxyAdminOwner); + assertTrue(serviceManager.quorumThresholdPercentage() == 66, "mismatch"); + vm.expectEmit(); + emit QuorumThresholdPercentageChanged(76); + serviceManager.updateQuorumThresholdPercentage(76); + assertTrue(serviceManager.quorumThresholdPercentage() == 76, "mismatch"); + vm.stopPrank(); + } + + function test_UpdateQuorumThresholdPercentage_RevertIfNotOwner() public { + vm.expectRevert("Ownable: caller is not the owner"); + serviceManager.updateQuorumThresholdPercentage(76); + } + + function test_UpdateQuorumThresholdPercentage_RevertIfInvalidQuorumThresholdPercentage() public { + vm.startPrank(proxyAdminOwner); + vm.expectRevert(InvalidQuorumThresholdPercentage.selector); + serviceManager.updateQuorumThresholdPercentage(101); + vm.stopPrank(); + } + + function test_UpdateRollupChainId() public { + vm.startPrank(proxyAdminOwner); + assertTrue(serviceManager.rollupChainId() == 1, "mismatch"); + vm.expectEmit(); + emit RollupChainIdUpdated(1, 42); + serviceManager.updateRollupChainId(42); + assertTrue(serviceManager.rollupChainId() == 42, "mismatch"); + vm.stopPrank(); + } + + function test_UpdateRollupChainId_RevertIfNotOwner() public { + vm.expectRevert("Ownable: caller is not the owner"); + serviceManager.updateRollupChainId(42); + } + function test_confirmAlert() public { vm.startPrank(proxyAdminOwner); serviceManager.disableAllowlist(); vm.stopPrank(); - uint256 nonRandomNumber = 111; - uint256 numNonSigners = 1; - uint256 quorumBitmap = 1; - bytes memory quorumNumbers = BitmapUtils.bitmapToBytesArray(quorumBitmap); - ( uint32 referenceBlockNumber, BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); - ( - BLSSignatureChecker.QuorumStakeTotals memory quorumStakeTotals, - /* bytes32 signatoryRecordHash */ - ) = serviceManager.checkSignatures(msgHash, quorumNumbers, referenceBlockNumber, nonSignerStakesAndSignature); - bytes memory quorumThresholdPercentages = new bytes(1); quorumThresholdPercentages[0] = bytes1(uint8(67)); @@ -159,12 +244,245 @@ contract MachServiceManagerTest is BLSAVSDeployer { vm.startPrank(proxyAdminOwner); vm.expectEmit(); + assertEq(serviceManager.totalAlerts(), 0); + assertFalse(serviceManager.contains("foo")); + emit AlertConfirmed(msgHash, alertHeader.messageHash); serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + assertEq(serviceManager.totalAlerts(), 1); + assertTrue(serviceManager.contains("foo")); + + vm.stopPrank(); + } + + function test_confirmAlert_RevertIfInvalidConfirmer() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); + vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(1); + quorumThresholdPercentages[0] = bytes1(uint8(67)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: referenceBlockNumber + }); + vm.expectRevert(InvalidConfirmer.selector); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + } + + function test_confirmAlert_RevertIfAlreadyAdded() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); + vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(1); + quorumThresholdPercentages[0] = bytes1(uint8(67)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: referenceBlockNumber + }); + + vm.startPrank(proxyAdminOwner); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); vm.expectRevert(AlreadyAdded.selector); serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + vm.stopPrank(); + } + + function test_confirmAlert_RevertIfInvalidQuorumParam() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); + vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(5); + quorumThresholdPercentages[0] = bytes1(uint8(67)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: referenceBlockNumber + }); + + vm.startPrank(proxyAdminOwner); + vm.expectRevert(InvalidQuorumParam.selector); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + vm.stopPrank(); + } + + function test_confirmAlert_RevertIfResolvedAlert() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); + vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(1); + quorumThresholdPercentages[0] = bytes1(uint8(67)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: referenceBlockNumber + }); + + vm.startPrank(proxyAdminOwner); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + serviceManager.removeAlert("foo"); + + vm.expectRevert(ResolvedAlert.selector); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + vm.stopPrank(); + } + + function test_confirmAlert_RevertIfInvalidReferenceBlockNum() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); + vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(1); + quorumThresholdPercentages[0] = bytes1(uint8(67)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: uint32(block.number) + }); + + vm.startPrank(proxyAdminOwner); + vm.expectRevert(InvalidReferenceBlockNum.selector); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + vm.stopPrank(); + } + + function test_confirmAlert_RevertIfInvalidQuorumThresholdPercentage() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); + vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(1); + quorumThresholdPercentages[0] = bytes1(uint8(101)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: referenceBlockNumber + }); + + vm.startPrank(proxyAdminOwner); + vm.expectRevert(InvalidQuorumThresholdPercentage.selector); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + vm.stopPrank(); + } + function test_confirmAlert_RevertIfInsufficientThresholdPercentages() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, numNonSigners, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(1); + quorumThresholdPercentages[0] = bytes1(uint8(65)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: referenceBlockNumber + }); + + vm.startPrank(proxyAdminOwner); + vm.expectRevert(InsufficientThresholdPercentages.selector); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + vm.stopPrank(); + } + + function test_confirmAlert_RevertIfInsufficientThreshold() public { + vm.startPrank(proxyAdminOwner); + serviceManager.disableAllowlist(); + vm.stopPrank(); + + ( + uint32 referenceBlockNumber, + BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(nonRandomNumber, 8, quorumBitmap); + + bytes memory quorumThresholdPercentages = new bytes(1); + quorumThresholdPercentages[0] = bytes1(uint8(67)); + + IMachServiceManager.AlertHeader memory alertHeader = IMachServiceManager.AlertHeader({ + messageHash: "foo", + quorumNumbers: quorumNumbers, + quorumThresholdPercentages: quorumThresholdPercentages, + referenceBlockNumber: referenceBlockNumber + }); + + vm.startPrank(proxyAdminOwner); + vm.expectRevert(InsufficientThreshold.selector); + serviceManager.confirmAlert(alertHeader, nonSignerStakesAndSignature); + vm.stopPrank(); + } + + function test_removeAlert() public { + test_confirmAlert(); + vm.startPrank(proxyAdminOwner); + assertEq(serviceManager.totalAlerts(), 1); + assertTrue(serviceManager.contains("foo")); + + vm.expectEmit(); + emit AlertRemoved("foo", msg.sender); + serviceManager.removeAlert("foo"); + + assertFalse(serviceManager.contains("foo")); + assertEq(serviceManager.totalAlerts(), 0); + vm.stopPrank(); + } + + function test_removeAlert_RevertIfNotOwner() public { + test_confirmAlert(); + vm.expectRevert("Ownable: caller is not the owner"); + serviceManager.removeAlert("foo"); } }