Raisebox Faucet

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

Insecure Burn Logic Allows Owner to Drain All Faucet Tokens Instead of Burning Specified Amount

In RaiseBoxFaucet::burnFaucetTokens, all tokens have been transfer to owner and contract have not tokens to drip after owner call this function.

Description

  • Normal behavior:
    This function should transfer amountToBurn tokens to the owner and burn exactly amountToBurn tokens from the owner's balance.

  • Actual issue:
    It transfers the entire balanceOf(address(this)) tokens to the owner but burns only amountToBurn tokens from the owner's balance.
    As a result, regardless of how many tokens the owner intends to burn, the contract's token balance becomes zero after this function is called.

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:

  • This will occur whenever the owner calls burnFaucetTokens to burn tokens.

Impact:

  • The faucet becomes empty, breaking its intended distribution mechanism.

Proof of Concept

Add the following to the test, and it will pass.

function test_balance_will_be_zero_after_burning() public {
vm.prank(owner);
if(raiseBoxFaucet.getFaucetTotalSupply() == 0) {
raiseBoxFaucet.mintFaucetTokens(
raiseBoxFaucetContractAddress,
INITIAL_SUPPLY_MINTED
);
}
assertTrue(raiseBoxFaucet.getFaucetTotalSupply() > 0, "Supply not 0 before burning");
raiseBoxFaucet.burnFaucetTokens(0);
assertTrue(raiseBoxFaucet.getFaucetTotalSupply() == 0, "Supply is zero after burning 0 token");
}

Recommended Mitigation

Replace the argument balanceOf(address(this)) in the _transfer call with 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)));
+ _transfer(address(this), msg.sender, amountToBurn);
_burn(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.