Raisebox Faucet

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

Insufficient Token Balance Check in `burnFaucetTokens`

Description

The burnFaucetTokens function allows the owner to burn tokens by transferring the contract’s balance to the owner and then burning from the owner’s balance. It checks the contract’s balance but not the owner’s balance before calling _burn, which could revert if the owner has insufficient tokens due to prior transfers elsewhere.

// Root cause in the codebase with @> marks to highlight the relevant section
function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
@>_transfer(address(this), msg.sender, balanceOf(address(this))); // Transfers all tokens to owner
@>_burn(msg.sender, amountToBurn); // No check for owner's balance
}

Risk

Likelihood:

  • Occurs when the owner has transferred some tokens elsewhere, reducing their balance below amountToBurn.

  • Occurs only when the owner calls burnFaucetTokens with an amountToBurn exceeding their balance after the transfer.

Impact:

  • Function reverts unexpectedly, preventing the owner from burning tokens.

  • Causes a denial-of-service for the burn operation, potentially disrupting token management.

Proof of Concept

Explanation: The PoC demonstrates how the burnFaucetTokens function fails if the owner’s balance is insufficient. The owner transfers some tokens to another address, reducing their balance. When burnFaucetTokens is called with an amount exceeding the owner’s balance after the contract’s transfer, the function reverts.

// Assume owner has 500 tokens elsewhere and contract has 1000 tokens
function testBurnFailure(RaiseBoxFaucet faucet) public {
// Owner transfers 500 tokens to another address
faucet.transfer(address(0x123), 500 * 10**18);
// Attempt to burn 1000 tokens
faucet.burnFaucetTokens(1000 * 10**18); // Reverts because owner only has 500 tokens after transfer
}

Recommended Mitigation

Explanation: To avoid the issue, we modify burnFaucetTokens to burn tokens directly from the contract’s balance, eliminating the need to transfer to the owner and check their balance. This simplifies the function and ensures it only depends on the contract’s balance, which is already verified.

function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
- _transfer(address(this), msg.sender, balanceOf(address(this)));
- _burn(msg.sender, amountToBurn);
+ _burn(address(this), amountToBurn); // Burn directly from contract
}
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.