Raisebox Faucet

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

`RaiseBoxFaucet` contracts deployed with `RaiseBoxFaucet::faucetDrip` set higher than `1000e18` risk the owner being prevented from minting more tokens

Description

DeployRaiseBoxFaucet currently deploys RaiseBoxFaucet such that 1000 tokens will be dripped to each user that successfully calls claimFaucetTokens. In mintFaucetTokens, the function only allows the owner to mint new tokens if the contract holds less than 1000 tokens.

Therefore, if the RaiseBoxFaucet contract is deployed such that more than 1000 tokens will be dripped to each user, the contract could hold less than the drip amount while still holding above the 1000 token threshold that prevents the owner from minting more tokens.

function mintFaucetTokens(address to, uint256 amount) public onlyOwner {
if (to != address(this)) {
revert RaiseBoxFaucet_MiningToNonContractAddressFailed();
}
@> if (balanceOf(address(to)) > 1000 * 10 ** 18) {
revert RaiseBoxFaucet_FaucetNotOutOfTokens();
}
_mint(to, amount);
emit MintedNewFaucetTokens(to, amount);
}

Risk

Likelihood:

This will happen only when RaiseBoxFaucet is deployed and faucetDrip is set to a value that satisfies the following equation:

  • INITIAL_SUPPLY % faucetDrip > 1000e18

Therefore, since the INITIAL_SUPPLY is set as 1000000000e18, a faucetDrip value of 1900e18 would prevent the owner from minting more tokens.

Impact:

This will temperarily prevent the owner from minting more tokens. The owner can use burnFaucetTokens to burn tokens so the supply is below the 1000 token threshold, allowing the owner to then mint more faucet tokens.

Proof of Concept

function testOwnerCanBePreventedFromMintingMoreFaucetTokens() public {
vm.prank(owner);
RaiseBoxFaucet brokenFaucet = new RaiseBoxFaucet(
"raiseboxtoken",
"RB",
900000000 * 10 ** 18, // 1000000000 / 900000000 = 1 remainder 100000000 > 1000
0.005 ether,
1 ether
);
vm.prank(user);
brokenFaucet.claimFaucetTokens();
vm.prank(user2);
vm.expectRevert(RaiseBoxFaucet.RaiseBoxFaucet_InsufficientContractBalance.selector);
brokenFaucet.claimFaucetTokens();
vm.prank(owner);
vm.expectRevert(RaiseBoxFaucet.RaiseBoxFaucet_FaucetNotOutOfTokens.selector);
brokenFaucet.mintFaucetTokens(address(brokenFaucet), 1e27);
}

This test shows that the faucet is in a situation where a user cannot claim tokens because the contract does not have the balance, yet the owner is not able to mint new faucet tokens.

Recommended Mitigation

Either allow minting new tokens to the contract regardless of the token balance in the contract, or compare the contract token balance to faucetDrip instead.

function mintFaucetTokens(address to, uint256 amount) public onlyOwner {
if (to != address(this)) {
revert RaiseBoxFaucet_MiningToNonContractAddressFailed();
}
- if (balanceOf(address(to)) > 1000 * 10 ** 18) {
+ if (balanceOf(address(to)) > faucetDrip) {
revert RaiseBoxFaucet_FaucetNotOutOfTokens();
}
_mint(to, amount);
emit MintedNewFaucetTokens(to, amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 15 days ago
Submission Judgement Published
Validated
Assigned finding tags:

mintFaucetTokens is unusable due to logic/design mismatch with initial supply

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.