@@ -912,6 +912,137 @@ contract InitRepo_Test is Base_Test {
912912 assertFalse (escrow.getAccountExists (124 , 456 ));
913913 }
914914
915+ function test_initRepo_fuzz_signatures (uint256 wrongNonce , uint256 wrongDeadline ) public {
916+ vm.assume (wrongNonce != escrow.ownerNonce ());
917+ vm.assume (wrongDeadline != block .timestamp + 1 hours);
918+ vm.assume (wrongDeadline > block .timestamp ); // Must be future timestamp
919+
920+ address [] memory admins = new address [](1 );
921+ admins[0 ] = repoAdmin;
922+ uint256 repoId = 999 ;
923+ uint256 accountId = 999 ;
924+
925+ // Test with wrong nonce
926+ bytes32 digestWrongNonce = keccak256 (
927+ abi.encodePacked (
928+ "\x19\x01 " ,
929+ escrow.DOMAIN_SEPARATOR (),
930+ keccak256 (abi.encode (
931+ escrow.SET_ADMIN_TYPEHASH (),
932+ repoId,
933+ accountId,
934+ keccak256 (abi.encode (admins)),
935+ wrongNonce,
936+ block .timestamp + 1 hours
937+ ))
938+ )
939+ );
940+
941+ (uint8 v1 , bytes32 r1 , bytes32 s1 ) = vm.sign (ownerPrivateKey, digestWrongNonce);
942+ expectRevert (Errors.INVALID_SIGNATURE);
943+ escrow.initRepo (repoId, accountId, admins, block .timestamp + 1 hours, v1, r1, s1);
944+
945+ // Test with wrong deadline in signature
946+ bytes32 digestWrongDeadline = keccak256 (
947+ abi.encodePacked (
948+ "\x19\x01 " ,
949+ escrow.DOMAIN_SEPARATOR (),
950+ keccak256 (abi.encode (
951+ escrow.SET_ADMIN_TYPEHASH (),
952+ repoId,
953+ accountId,
954+ keccak256 (abi.encode (admins)),
955+ escrow.ownerNonce (),
956+ wrongDeadline
957+ ))
958+ )
959+ );
960+
961+ (uint8 v2 , bytes32 r2 , bytes32 s2 ) = vm.sign (ownerPrivateKey, digestWrongDeadline);
962+ expectRevert (Errors.INVALID_SIGNATURE);
963+ escrow.initRepo (repoId, accountId, admins, block .timestamp + 1 hours, v2, r2, s2);
964+ }
965+
966+ function test_initRepo_fuzz_batchLimits (uint8 numAdmins ) public {
967+ vm.assume (numAdmins > 0 );
968+ uint256 batchLimit = escrow.batchLimit ();
969+
970+ address [] memory admins = new address [](numAdmins);
971+ for (uint i = 0 ; i < numAdmins; i++ ) {
972+ admins[i] = makeAddr (string (abi.encodePacked ("batchAdmin " , i)));
973+ }
974+
975+ uint256 repoId = 888 ;
976+ uint256 accountId = 888 ;
977+ uint256 deadline = block .timestamp + 1 hours ;
978+
979+ bytes32 digest = keccak256 (
980+ abi.encodePacked (
981+ "\x19\x01 " ,
982+ escrow.DOMAIN_SEPARATOR (),
983+ keccak256 (abi.encode (
984+ escrow.SET_ADMIN_TYPEHASH (),
985+ repoId,
986+ accountId,
987+ keccak256 (abi.encode (admins)),
988+ escrow.ownerNonce (),
989+ deadline
990+ ))
991+ )
992+ );
993+
994+ (uint8 v , bytes32 r , bytes32 s ) = vm.sign (ownerPrivateKey, digest);
995+
996+ if (numAdmins <= batchLimit) {
997+ // Should succeed if within batch limit
998+ escrow.initRepo (repoId, accountId, admins, deadline, v, r, s);
999+
1000+ // Verify all admins were added
1001+ for (uint i = 0 ; i < numAdmins; i++ ) {
1002+ assertTrue (escrow.getIsAuthorizedAdmin (repoId, accountId, admins[i]));
1003+ }
1004+
1005+ address [] memory allAdmins = escrow.getAllAdmins (repoId, accountId);
1006+ assertEq (allAdmins.length , numAdmins);
1007+ } else {
1008+ // Should fail if exceeds batch limit
1009+ expectRevert (Errors.BATCH_LIMIT_EXCEEDED);
1010+ escrow.initRepo (repoId, accountId, admins, deadline, v, r, s);
1011+ }
1012+ }
1013+
1014+ function test_initRepo_fuzz_timeDeadlines (uint32 timeOffset ) public {
1015+ vm.assume (timeOffset > 0 && timeOffset <= 365 days);
1016+
1017+ address [] memory admins = new address [](1 );
1018+ admins[0 ] = repoAdmin;
1019+ uint256 repoId = 777 ;
1020+ uint256 accountId = 777 ;
1021+ uint256 deadline = block .timestamp + timeOffset;
1022+
1023+ bytes32 digest = keccak256 (
1024+ abi.encodePacked (
1025+ "\x19\x01 " ,
1026+ escrow.DOMAIN_SEPARATOR (),
1027+ keccak256 (abi.encode (
1028+ escrow.SET_ADMIN_TYPEHASH (),
1029+ repoId,
1030+ accountId,
1031+ keccak256 (abi.encode (admins)),
1032+ escrow.ownerNonce (),
1033+ deadline
1034+ ))
1035+ )
1036+ );
1037+
1038+ (uint8 v , bytes32 r , bytes32 s ) = vm.sign (ownerPrivateKey, digest);
1039+
1040+ // Should work with any reasonable future deadline
1041+ escrow.initRepo (repoId, accountId, admins, deadline, v, r, s);
1042+ assertTrue (escrow.getIsAuthorizedAdmin (repoId, accountId, repoAdmin));
1043+ assertTrue (escrow.getAccountExists (repoId, accountId));
1044+ }
1045+
9151046 /* -------------------------------------------------------------------------- */
9161047 /* EVENTS */
9171048 /* -------------------------------------------------------------------------- */
0 commit comments