Raisebox Faucet

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

[M-02] Faucet burns wrong amount

Faucet burns wrong amount

Description

  • The burnFaucetTokens function should burn exactly the amountToBurn specified by the owner

  • Issue:

      1. The faucet transfers all tokens to owner

      1. burns the requested amountToBurnfrom owner

    • ... and the faucet ends up without tokens.

/// @notice Burns faucet tokens held by the contract
/// @dev Transfers tokens to owner first, then burns from owner
/// @param amountToBurn Amount of tokens to burn
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 (high):

  • Issue occurs every time owner executes burnFaucetTokens with partial faucet amount as amountToBurn


Impact:

  • Incorrect token burn

Proof of Concept

Owner tries to burn only 1 $RB from faucet, but ends up with all tokens in her wallet and faucet remaining token balance is 0

function test_burnFaucetTokens_WhenBurningASingleTokenAllFaucetBalanceIsTransferred() public {
// Initial token balance of the faucet
uint256 initialFaucetTokenBalance = raiseBoxFaucet.balanceOf(address(raiseBoxFaucet));
console.log("Initial faucet token balance:", initialFaucetTokenBalance);
// Owner tries to burn 1 token
vm.prank(owner);
raiseBoxFaucet.burnFaucetTokens(1 * 10 ** 18);
// Faucet token balance should be 0 after burning 1 token
uint256 remainingFaucetTokenBalance = raiseBoxFaucet.balanceOf(address(raiseBoxFaucet));
console.log("Remaining faucet token balance:", remainingFaucetTokenBalance);
assertEq(remainingFaucetTokenBalance, 0);
// Owner's token balance should be INITIAL_SUPPLY - 1
uint256 ownerTokenBalance = raiseBoxFaucet.balanceOf(owner);
console.log("Owner's token balance:", ownerTokenBalance);
assertEq(ownerTokenBalance, initialFaucetTokenBalance - 1 * 10 ** 18);
}

Recommended Mitigation

  • Check if faucet token balance is sufficient

  • and burn directly from contract.

- remove this code
+ add this code
/// @notice Burns faucet tokens held by the contract
- /// @dev Transfers tokens to owner first, then burns from owner
/// @param amountToBurn Amount of tokens to burn
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);
+ _burn(address(this), amountToBurn);
}
Updates

Lead Judging Commences

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