Raisebox Faucet

First Flight #50
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Potential Denial-of-Service via Gas Limit in ETH Transfers

Description

The claimFaucetTokens function uses a low-level call for ETH transfers without a gas limit. A malicious claimant contract with a complex receive or fallback function could consume excessive gas, causing the transaction to fail and potentially blocking other claims.

// Root cause in the codebase with @> marks to highlight the relevant section
function claimFaucetTokens() public {
// ... checks ...
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
// ... daily drip checks ...
@>(bool success,) = faucetClaimer.call{value: sepEthAmountToDrip}(""); // No gas limit
if (success) {
emit SepEthDripped(faucetClaimer, sepEthAmountToDrip);
} else {
revert RaiseBoxFaucet_EthTransferFailed();
}
}
}

Risk

Likelihood:

  • Occurs when a claimant is a contract with a gas-intensive receive or fallback function.

  • Occurs during first-time claims, as ETH is only sent to new claimers.

Impact:

  • Transaction failures prevent legitimate claims, disrupting faucet functionality.

  • Could temporarily block ETH drips for other users until the malicious contract is avoided.

Proof of Concept

Explanation: The PoC shows how a malicious claimant contract with a gas-intensive receive function causes the claimFaucetTokens call to fail. The contract consumes all available gas, leading to a revert and preventing the claim from succeeding.

contract MaliciousClaimer {
receive() external payable {
uint256 i = 0;
while (true) { i++; } // Consumes all gas
}
}
function testGasDoS(RaiseBoxFaucet faucet, MaliciousClaimer claimer) public {
vm.prank(address(claimer));
faucet.claimFaucetTokens(); // Fails due to excessive gas consumption
}

Recommended Mitigation

Explanation: We add a gas limit (e.g., 2300, sufficient for simple ETH transfers) to the call in claimFaucetTokens. This prevents a malicious contract from consuming excessive gas, ensuring the transaction either succeeds or fails predictably without affecting other users.

function claimFaucetTokens() public {
// ... checks ...
if (!hasClaimedEth[faucetClaimer] && !sepEthDripsPaused) {
// ... daily drip checks ...
- (bool success,) = faucetClaimer.call{value: sepEthAmountToDrip}("");
+ (bool success,) = faucetClaimer.call{value: sepEthAmountToDrip, gas: 2300}("");
// ... rest of function ...
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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