Raisebox Faucet

First Flight #50
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Incorrect reset of dailyDrips

High: Daily drips reset unproperly

Description

  • Daily drips reset when a not first time user calls claimFaucestTokens

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; // @> This part resets the drips when it's not supposed to.
}

Risk

Likelihood: High

  • The dailyDrips can be reset many times per day

  • Reset happens every time when a user claims tokens for second+ time

Impact: High

  • Users can claim more sepolia ETH per day than the limit set in dailySepEthCap

Proof of Concept

  1. alice claims tokens for first time

    • receives tokens and sepolia ETH

  2. we wait 3 days

    • bob claims for first time as long with 3 more users - first timers (to make it realistic)

    • dailyDrips are 20000000000000000 = 0.02 ETH for the 4 users that called for 0.005

  3. alice call claimFaucetTokens for second time triggering the Unwanted clear of dailyDrips

    • daily drips are now 0

function testResetDailyDrips() public {
vm.prank(alice); // 1st claim for alice
raiseBoxFaucet.claimFaucetTokens();
// alice have claimed 1000 tokens and 0.005 sepolia ETH
assertEq(raiseBoxFaucet.getBalance(alice), 1000e18);
assertEq(raiseBoxFaucet.getHasClaimedEth(alice), true);
vm.warp(block.timestamp + 3 days);
vm.prank(bob);// bob calls and 3 other users also do (his friends maybe)
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user2);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user3);
raiseBoxFaucet.claimFaucetTokens();
// dailyDrips are 20000000000000000 = 0.02 ETH
assertEq(raiseBoxFaucet.dailyDrips(), 0.02 ether);
vm.prank(alice);
raiseBoxFaucet.claimFaucetTokens();
// dailyDrips are now 0
assertEq(raiseBoxFaucet.dailyDrips(), 0);
}

Recommended Mitigation

Remove the else statement after the check for already claimed and if the claiming is paused.
It just breaks the logic of distributing sepolia ETH properly.

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;
- }
Updates

Lead Judging Commences

inallhonesty Lead Judge 17 days ago
Submission Judgement Published
Validated
Assigned finding tags:

dailyDrips Reset Bug

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.