dailyDrips is wrongly reset , letting new users bypass the daily cap and claim Ether.
Description
function claimFaucetTokens() public {
...
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,
address(this).balance < sepEthAmountToDrip ? "Faucet out of ETH" : "Daily ETH cap reached"
);
}
} else {
@> dailyDrips = 0;
}
...
}
Risk
Proof of Concept
pragma solidity ^0.8.30;
import {Test, console} from "../lib/lib/forge-std/src/Test.sol";
import {RaiseBoxFaucet} from "../src/RaiseBoxFaucet.sol";
contract Audit_Test is Test {
function test_dripETH() public{
RaiseBoxFaucet raiseBoxFaucet;
raiseBoxFaucet = new RaiseBoxFaucet(
"raiseboxtoken",
"RB",
1000 * 10 ** 18,
1 ether,
2 ether
);
vm.deal(address(raiseBoxFaucet), 4 ether);
address user1 = makeAddr("1");
address user2 = makeAddr("2");
address user3 = makeAddr("3");
address user4 = makeAddr("4");
vm.warp(3 days);
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
vm.warp(block.timestamp + 3 days);
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user3);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user4);
raiseBoxFaucet.claimFaucetTokens();
assert(address(user1).balance == 1 ether);
assert(address(user2).balance == 1 ether);
assert(address(user3).balance == 1 ether);
assert(address(user4).balance == 1 ether);
}
}
Recommended Mitigation
function claimFaucetTokens() public {
...
// drip sepolia eth to first time claimers if supply hasn't ran out or sepolia drip not paused**
// still checks
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
uint256 currentDay = block.timestamp / 24 hours;
if (currentDay > lastDripDay) {
lastDripDay = currentDay;
dailyDrips = 0;
- // dailyClaimCount = 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,
address(this).balance < sepEthAmountToDrip ? "Faucet out of ETH" : "Daily ETH cap reached"
);
}
- } else {
- dailyDrips = 0;
}
...
}