Description
The function burnFaucetTokens should allow the owner to reduce the supply of tokens in the faucet contract.
However, burnFaucetTokens sends the entire contract balance of tokens to the owner and proceeds to burn the tokens from the owner. If the owner does not want to burn all of the tokens in the contract, they will receive the remainder of the tokens that should have remained in the contract.
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);
}
Risk
Likelihood:
This happens whenever the owner attempts to burn tokens in the contract but does not attempt to burn the entire balance of tokens in the contract.
Impact:
This breaks a defined limitation of the owner. The owner should not be able to claim any faucet tokens.
Proof of Concept
function testOwnerReceivesTokensWhenBurning() public {
uint256 amountToBurn = 1000e18;
vm.prank(owner);
raiseBoxFaucet.burnFaucetTokens(amountToBurn);
uint256 ownerBalanceAfterBurn = raiseBoxFaucet.balanceOf(owner);
uint256 contractBalanceAfterBurn = raiseBoxFaucet.balanceOf(address(raiseBoxFaucet));
console.log("Contract Balance Before Burn: ", raiseBoxFaucet.INITIAL_SUPPLY());
console.log("Amount Burned: ", amountToBurn);
console.log("Owner Balance After Burn: ", ownerBalanceAfterBurn);
assert(ownerBalanceAfterBurn == raiseBoxFaucet.INITIAL_SUPPLY() - amountToBurn);
assert(contractBalanceAfterBurn == 0);
}
This test shows that the owner receieves all of the tokens in the faucet contract minus the tokens that were burned.
Recommended Mitigation
Do not transfer tokens to the owner and burn directly from the contract.
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);
}