@@ -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