Raisebox Faucet

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

Full-Balance Transfer Prior to Burn Causes Faucet Drain

Root + Impact

Description

Normal Behavior

  • The burnFaucetTokens() function should only transfer and burn the specified amount amountToBurn of faucet tokens from the contract’s own balance without transferring all tokens to the owner.

Issue

  • The burnFaucetTokens() function transfer the full contract balance to owner instead of transferring amountToBurn.

function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
// transfer faucet balance to owner first before burning
// ensures owner has a balance before _burn (owner only function) can be called successfully
@> _transfer(address(this), msg.sender, balanceOf(address(this)));
_burn(msg.sender, amountToBurn);
}

Risk

Likelihood:

  • The defined flawed logic always transfers the entire balance from the contract to the owner before burning, regardless of amountToBurn.

Impact:

  • This drains all tokens from the contract, which can disrupt core functionalities that depend on the contract’s token balance (e.g., faucet claims). Users can't claim faucet tokens until the mintFaucetTokens() called again.


Proof of Concept

To test this, include the following code in the RaiseBoxFaucetTest.t.sol file:

function test_BurnFunctionCanBurnTheSpecifiedAmount() public {
uint256 burnAmount = 2e18;
assertTrue(
raiseBoxFaucet.getFaucetTotalSupply() == INITIAL_SUPPLY_MINTED,
"Total supply should be equal to Intial supply minted"
);
vm.prank(owner);
raiseBoxFaucet.burnFaucetTokens(burnAmount);
assertEq(raiseBoxFaucet.getFaucetTotalSupply(), INITIAL_SUPPLY_MINTED - burnAmount );
}

Recommended Mitigation

To mitigate the flaw, transfer and burn only the specified amountToBurn, not the full contract balance.

function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
// transfer faucet balance to owner first before burning
// ensures owner has a balance before _burn (owner only function) can be called successfully
- _transfer(address(this), msg.sender, balanceOf(address(this)));
+ _transfer(address(this), msg.sender, amountToBurn);
_burn(msg.sender, amountToBurn);
}
Updates

Lead Judging Commences

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