Raisebox Faucet

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

Owner must always mint a certain amount as to prevent a scenario where the faucets is always empty

Limitation of the "minimum threshold of tokens until owner can mint a new one" could create a scenario where "Owner must always keep track of the balance of RaiseBoxFaucet token contract"

Description

  • An owner can only mint if the Contract had less than or equal to 1000e18, this check is implemented inside RaiseBoxFaucet:mintFaucetTokens function.

  • The check itself could cause an issue where a claimers could always be prevented to claim a new faucets token when the owner only mint a small amount of tokens when the faucets is empty.

  • The owner then have to always mint a substantial amount of new tokens when the faucet token is empty or faced with a scenario where the owner mint a small amount of tokens but needs to keep doing it as to keep the faucets running.

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:

  • In the source code, the RaiseBoxFaucet:INITIAL_SUPPLY had the amount large enough to at least prevent this vulnerabilities to happened

  • It would take 1e6 amount of claims to empty the faucets. and trigger the unfortunate scenario explained above.

Impact:

  • The RaiseBoxFaucet:mintFaucetTokens function is of no use before the first 1e6 claims being executed which took forever.

  • Might as well remove the function entirely to save gases upon contract creation


Proof of Concept

NOTE: for this PoC, i reduce the RaiseBoxFaucet:INITIAL_SUPPLY to simulate an almost empty faucet token.

First, On src/RaiseBoxFaucet:

// state variables....
...
// minted on deploy via constructor
- uint256 public constant INITIAL_SUPPLY = 1000000000 * 10 ** 18;
+ uint256 public constant INITIAL_SUPPLY = 5000 * 10 ** 18;
...

then Implement the same changes in test/RaiseBoxFaucet.t.sol

...
// test constants
- uint256 public constant INITIAL_SUPPLY_MINTED = 1000_000000 * 10 ** 18;
+ uint256 public constant INITIAL_SUPPLY_MINTED = 5000 * 10 ** 18;
...

After that Implement a test function below on test/RaiseBoxFaucet.t.sol

function testClaimFaucetsWorkOnlyIfOwnerMintNewTokenAfterInitialSupplyIsAlmostEmptyOrEmpty() public {
for (uint256 i = 1; i < 10; i++) {
address claimer = address(uint160(i));
vm.prank(claimer);
raiseBoxFaucet.claimFaucetTokens();
}
uint256 boxTokenBalance = raiseBoxFaucet.getBalance(address(raiseBoxFaucet));
console.log(boxTokenBalance);
vm.prank(user1);
vm.expectRevert();
raiseBoxFaucet.claimFaucetTokens();
// Only if the owner mint a new token, claimers can claim again, and the owner could not mint a small amount of tokens...
// Otherwise only the first couple of claims could only be executed after the last mint
vm.prank(owner);
raiseBoxFaucet.mintFaucetTokens(address(raiseBoxFaucet), 1000e18);
vm.prank(user1);
raiseBoxFaucet.claimFaucetTokens();
vm.prank(user2);
vm.expectRevert();
raiseBoxFaucet.claimFaucetTokens();
}

Recommended Mitigation

Just remove RaiseBoxFaucet:mintFaucetTokens to save gases, the RaiseBoxFaucet:INITIAL_SUPPLY of 1000000000e18 tokens should be more than enough to prevent scenario above

- 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);
- }
Updates

Lead Judging Commences

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