@@ -863,4 +863,257 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup {
863863 }
864864 return (operators, signatures);
865865 }
866+
867+ function test_RevertsWhen_ZeroStrategies_UpdateQuorumConfig () public {
868+ IECDSAStakeRegistryTypes.Quorum memory invalidQuorum = IECDSAStakeRegistryTypes.Quorum ({
869+ strategies: new IECDSAStakeRegistryTypes.StrategyParams [](0 )
870+ });
871+ address [] memory operators = new address [](0 );
872+
873+ vm.expectRevert (IECDSAStakeRegistryErrors.InvalidQuorum.selector );
874+ registry.updateQuorumConfig (invalidQuorum, operators);
875+ }
876+
877+ function test_RevertsWhen_PartialBPSSum_UpdateQuorumConfig () public {
878+ IStrategy s1 = IStrategy (address (0x1 ));
879+ IStrategy s2 = IStrategy (address (0x2 ));
880+ IECDSAStakeRegistryTypes.StrategyParams[] memory strategies =
881+ new IECDSAStakeRegistryTypes.StrategyParams [](2 );
882+ strategies[0 ] = IECDSAStakeRegistryTypes.StrategyParams ({strategy: s1, multiplier: 9000 });
883+ strategies[1 ] = IECDSAStakeRegistryTypes.StrategyParams ({strategy: s2, multiplier: 999 });
884+
885+ address [] memory operators = new address [](0 );
886+
887+ vm.expectRevert (IECDSAStakeRegistryErrors.InvalidQuorum.selector );
888+ registry.updateQuorumConfig (
889+ IECDSAStakeRegistryTypes.Quorum ({strategies: strategies}), operators
890+ );
891+ }
892+
893+ function test_RevertsWhen_ExcessBPSSum_UpdateQuorumConfig () public {
894+ IStrategy s1 = IStrategy (address (0x1 ));
895+ IStrategy s2 = IStrategy (address (0x2 ));
896+ IECDSAStakeRegistryTypes.StrategyParams[] memory strategies =
897+ new IECDSAStakeRegistryTypes.StrategyParams [](2 );
898+ strategies[0 ] = IECDSAStakeRegistryTypes.StrategyParams ({strategy: s1, multiplier: 9000 });
899+ strategies[1 ] = IECDSAStakeRegistryTypes.StrategyParams ({strategy: s2, multiplier: 1001 });
900+
901+ address [] memory operators = new address [](0 );
902+
903+ vm.expectRevert (IECDSAStakeRegistryErrors.InvalidQuorum.selector );
904+ registry.updateQuorumConfig (
905+ IECDSAStakeRegistryTypes.Quorum ({strategies: strategies}), operators
906+ );
907+ }
908+
909+ function test_RevertsWhen_FutureReferenceBlock_CheckSignatures () public {
910+ bytes32 digest = keccak256 ("data " );
911+ (uint8 v , bytes32 r , bytes32 s ) = vm.sign (operator1Pk, digest);
912+ bytes [] memory signatures = new bytes [](1 );
913+ signatures[0 ] = abi.encodePacked (r, s, v);
914+ address [] memory operators = new address [](1 );
915+ operators[0 ] = operator1;
916+
917+ vm.expectRevert (IECDSAStakeRegistryErrors.InvalidReferenceBlock.selector );
918+ registry.isValidSignature (digest, abi.encode (operators, signatures, uint32 (block .number )));
919+ }
920+ }
921+
922+ contract ECDSAStakeRegistryEventsTest is ECDSAStakeRegistrySetup {
923+ address private newOperator = address (0x123 );
924+ address private newSigningKey = address (0x456 );
925+ uint256 private blockBeforeUpdate;
926+
927+ function setUp () public override {
928+ super .setUp ();
929+ // Ensure block number can be checkpointed
930+ vm.roll (block .number + 1 );
931+ blockBeforeUpdate = block .number ;
932+ }
933+
934+ function test_OperatorRegistered_Event () public {
935+ ISignatureUtilsMixinTypes.SignatureWithSaltAndExpiry memory sig;
936+
937+ // Expect event
938+ vm.expectEmit (true , true , false , true );
939+ emit OperatorRegistered (newOperator, address (mockServiceManager));
940+
941+ // Test action
942+ vm.prank (newOperator);
943+ registry.registerOperatorWithSignature (sig, newOperator);
944+
945+ // Verify state
946+ assertTrue (registry.operatorRegistered (newOperator));
947+ }
948+
949+ function test_OperatorDeregistered_Event () public {
950+ vm.expectEmit (true , true , false , true );
951+ emit OperatorDeregistered (operator1, address (mockServiceManager));
952+
953+ vm.prank (operator1);
954+ registry.deregisterOperator ();
955+
956+ assertFalse (registry.operatorRegistered (operator1));
957+ }
958+
959+ function test_QuorumUpdated_Event () public {
960+ IECDSAStakeRegistryTypes.Quorum memory oldQuorum = registry.quorum ();
961+ IECDSAStakeRegistryTypes.Quorum memory newQuorum = IECDSAStakeRegistryTypes.Quorum ({
962+ strategies: new IECDSAStakeRegistryTypes.StrategyParams [](1 )
963+ });
964+ newQuorum.strategies[0 ] = IECDSAStakeRegistryTypes.StrategyParams ({
965+ strategy: IStrategy (address (0x1234 )),
966+ multiplier: 10000
967+ });
968+
969+ vm.expectEmit (true , true , true , true );
970+ emit QuorumUpdated (oldQuorum, newQuorum);
971+
972+ registry.updateQuorumConfig (newQuorum, new address [](0 ));
973+
974+ assertEq (registry.quorum ().strategies.length , newQuorum.strategies.length );
975+ }
976+
977+ function test_MinimumWeightUpdated_Event () public {
978+ uint256 oldWeight = registry.minimumWeight ();
979+ uint256 newWeight = 5000 ;
980+
981+ vm.expectEmit (true , true , true , true );
982+ emit MinimumWeightUpdated (oldWeight, newWeight);
983+
984+ registry.updateMinimumWeight (newWeight, new address [](0 ));
985+
986+ assertEq (registry.minimumWeight (), newWeight);
987+ }
988+
989+ function test_MinimumWeightUpdated_Zero_Threshold () public {
990+ registry.updateMinimumWeight (1000 , new address [](0 ));
991+ uint256 oldWeight = registry.minimumWeight ();
992+ uint256 newWeight = 0 ;
993+
994+ vm.expectEmit (true , true , true , true );
995+ emit MinimumWeightUpdated (oldWeight, newWeight);
996+
997+ registry.updateMinimumWeight (newWeight, new address [](0 ));
998+
999+ assertEq (registry.minimumWeight (), newWeight);
1000+ }
1001+
1002+ function test_OperatorWeightUpdated_Event () public {
1003+ uint256 oldWeight = registry.getLastCheckpointOperatorWeight (operator1);
1004+ uint256 newWeight = oldWeight + 100 ; // Simulate weight increase
1005+
1006+ IStrategy[] memory strategies = new IStrategy [](1 );
1007+ strategies[0 ] = registry.quorum ().strategies[0 ].strategy;
1008+ uint256 [] memory shares = new uint256 [](1 );
1009+ shares[0 ] = newWeight;
1010+
1011+ vm.mockCall (
1012+ address (mockDelegationManager),
1013+ abi.encodeWithSelector (
1014+ MockDelegationManager.getOperatorShares.selector , operator1, strategies
1015+ ),
1016+ abi.encode (shares)
1017+ );
1018+
1019+ vm.expectEmit (true , true , true , true );
1020+ emit OperatorWeightUpdated (operator1, oldWeight, newWeight);
1021+
1022+ address [] memory operators = new address [](1 );
1023+ operators[0 ] = operator1;
1024+ registry.updateOperators (operators);
1025+
1026+ assertEq (registry.getLastCheckpointOperatorWeight (operator1), newWeight);
1027+ }
1028+
1029+ function test_TotalWeightUpdated_Event () public {
1030+ uint256 oldTotal = registry.getLastCheckpointTotalWeight ();
1031+
1032+ uint256 weight1 = registry.getLastCheckpointOperatorWeight (operator1);
1033+ uint256 weight2 = registry.getLastCheckpointOperatorWeight (operator2);
1034+
1035+ IStrategy[] memory strategies = new IStrategy [](1 );
1036+ strategies[0 ] = registry.quorum ().strategies[0 ].strategy;
1037+
1038+ uint256 [] memory shares1 = new uint256 [](1 );
1039+ shares1[0 ] = weight1 * 2 ;
1040+
1041+ uint256 [] memory shares2 = new uint256 [](1 );
1042+ shares2[0 ] = weight2 * 2 ;
1043+
1044+ uint256 newTotal = oldTotal + weight1 + weight2;
1045+
1046+ vm.mockCall (
1047+ address (mockDelegationManager),
1048+ abi.encodeWithSelector (
1049+ MockDelegationManager.getOperatorShares.selector , operator1, strategies
1050+ ),
1051+ abi.encode (shares1)
1052+ );
1053+
1054+ vm.mockCall (
1055+ address (mockDelegationManager),
1056+ abi.encodeWithSelector (
1057+ MockDelegationManager.getOperatorShares.selector , operator2, strategies
1058+ ),
1059+ abi.encode (shares2)
1060+ );
1061+
1062+ vm.expectEmit (true , true , true , true );
1063+ emit TotalWeightUpdated (oldTotal, newTotal);
1064+
1065+ address [] memory operators = new address [](2 );
1066+ operators[0 ] = operator1;
1067+ operators[1 ] = operator2;
1068+ registry.updateOperators (operators);
1069+
1070+ assertEq (registry.getLastCheckpointTotalWeight (), newTotal);
1071+ }
1072+
1073+ function test_ThresholdWeightUpdated_Event () public {
1074+ uint256 newThreshold = 10000000000 ;
1075+
1076+ vm.expectEmit (true , true , true , true );
1077+ emit ThresholdWeightUpdated (newThreshold);
1078+
1079+ vm.prank (registry.owner ());
1080+ registry.updateStakeThreshold (newThreshold);
1081+
1082+ assertEq (registry.getLastCheckpointThresholdWeight (), newThreshold);
1083+ }
1084+
1085+ function test_SigningKeyUpdate_Event () public {
1086+ address oldKey = registry.getLatestOperatorSigningKey (operator1);
1087+ address newKey = address (0x789 );
1088+
1089+ vm.expectEmit (true , true , true , true );
1090+ emit SigningKeyUpdate (operator1, block .number , newKey, oldKey);
1091+
1092+ vm.prank (operator1);
1093+ registry.updateOperatorSigningKey (newKey);
1094+
1095+ assertEq (registry.getLatestOperatorSigningKey (operator1), newKey);
1096+ }
1097+
1098+ function test_MultiEvent_DeregisterOperator () public {
1099+ uint256 oldOperatorWeight = registry.getLastCheckpointOperatorWeight (operator1);
1100+ uint256 oldTotalWeight = registry.getLastCheckpointTotalWeight ();
1101+ uint256 expectedNewTotal = oldTotalWeight - oldOperatorWeight;
1102+
1103+ vm.expectEmit (true , true , true , true );
1104+ emit OperatorWeightUpdated (operator1, oldOperatorWeight, 0 );
1105+
1106+ vm.expectEmit (true , true , true , true );
1107+ emit TotalWeightUpdated (oldTotalWeight, expectedNewTotal);
1108+
1109+ vm.expectEmit (true , true , false , true );
1110+ emit OperatorDeregistered (operator1, address (mockServiceManager));
1111+
1112+ vm.prank (operator1);
1113+ registry.deregisterOperator ();
1114+
1115+ assertFalse (registry.operatorRegistered (operator1));
1116+ assertEq (registry.getLastCheckpointOperatorWeight (operator1), 0 );
1117+ assertEq (registry.getLastCheckpointTotalWeight (), expectedNewTotal);
1118+ }
8661119}
0 commit comments