Raisebox Faucet

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

[M] Owner Can Illegally Drain Faucet Tokens via Burn Function

Root + Impact

Description

  • Expected Behavior

    The smart contract’s documentation explicitly states that the owner:

    “cannot claim faucet tokens”

    The burnFaucetTokens() function is intended to allow the owner to burn tokens held by the contract, reducing supply without gaining access to those tokens.


    Actual Behavior

    The current implementation of burnFaucetTokens() first transfers the entire token balance from the contract to the owner before burning only the requested amountToBurn. This means the owner receives all faucet tokens, and only a portion is burned — violating the core security assumption.

    function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
    require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
    // @> Transfers *entire* balance to owner
    _transfer(address(this), msg.sender, balanceOf(address(this)));
    // @> Burns only the specified amount
    _burn(msg.sender, amountToBurn);
    }

    🔴 The line:

    _transfer(address(this), msg.sender, balanceOf(address(this)));

    ...transfers all faucet tokens to the owner, not just the tokens intended for burning.

Risk

Likelihood:

  • This function is callable by the owner at any time.

No limit exists on how much the owner can pull from the faucet balance under the pretext of burning.

Impact:

  • Owner can drain all faucet tokens to their wallet and burn only a small portion, violating intended permission boundaries.

Undermines trust in the faucet mechanism and token distribution fairness.

Proof of Concept

Assume contract holds 100,000 tokens:

burnFaucetTokens(1000);

What happens:

  • Owner receives all 100,000 tokens

  • Only 1,000 are burned

  • Remaining 99,000 tokens are now in the owner's wallet

  • This is functionally equivalent to stealing from the faucet, which is not allowed per role definitions.

Recommended Mitigation

- _transfer(address(this), msg.sender, balanceOf(address(this)));
+ _transfer(address(this), msg.sender, amountToBurn);
Updates

Lead Judging Commences

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

Unnecessary and convoluted logic in burnFaucetTokens

Support

FAQs

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