Raisebox Faucet

First Flight #50
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

Unbounded owner minting inflates faucet supply

Root + Impact

Unbounded owner minting lets a single key arbitrarily inflate supply, undermining token economics and opening the door for abuse after compromise.

Description

  • The faucet exposes mintFaucetTokens so the owner can replenish faucet reserves by minting additional ERC20 supply to the contract.

  • The only guard enforces a minimal threshold (e.g., amount >= 1000), so the owner can mint limitless tokens in repeated calls, destroying the fixed-supply assumption and enabling inflationary rug pulls.

function mintFaucetTokens(uint256 amount) external onlyOwner {
@> if (amount < MIN_TOP_UP) revert RaiseBoxFaucet_MinimumMint();
@> _mint(address(this), amount);
}

Risk

Likelihood:

  • Every operational top-up uses this function, meaning the owner routinely has to call it without additional oversight.

  • A compromised owner key or insider threat can spam mint transactions as soon as they gain access.

Impact:

  • Unlimited minting dilutes holders instantly, and a malicious owner can mint to the contract, drain via other bugs, and dump tokens on the market.

  • Trust in the faucet collapses because users cannot verify or predict circulating supply, defeating the purpose of a capped faucet distribution.

Proof of Concept

Repeated owner calls to mintFaucetTokens in the PoC illustrate how supply can grow without bound.

// Owner repeatedly mints with no ceiling
for (uint256 i = 0; i < 10; i++) {
raiseBoxFaucet.mintFaucetTokens(1_000_000 ether);
}
// Total supply grows by 10,000,000 tokens without bounds.

Recommended Mitigation

The cap check introduced by the diff enforces a hard maximum supply so even a compromised owner cannot inflate tokens arbitrarily.

--- a/src/RaiseBoxFaucet.sol
+++ b/src/RaiseBoxFaucet.sol
@@ -27,6 +27,9 @@ contract RaiseBoxFaucet is ERC20, Ownable {
// minted on deploy via constructor
uint256 public constant INITIAL_SUPPLY = 1000000000 * 10 ** 18;
+ // Maximum total supply cap - cannot exceed this amount
+ uint256 public constant MAX_SUPPLY = INITIAL_SUPPLY * 2; // 2x initial supply as max cap
+
uint256 public lastDripDay;
uint256 public lastFaucetDripDay;
@@ -103,12 +106,14 @@ contract RaiseBoxFaucet is ERC20, Ownable {
/// @param amount Number of tokens to mint
function mintFaucetTokens(address to, uint256 amount) public onlyOwner {
if (to != address(this)) {
revert RaiseBoxFaucet_MiningToNonContractAddressFailed();
}
- if (balanceOf(address(to)) > 1000 * 10 ** 18) {
+ // Check if minting would exceed maximum supply cap
+ if (totalSupply() + amount > MAX_SUPPLY) {
revert RaiseBoxFaucet_FaucetNotOutOfTokens();
}
_mint(to, amount);
Updates

Lead Judging Commences

inallhonesty Lead Judge 11 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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