pragma solidity ^0.8.30;
import {Test, console} from "forge-std/Test.sol";
import {RaiseBoxFaucet} from "../src/RaiseBoxFaucet.sol";
contract OffByOneTest is Test {
RaiseBoxFaucet public faucet;
address public owner = makeAddr("owner");
function setUp() public {
vm.startPrank(owner);
faucet = new RaiseBoxFaucet(
"TestToken",
"TEST",
1000 * 10**18,
0.005 ether,
0.1 ether
);
vm.deal(address(faucet), 10 ether);
vm.stopPrank();
}
function testOffByOneLocksFinalDrip() public {
console.log("=== Off by one ===");
console.log("");
vm.prank(owner);
faucet.burnFaucetTokens(faucet.balanceOf(address(faucet)) - 2000 * 10**18);
uint256 initialBalance = faucet.balanceOf(address(faucet));
console.log("Initial faucet balance:", initialBalance / 1e18, "tokens");
console.log("Faucet drip amount:", 1000, "tokens");
console.log("");
address user1 = makeAddr("user1");
vm.prank(user1);
faucet.claimFaucetTokens();
uint256 balanceAfterFirstClaim = faucet.balanceOf(address(faucet));
console.log("Balance after first claim:", balanceAfterFirstClaim / 1e18, "tokens");
console.log("User1 received:", faucet.balanceOf(user1) / 1e18, "tokens");
console.log("");
assertEq(balanceAfterFirstClaim, 1000 * 10**18, "Should have exactly 1000 tokens left");
vm.warp(block.timestamp + 3 days + 1);
address user2 = makeAddr("user2");
console.log("Second user attempting to claim...");
console.log("Balance check: balanceOf(contract) <= faucetDrip");
console.log("Balance check:", balanceAfterFirstClaim / 1e18, "<=", 1000);
console.log("Result: TRUE - REVERTS");
console.log("");
vm.prank(user2);
vm.expectRevert(RaiseBoxFaucet.RaiseBoxFaucet_InsufficientContractBalance.selector);
faucet.claimFaucetTokens();
uint256 finalBalance = faucet.balanceOf(address(faucet));
console.log("=== Results ===");
console.log("Final locked balance:", finalBalance / 1e18, "tokens");
console.log("User2 received:", faucet.balanceOf(user2) / 1e18, "tokens");
console.log("");
assertEq(finalBalance, 1000 * 10**18, "1000 tokens should be locked");
assertEq(faucet.balanceOf(user2), 0, "User2 should have received nothing");
}
function testCorrectBehaviorWithMoreTokens() public {
console.log("=== Normal claim with sufficient balance ===");
console.log("");
vm.prank(owner);
faucet.burnFaucetTokens(faucet.balanceOf(address(faucet)) - 1001 * 10**18);
uint256 balance = faucet.balanceOf(address(faucet));
console.log("Faucet balance:", balance / 1e18, "tokens");
console.log("Faucet drip:", 1000, "tokens");
console.log("");
address user = makeAddr("normalUser");
vm.prank(user);
faucet.claimFaucetTokens();
console.log("Claim succeeded");
console.log("User received:", faucet.balanceOf(user) / 1e18, "tokens");
console.log("Remaining balance:", faucet.balanceOf(address(faucet)) / 1e18, "tokens");
console.log("");
console.log("Works correctly when balance > faucetDrip");
}
}