Raisebox Faucet

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

Burn Logic (MisImplementation) Making faucet Contract's Balance zero

Root + Impact - Burn Logic (MisImplementation)
Making faucet Contract's Balance zero

Description

  • Normal behavior:
    The burnFaucetTokens() function should allow the contract owner to burn a specified number of faucet tokens (amountToBurn) directly from the contract’s balance, thereby reducing total supply and maintaining consistency in the faucet’s token economy.

  • Issue:
    The original implementation transferred the entire contract balance to the owner before burning only amountToBurn tokens from the owner’s wallet.
    This resulted in the faucet contract’s balance becoming zero, while the owner retained unburned tokens that were unintentionally transferred, breaking supply logic and faucet token flow.

function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
// @> transfer faucet balance to owner first before burning
_transfer(address(this), msg.sender, balanceOf(address(this)));
// @> only burns the specified amount from owner instead of total transferred
_burn(msg.sender, amountToBurn);
}

Risk

Likelihood:

  • High — The condition triggers every time burnFaucetTokens() is executed, since the full contract balance is always transferred to the owner.

  • The issue is not dependent on external input or edge cases — it’s deterministic and reproducible.

Impact:

  • Owner receives all faucet tokens each time, regardless of burn amount.

  • Token supply metrics become inaccurate, leading to loss of trust, and broken faucet mechanics.

  • Could potentially allow accidental or malicious draining of faucet tokens.

Proof of Concept

uint256 contractBalance = raiseBoxFaucet.getFaucetTotalSupply();
uint256 burnAmount = contractBalance / 2;
vm.prank(owner);
raiseBoxFaucet.burnFaucetTokens(burnAmount);
// Contract balance becomes 0 instead of (contractBalance - burnAmount)
assertEq(raiseBoxFaucet.getFaucetTotalSupply(), 0);
// Owner receives unburned tokens unintentionally
assertEq(raiseBoxFaucet.getBalance(owner), contractBalance, "Owner wrongly owns all faucet tokens");

Making More Gas efficient

- require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
+ if(amountToBurn>balanceOf(address(this)),RaiseBoxFaucet_InsufficientFaucetTokenBalance())

Recommended Mitigation

- _transfer(address(this), msg.sender, balanceOf(address(this)));
- _burn(msg.sender, amountToBurn);
+ uint256 contractBalance = balanceOf(address(this));
+ if(amountToBurn>balanceOf(address(this)),RaiseBoxFaucet_InsufficientFaucetTokenBalance())
+ _burn(address(this), amountToBurn);
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 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.