Raisebox Faucet

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

Magic number usage can block minting when Faucet is out of tokens

Root + Impact / Magic number usage can block minting when Faucet is out of tokens

Description

  • The initial version of DeployRaiseBoxFaucet.s.sol::DeployRaiseboxContract ensures that the RaiseBoxFaucet.sol::faucetDrip value and the balance comparison value used in the RaiseBoxFaucet.sol::mintFaucetTokens function are identical. Therefore, when the standard (“happy path”) deployment script is used, this issue does not occur.

  • However, future Faucet deployments based on this contract may be vulnerable when a different deployment script is used that sets a greater value for faucetDrip.

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

Risk

Likelihood:

  • When the contract is deployed with a greater value for faucetDrip.

Impact:

  • When the faucet balance falls below the faucetDrip value but remains above the hardcoded magic number (1000 * 10 ** 18), the protocol will be unable to mint new faucet tokens. As a result, the claim faucet functionality will be blocked, making the protocol inoperable.

Proof of Concept

Add the following test to RaiseBoxFaucet.t.sol to reproduce the issue:

function test_audit_magicNumberUsageCanBlockMintingWhenFaucetIsOutOfTokens()
public
{
vm.startPrank(owner);
// Deploy faucet with higher faucetDrip
uint256 increasedFaucetDrip = 10000 * 10 ** 18;
uint256 mintThreshold = 1000 * 10 ** 18;
RaiseBoxFaucet testRaiseBox = new RaiseBoxFaucet(
"raiseboxtoken",
"RB",
increasedFaucetDrip, // faucetDrip
0.005 ether, // sepEthDrip
1 ether // dailySepEthCap
);
testRaiseBox.burnFaucetTokens(INITIAL_SUPPLY_MINTED);
testRaiseBox.mintFaucetTokens(address(testRaiseBox), mintThreshold * 2);
vm.stopPrank();
// Not able to claim as not enough balance
vm.prank(user1);
vm.expectRevert(
RaiseBoxFaucet.RaiseBoxFaucet_InsufficientContractBalance.selector
);
testRaiseBox.claimFaucetTokens();
// Not able to mint, as the balance is "enough" according to the hardcoded mintThreshold
vm.prank(owner);
vm.expectRevert(
RaiseBoxFaucet.RaiseBoxFaucet_FaucetNotOutOfTokens.selector
);
testRaiseBox.mintFaucetTokens(
address(testRaiseBox),
increasedFaucetDrip
);
}

Recommended Mitigation

Compare the balance against the actual faucetDrip value instead of using a hardcoded magic number.

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

Lead Judging Commences

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