@@ -1056,6 +1056,135 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
10561056        assertApproxEqAbs (cdnRateLarge, cdnRateSmall *  12 , 100 , "CDN rate should scale proportionally " );
10571057    }
10581058
1059+     // Minimum Funds Validation Tests 
1060+     function testInsufficientFunds_BelowMinimum  () public  {
1061+         // Setup: Client with insufficient funds (below 0.06 USDFC minimum) 
1062+         address  insufficientClient =  makeAddr ("insufficientClient " );
1063+         uint256  insufficientAmount =  5e16 ; // 0.05 USDFC (below 0.06 minimum) 
1064+ 
1065+         // Transfer tokens from test contract to the test client 
1066+         mockUSDFC.safeTransfer (insufficientClient, insufficientAmount);
1067+ 
1068+         vm.startPrank (insufficientClient);
1069+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 , 1000e18 , 365  days);
1070+         mockUSDFC.approve (address (payments), insufficientAmount);
1071+         payments.deposit (mockUSDFC, insufficientClient, insufficientAmount);
1072+         vm.stopPrank ();
1073+ 
1074+         // Prepare dataset creation data 
1075+         (string [] memory  dsKeys , string [] memory  dsValues ) =  _getSingleMetadataKV ("label " , "Insufficient Test " );
1076+         FilecoinWarmStorageService.DataSetCreateData memory  createData =  FilecoinWarmStorageService.DataSetCreateData ({
1077+             payer: insufficientClient,
1078+             clientDataSetId: 999 ,
1079+             metadataKeys: dsKeys,
1080+             metadataValues: dsValues,
1081+             signature: FAKE_SIGNATURE
1082+         });
1083+ 
1084+         bytes  memory  encodedCreateData =  abi.encode (
1085+             createData.payer,
1086+             createData.clientDataSetId,
1087+             createData.metadataKeys,
1088+             createData.metadataValues,
1089+             createData.signature
1090+         );
1091+ 
1092+         // Expected minimum: (0.06 USDFC * 86400) / 86400 = 0.06 USDFC = 6e16 
1093+         uint256  minimumRequired =  6e16 ;
1094+ 
1095+         // Expect revert with InsufficientFundsForMinimumRate error 
1096+         makeSignaturePass (insufficientClient);
1097+         vm.expectRevert (
1098+             abi.encodeWithSelector (
1099+                 Errors.InsufficientFundsForMinimumRate.selector , insufficientClient, minimumRequired, insufficientAmount
1100+             )
1101+         );
1102+         vm.prank (serviceProvider);
1103+         mockPDPVerifier.createDataSet (pdpServiceWithPayments, encodedCreateData);
1104+     }
1105+ 
1106+     function testInsufficientFunds_ExactMinimum  () public  {
1107+         // Setup: Client with exactly the minimum funds (0.06 USDFC) 
1108+         address  exactClient =  makeAddr ("exactClient " );
1109+         uint256  exactAmount =  6e16 ; // Exactly 0.06 USDFC 
1110+ 
1111+         // Transfer tokens from test contract to the test client 
1112+         mockUSDFC.safeTransfer (exactClient, exactAmount);
1113+ 
1114+         vm.startPrank (exactClient);
1115+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 , 1000e18 , 365  days);
1116+         mockUSDFC.approve (address (payments), exactAmount);
1117+         payments.deposit (mockUSDFC, exactClient, exactAmount);
1118+         vm.stopPrank ();
1119+ 
1120+         // Prepare dataset creation data 
1121+         (string [] memory  dsKeys , string [] memory  dsValues ) =  _getSingleMetadataKV ("label " , "Exact Minimum Test " );
1122+         FilecoinWarmStorageService.DataSetCreateData memory  createData =  FilecoinWarmStorageService.DataSetCreateData ({
1123+             payer: exactClient,
1124+             clientDataSetId: 1000 ,
1125+             metadataKeys: dsKeys,
1126+             metadataValues: dsValues,
1127+             signature: FAKE_SIGNATURE
1128+         });
1129+ 
1130+         bytes  memory  encodedCreateData =  abi.encode (
1131+             createData.payer,
1132+             createData.clientDataSetId,
1133+             createData.metadataKeys,
1134+             createData.metadataValues,
1135+             createData.signature
1136+         );
1137+ 
1138+         // Should succeed with exact minimum 
1139+         makeSignaturePass (exactClient);
1140+         vm.prank (serviceProvider);
1141+         uint256  dataSetId =  mockPDPVerifier.createDataSet (pdpServiceWithPayments, encodedCreateData);
1142+ 
1143+         // Verify dataset was created 
1144+         assertEq (dataSetId, 1 , "Dataset should be created with exact minimum funds " );
1145+     }
1146+ 
1147+     function testInsufficientFunds_JustAboveMinimum  () public  {
1148+         // Setup: Client with slightly more than minimum (0.07 USDFC) 
1149+         address  aboveMinClient =  makeAddr ("aboveMinClient " );
1150+         uint256  aboveMinAmount =  7e16 ; // 0.07 USDFC (just above 0.06 minimum) 
1151+ 
1152+         // Transfer tokens from test contract to the test client 
1153+         mockUSDFC.safeTransfer (aboveMinClient, aboveMinAmount);
1154+ 
1155+         vm.startPrank (aboveMinClient);
1156+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 , 1000e18 , 365  days);
1157+         mockUSDFC.approve (address (payments), aboveMinAmount);
1158+         payments.deposit (mockUSDFC, aboveMinClient, aboveMinAmount);
1159+         vm.stopPrank ();
1160+ 
1161+         // Prepare dataset creation data 
1162+         (string [] memory  dsKeys , string [] memory  dsValues ) =  _getSingleMetadataKV ("label " , "Above Minimum Test " );
1163+         FilecoinWarmStorageService.DataSetCreateData memory  createData =  FilecoinWarmStorageService.DataSetCreateData ({
1164+             payer: aboveMinClient,
1165+             clientDataSetId: 1001 ,
1166+             metadataKeys: dsKeys,
1167+             metadataValues: dsValues,
1168+             signature: FAKE_SIGNATURE
1169+         });
1170+ 
1171+         bytes  memory  encodedCreateData =  abi.encode (
1172+             createData.payer,
1173+             createData.clientDataSetId,
1174+             createData.metadataKeys,
1175+             createData.metadataValues,
1176+             createData.signature
1177+         );
1178+ 
1179+         // Should succeed with funds above minimum 
1180+         makeSignaturePass (aboveMinClient);
1181+         vm.prank (serviceProvider);
1182+         uint256  dataSetId =  mockPDPVerifier.createDataSet (pdpServiceWithPayments, encodedCreateData);
1183+ 
1184+         // Verify dataset was created 
1185+         assertEq (dataSetId, 1 , "Dataset should be created with above-minimum funds " );
1186+     }
1187+ 
10591188    uint256  nextClientDataSetId =  0 ;
10601189
10611190    // Client-Data Set Tracking Tests 
@@ -4018,9 +4147,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
40184147
40194148        // Setup approvals and deposit 
40204149        vm.startPrank (client);
4021-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
4022-         mockUSDFC.approve (address (payments), 10e6 );
4023-         payments.deposit (mockUSDFC, client, 10e6 );
4150+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
4151+         mockUSDFC.approve (address (payments), 10e18 );
4152+         payments.deposit (mockUSDFC, client, 10e18 );
40244153        vm.stopPrank ();
40254154
40264155        // Create dataset 
@@ -4064,9 +4193,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
40644193
40654194        // Setup approvals and deposit 
40664195        vm.startPrank (client);
4067-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
4068-         mockUSDFC.approve (address (payments), 10e6 );
4069-         payments.deposit (mockUSDFC, client, 10e6 );
4196+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
4197+         mockUSDFC.approve (address (payments), 10e18 );
4198+         payments.deposit (mockUSDFC, client, 10e18 );
40704199        vm.stopPrank ();
40714200
40724201        // Create dataset 
@@ -4098,9 +4227,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
40984227    function testAddPiecesNonceUniquePerPayer  () public  {
40994228        // Setup approvals and deposit 
41004229        vm.startPrank (client);
4101-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
4102-         mockUSDFC.approve (address (payments), 20e6 );
4103-         payments.deposit (mockUSDFC, client, 20e6 );
4230+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
4231+         mockUSDFC.approve (address (payments), 20e18 );
4232+         payments.deposit (mockUSDFC, client, 20e18 );
41044233        vm.stopPrank ();
41054234
41064235        (string [] memory  dsKeys , string [] memory  dsValues ) =  _getSingleMetadataKV ("label " , "Dataset 1 " );
@@ -4167,9 +4296,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
41674296    function testNonceCannotBeReusedAcrossOperations  () public  {
41684297        // Setup: Approvals and deposit 
41694298        vm.startPrank (client);
4170-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
4171-         mockUSDFC.approve (address (payments), 10e6 );
4172-         payments.deposit (mockUSDFC, client, 10e6 );
4299+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
4300+         mockUSDFC.approve (address (payments), 10e18 );
4301+         payments.deposit (mockUSDFC, client, 10e18 );
41734302        vm.stopPrank ();
41744303
41754304        // Use nonce 777 to create a dataset 
0 commit comments