Raisebox Faucet

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

Gas Inefficiency — Unnecessary Storage Write for faucetClaimer in claimFaucetTokens()

Root + Impact

Description

Inside claimFaucetTokens(), the contract stores msg.sender into the state variable faucetClaimer, which is then used throughout the function. This assignment is unnecessary because the function can simply reference msg.sender directly or assign it to a local memory variable.

Each call performs an SSTORE operation (either 5,000 or 20,000 gas), wasting gas on every faucet claim without any functional need.

function claimFaucetTokens() public {
// @> Gas-inefficient: writing msg.sender to storage
faucetClaimer = msg.sender;
if (block.timestamp < (lastClaimTime[faucetClaimer] + CLAIM_COOLDOWN)) {
revert RaiseBoxFaucet_ClaimCooldownOn();
}
...
}

Risk: Low

Likelihood: High

Factor Observation Likelihood Influence
Frequency Happens on every faucet claim High
Severity Minor, but consistently costly Medium
Access Publicly callable High
Complexity Simple and deterministic High

Impact: Low

Impact Area Description
Gas Cost Adds unnecessary 5,000–20,000 gas per claim call.
Performance Reduces overall throughput and faucet efficiency.
Maintainability Misleads developers into thinking faucetClaimer has persistent meaning beyond function scope.
Code Quality Reflects misunderstanding of local vs. storage variables.

Proof of Concept

Compare gas usage between the current and optimized versions:

After replacing faucetClaimer = msg.sender; with a local variable, gas usage will drop.

  • Gas used: 242380
    (current implementation)

  • Gas used: 218876
    (replacing with local variable)

  • Gas used: 218855 (using direclty the msg.sender)

function testGasClaimFaucetTokens() public {
vm.startPrank(user1);
uint256 gasBefore = gasleft();
raiseBoxFaucet.claimFaucetTokens();
uint256 gasAfter = gasleft();
console.log("Gas used:", gasBefore - gasAfter);
}

Recommended Mitigation

Replacing faucetClaimer = msg.sender; with a local variable or directly using msg.sender all over in the function scope.

function claimFaucetTokens() public {
- faucetClaimer = msg.sender
+ address claimer = msg.sender; // Local variable, cheaper and cleaner
if (block.timestamp < (lastClaimTime[claimer] + CLAIM_COOLDOWN)) {
revert RaiseBoxFaucet_ClaimCooldownOn();
}
...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 14 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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