@@ -557,13 +557,13 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
557557            mockUSDFC,
558558            address (pdpServiceWithPayments),
559559            true , // approved 
560-             1000e6 , // rate allowance (1000 USDFC) 
561-             1000e6 , // lockup allowance (1000 USDFC) 
560+             1000e18 , // rate allowance (1000 USDFC) 
561+             1000e18 , // lockup allowance (1000 USDFC) 
562562            365  days  // max lockup period 
563563        );
564564
565565        // Client deposits funds to the FilecoinPayV1 contract for future payments 
566-         uint256  depositAmount =  10e6 ; // Sufficient funds for initial lockup and future operations 
566+         uint256  depositAmount =  10e18 ; // Sufficient funds for initial lockup and future operations 
567567        mockUSDFC.approve (address (payments), depositAmount);
568568        payments.deposit (mockUSDFC, client, depositAmount);
569569        vm.stopPrank ();
@@ -682,13 +682,13 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
682682            mockUSDFC,
683683            address (pdpServiceWithPayments),
684684            true , // approved 
685-             1000e6 , // rate allowance (1000 USDFC) 
686-             1000e6 , // lockup allowance (1000 USDFC) 
685+             1000e18 , // rate allowance (1000 USDFC) 
686+             1000e18 , // lockup allowance (1000 USDFC) 
687687            365  days  // max lockup period 
688688        );
689689
690690        // Client deposits funds to the FilecoinPayV1 contract for future payments 
691-         uint256  depositAmount =  10e6 ; // Sufficient funds for initial lockup and future operations 
691+         uint256  depositAmount =  10e18 ; // Sufficient funds for initial lockup and future operations 
692692        mockUSDFC.approve (address (payments), depositAmount);
693693        payments.deposit (mockUSDFC, client, depositAmount);
694694        vm.stopPrank ();
@@ -795,11 +795,11 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
795795            mockUSDFC,
796796            address (pdpServiceWithPayments),
797797            true , // approved 
798-             1000e6 , // rate allowance (1000 USDFC) 
799-             1000e6 , // lockup allowance (1000 USDFC) 
798+             1000e18 , // rate allowance (1000 USDFC) 
799+             1000e18 , // lockup allowance (1000 USDFC) 
800800            365  days  // max lockup period 
801801        );
802-         uint256  depositAmount =  10e6 ; // Sufficient funds for initial lockup and future operations 
802+         uint256  depositAmount =  10e18 ; // Sufficient funds for initial lockup and future operations 
803803        mockUSDFC.approve (address (payments), depositAmount);
804804        payments.deposit (mockUSDFC, client, depositAmount);
805805        vm.stopPrank ();
@@ -909,38 +909,132 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
909909        // Test the values returned by getServicePrice 
910910        FilecoinWarmStorageService.ServicePricing memory  pricing =  pdpServiceWithPayments.getServicePrice ();
911911
912-         uint256  decimals =  6 ; // MockUSDFC uses 6  decimals in tests 
913-         uint256  expectedNoCDN =  25  *  10  **  (decimals -  1 ); // 2.5 USDFC with 6  decimals 
914-         uint256  expectedWithCDN =  3  *  10  **  decimals; // 3 USDFC with 6  decimals (2.5 + 0.5 CDN) 
912+         uint256  decimals =  18 ; // MockUSDFC uses 18  decimals in tests 
913+         uint256  expectedNoCDN =  25  *  10  **  (decimals -  1 ); // 2.5 USDFC with 18  decimals 
914+         uint256  expectedWithCDN =  3  *  10  **  decimals; // 3 USDFC with 18  decimals (2.5 + 0.5 CDN) 
915915
916916        assertEq (pricing.pricePerTiBPerMonthNoCDN, expectedNoCDN, "No CDN price should be 2.5 * 10^decimals " );
917917        assertEq (pricing.pricePerTiBPerMonthWithCDN, expectedWithCDN, "With CDN price should be 3 * 10^decimals " );
918918        assertEq (address (pricing.tokenAddress), address (mockUSDFC), "Token address should match USDFC " );
919919        assertEq (pricing.epochsPerMonth, 86400 , "Epochs per month should be 86400 " );
920920
921921        // Verify the values are in expected range 
922-         assert (pricing.pricePerTiBPerMonthNoCDN <  10  **  8 ); // Less than 10^8  
923-         assert (pricing.pricePerTiBPerMonthWithCDN <  10  **  8 ); // Less than 10^8  
922+         assert (pricing.pricePerTiBPerMonthNoCDN <  10  **  20 ); // Less than 10^20  
923+         assert (pricing.pricePerTiBPerMonthWithCDN <  10  **  20 ); // Less than 10^20  
924924    }
925925
926926    function testGetEffectiveRatesValues  () public  view  {
927927        // Test the values returned by getEffectiveRates 
928928        (uint256  serviceFee , uint256  spPayment ) =  pdpServiceWithPayments.getEffectiveRates ();
929929
930-         uint256  decimals =  6 ; // MockUSDFC uses 6  decimals in tests 
931-         // Total is 2.5 USDFC with 6  decimals 
930+         uint256  decimals =  18 ; // MockUSDFC uses 18  decimals in tests 
931+         // Total is 2.5 USDFC with 18  decimals 
932932        uint256  expectedTotal =  25  *  10  **  (decimals -  1 );
933933
934934        // Test setup uses 0% commission 
935935        uint256  expectedServiceFee =  0 ; // 0% commission 
936936        uint256  expectedSpPayment =  expectedTotal; // 100% goes to SP 
937937
938938        assertEq (serviceFee, expectedServiceFee, "Service fee should be 0 with 0% commission " );
939-         assertEq (spPayment, expectedSpPayment, "SP payment should be 2.5 * 10^6  " );
940-         assertEq (serviceFee +  spPayment, expectedTotal, "Total should equal 2.5 * 10^6  " );
939+         assertEq (spPayment, expectedSpPayment, "SP payment should be 2.5 * 10^18  " );
940+         assertEq (serviceFee +  spPayment, expectedTotal, "Total should equal 2.5 * 10^18  " );
941941
942942        // Verify the values are in expected range 
943-         assert (serviceFee +  spPayment <  10  **  8 ); // Less than 10^8 
943+         assert (serviceFee +  spPayment <  10  **  20 ); // Less than 10^20 
944+     }
945+ 
946+     // Minimum Pricing Tests 
947+     function testCalculateRatesPerEpoch_BelowMinimumThreshold  () public  view  {
948+         // Test various sizes below 24 GiB threshold 
949+         uint256  oneGiB =  1024  *  1024  *  1024 ;
950+ 
951+         // Calculate expected minimum rate (24 GiB at 2.5 USDFC/TiB/month) 
952+         // 24 GiB / 1024 GiB * 2.5 USDFC = 0.05859375 USDFC/month 
953+         uint256  twentyFourGiB =  24  *  oneGiB;
954+         (uint256  expectedMinRate ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (twentyFourGiB);
955+ 
956+         // Test 0 bytes 
957+         (uint256  rateZero ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (0 );
958+         assertEq (rateZero, expectedMinRate, "0 bytes should return minimum rate " );
959+ 
960+         // Test 1 GiB 
961+         (uint256  rateOneGiB ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (oneGiB);
962+         assertEq (rateOneGiB, expectedMinRate, "1 GiB should return minimum rate " );
963+ 
964+         // Test 12 GiB (half of threshold) 
965+         (uint256  rateTwelveGiB ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (12  *  oneGiB);
966+         assertEq (rateTwelveGiB, expectedMinRate, "12 GiB should return minimum rate " );
967+ 
968+         // Test 23 GiB (just below threshold) 
969+         (uint256  rateTwentyThreeGiB ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (23  *  oneGiB);
970+         assertEq (rateTwentyThreeGiB, expectedMinRate, "23 GiB should return minimum rate " );
971+     }
972+ 
973+     function testCalculateRatesPerEpoch_AtMinimumThreshold  () public  view  {
974+         // Test exactly at 24 GiB threshold 
975+         uint256  oneGiB =  1024  *  1024  *  1024 ;
976+         uint256  twentyFourGiB =  24  *  oneGiB;
977+ 
978+         (uint256  rateAtThreshold ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (twentyFourGiB);
979+ 
980+         // At exactly 24 GiB, minimum pricing and proportional pricing should yield the same rate 
981+         // This is the boundary condition 
982+         assert (rateAtThreshold >  0 );
983+     }
984+ 
985+     function testCalculateRatesPerEpoch_AboveMinimumThreshold  () public  view  {
986+         // Test sizes above 24 GiB threshold - should use proportional pricing 
987+         uint256  oneGiB =  1024  *  1024  *  1024 ;
988+         uint256  twentyFourGiB =  24  *  oneGiB;
989+ 
990+         (uint256  minRate ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (twentyFourGiB);
991+ 
992+         // Test 25 GiB (just above threshold) 
993+         (uint256  rateTwentyFiveGiB ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (25  *  oneGiB);
994+         assert (rateTwentyFiveGiB >  minRate);
995+ 
996+         // Test 48 GiB (double the threshold) 
997+         (uint256  rateFourtyEightGiB ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (48  *  oneGiB);
998+         assert (rateFourtyEightGiB >  rateTwentyFiveGiB);
999+ 
1000+         // Test 1 TiB (much larger) 
1001+         uint256  oneTiB =  oneGiB *  1024 ;
1002+         (uint256  rateOneTiB ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (oneTiB);
1003+         assert (rateOneTiB >  rateFourtyEightGiB);
1004+     }
1005+ 
1006+     function testMinimumPricing_ApproximatelyPoint06USDFC  () public  view  {
1007+         // Verify that minimum pricing is approximately 0.06 USDFC/month 
1008+         uint256  decimals =  18 ; // MockUSDFC uses 18 decimals in tests 
1009+         uint256  oneGiB =  1024  *  1024  *  1024 ;
1010+ 
1011+         // Get rate per epoch for dataset below threshold 
1012+         (uint256  ratePerEpoch ,,) =  pdpServiceWithPayments.calculateRatesPerEpoch (oneGiB);
1013+ 
1014+         // Convert to rate per month (86400 epochs per month) 
1015+         uint256  ratePerMonth =  ratePerEpoch *  86400 ;
1016+ 
1017+         // Expected: approximately 0.06 USDFC with 18 decimals = 60000000000000000 
1018+         // Actual at 2.5 USDFC/TiB: 24/1024 * 2.5 = 0.05859375 USDFC = 58593750000000000 (with 18 decimals) 
1019+         uint256  expectedApprox =  6  *  10  **  (decimals -  2 ); // 60000000000000000 
1020+         uint256  tolerance =  2  *  10  **  (decimals -  2 ); // Allow 0.02 USDFC tolerance 
1021+ 
1022+         assertApproxEqAbs (ratePerMonth, expectedApprox, tolerance, "Minimum rate should be ~0.06 USDFC/month " );
1023+     }
1024+ 
1025+     function testMinimumPricing_CDNRatesUnaffected  () public  view  {
1026+         // Verify that CDN rates remain proportional (not affected by minimum pricing) 
1027+         uint256  oneGiB =  1024  *  1024  *  1024 ;
1028+ 
1029+         // Get rates for small dataset 
1030+         (, uint256  cacheMissRateSmall , uint256  cdnRateSmall ) =  pdpServiceWithPayments.calculateRatesPerEpoch (oneGiB);
1031+ 
1032+         // Get rates for larger dataset (12 GiB) 
1033+         (, uint256  cacheMissRateLarge , uint256  cdnRateLarge ) =  pdpServiceWithPayments.calculateRatesPerEpoch (12  *  oneGiB);
1034+ 
1035+         // CDN rates should scale proportionally with size (allow small rounding tolerance) 
1036+         assertApproxEqAbs (cacheMissRateLarge, cacheMissRateSmall *  12 , 100 , "Cache miss rate should scale proportionally " );
1037+         assertApproxEqAbs (cdnRateLarge, cdnRateSmall *  12 , 100 , "CDN rate should scale proportionally " );
9441038    }
9451039
9461040    uint256  nextClientDataSetId =  0 ;
@@ -971,9 +1065,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
9711065
9721066        // Setup client payment approval if not already done 
9731067        vm.startPrank (clientAddress);
974-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
975-         mockUSDFC.approve (address (payments), 100e6 );
976-         payments.deposit (mockUSDFC, clientAddress, 100e6 );
1068+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
1069+         mockUSDFC.approve (address (payments), 100e18 );
1070+         payments.deposit (mockUSDFC, clientAddress, 100e18 );
9771071        vm.stopPrank ();
9781072
9791073        // Create data set as approved provider 
@@ -1157,9 +1251,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
11571251
11581252        // Setup client payment approval if not already done 
11591253        vm.startPrank (clientAddress);
1160-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
1161-         mockUSDFC.approve (address (payments), 100e6 );
1162-         payments.deposit (mockUSDFC, clientAddress, 100e6 );
1254+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
1255+         mockUSDFC.approve (address (payments), 100e18 );
1256+         payments.deposit (mockUSDFC, clientAddress, 100e18 );
11631257        vm.stopPrank ();
11641258
11651259        // Create data set as approved provider 
@@ -1302,11 +1396,11 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
13021396            mockUSDFC,
13031397            address (pdpServiceWithPayments),
13041398            true ,
1305-             1000e6 , // rate allowance 
1306-             1000e6 , // lockup allowance 
1399+             1000e18 , // rate allowance 
1400+             1000e18 , // lockup allowance 
13071401            365  days  // max lockup period 
13081402        );
1309-         uint256  depositAmount =  100e6 ;
1403+         uint256  depositAmount =  100e18 ;
13101404        mockUSDFC.approve (address (payments), depositAmount);
13111405        payments.deposit (mockUSDFC, client, depositAmount);
13121406        vm.stopPrank ();
@@ -1482,11 +1576,11 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
14821576            mockUSDFC,
14831577            address (pdpServiceWithPayments),
14841578            true ,
1485-             1000e6 , // rate allowance 
1486-             1000e6 , // lockup allowance 
1579+             1000e18 , // rate allowance 
1580+             1000e18 , // lockup allowance 
14871581            365  days  // max lockup period 
14881582        );
1489-         uint256  depositAmount =  100e6 ;
1583+         uint256  depositAmount =  100e18 ;
14901584        mockUSDFC.approve (address (payments), depositAmount);
14911585        payments.deposit (mockUSDFC, client, depositAmount);
14921586        vm.stopPrank ();
@@ -1603,11 +1697,11 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
16031697            mockUSDFC,
16041698            address (pdpServiceWithPayments),
16051699            true ,
1606-             1000e6 , // rate allowance 
1607-             1000e6 , // lockup allowance 
1700+             1000e18 , // rate allowance 
1701+             1000e18 , // lockup allowance 
16081702            365  days  // max lockup period 
16091703        );
1610-         uint256  depositAmount =  100e6 ;
1704+         uint256  depositAmount =  100e18 ;
16111705        mockUSDFC.approve (address (payments), depositAmount);
16121706        payments.deposit (mockUSDFC, client, depositAmount);
16131707        vm.stopPrank ();
@@ -2814,8 +2908,8 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
28142908        );
28152909
28162910        vm.startPrank (client);
2817-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
2818-         uint256  depositAmount =  1e6 ;
2911+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
2912+         uint256  depositAmount =  1e18 ;
28192913        mockUSDFC.approve (address (payments), depositAmount);
28202914        payments.deposit (mockUSDFC, client, depositAmount);
28212915        vm.stopPrank ();
@@ -2867,8 +2961,8 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
28672961        );
28682962
28692963        vm.startPrank (client);
2870-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
2871-         uint256  depositAmount =  1e6 ;
2964+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
2965+         uint256  depositAmount =  1e18 ;
28722966        mockUSDFC.approve (address (payments), depositAmount);
28732967        payments.deposit (mockUSDFC, client, depositAmount);
28742968        vm.stopPrank ();
@@ -2918,8 +3012,8 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
29183012        );
29193013
29203014        vm.startPrank (client);
2921-         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e6 ,  1000e6 , 365  days);
2922-         uint256  depositAmount =  10e6 ;
3015+         payments.setOperatorApproval (mockUSDFC, address (pdpServiceWithPayments), true , 1000e18 ,  1000e18 , 365  days);
3016+         uint256  depositAmount =  10e18 ;
29233017        mockUSDFC.approve (address (payments), depositAmount);
29243018        payments.deposit (mockUSDFC, client, depositAmount);
29253019        vm.stopPrank ();
@@ -3972,7 +4066,7 @@ contract FilecoinWarmStorageServiceSignatureTest is Test {
39724066        pdpService =  SignatureCheckingService (address (serviceProxy));
39734067
39744068        // Fund the payer 
3975-         mockUSDFC.safeTransfer (payer, 1000  *  10  **  6 ); // 1000 USDFC 
4069+         mockUSDFC.safeTransfer (payer, 1000  *  10  **  18 ); // 1000 USDFC 
39764070    }
39774071
39784072    // Test the recoverSigner function indirectly through signature verification 
0 commit comments