User can claim eth sepolia even though the dailySepEthCap was reached
Description
Each time a user claims drip for the first time, he will earn an amount of sepolia eth.
And each time it appends the dailyDrips will be incremented, and we will check if it is greater than sepEthAmountToDrip as the following:
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
...
if (dailyDrips + sepEthAmountToDrip <= dailySepEthCap && address(this).balance >= sepEthAmountToDrip) {
hasClaimedEth[faucetClaimer] = true;
dailyDrips += sepEthAmountToDrip;
}
...
} else {
dailyDrips = 0;
}
The problem is related to the else settlement. If user claims a drip again, he will trigger this settlement and if the dailyDrips already reach the dailySepEthCap, it will return to 0 allowing another user who didn't claim drip yet to earn sepolia eth even though the dailySepEthCap was already reached this day.
Risk
Likelyhood (High) : Every time the claimer calls the function claimFaucetTokens, the dailyDrip will be reset.
Impact (Medium) : The sepolia eth reserves of the contract could be drained unintentionally by new claimers, because this else settlement breaks the dailyDrip and dailySepEthCap conditions.
Proof of Concept
In the RaiseBoxFaucet.t.sol change the sepEthDrip and the dailySepEthCap for test purposes:
function setUp() public {
owner = address(this);
raiseBoxFaucet = new RaiseBoxFaucet(
"raiseboxtoken",
"RB",
1000 * 10 ** 18,
0.5 ether,
1 ether
);
...
}
And add this test :
function testDailySepEthDrip() public {
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
assertEq(block.timestamp, raiseBoxFaucet.getUserLastClaimTime(user1));
advanceBlockTime(block.timestamp + 3 days);
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
assertEq(user2.balance, 0.5 ether);
vm.prank(user3);
raiseBoxFaucet.claimFaucetTokens();
assertEq(user3.balance, 0.5 ether);
vm.prank(user4);
raiseBoxFaucet.claimFaucetTokens();
assertEq(user4.balance, 0 ether);
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user5);
raiseBoxFaucet.claimFaucetTokens();
assertEq(user5.balance, 0.5 ether);
}
Recommended Mitigation
Remove the else stalement.
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
...
if (dailyDrips + sepEthAmountToDrip <= dailySepEthCap && address(this).balance >= sepEthAmountToDrip) {
hasClaimedEth[faucetClaimer] = true;
dailyDrips += sepEthAmountToDrip;
}
...
+ }
- } else {
- dailyDrips = 0;
- }