BriVault

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

Unrestricted mint() allows owner to arbitrarily mint infinite tokens and causes inflation

[H-04] Unrestricted mint() allows owner to arbitrarily mint infinite tokens and causes inflation

Description

The BriTechToken contract exposes a public mint() function callable by the contract owner which mints a fixed large amount of tokens on every invocation:

// briTechToken.sol
function mint() public onlyOwner {
// Exactly 10,000,000 BTT tokens are minted.
// @audit Owner can repeatedly mint 10M tokens, leading to infinite inflation.
_mint(owner(), 10_000_000 * 1e18);
}

There is no supply cap, no one-time check, and no governance or timelock restrictions. As a result, the owner (or an attacker who compromises the owner key) can call mint() repeatedly to create arbitrary amounts of BTT, destroying scarcity and the token’s economic integrity.

Risk

Likelihood: Medium

  • mint() is callable by the owner at any time.

  • Compromise or misuse of the owner key (or owner intentionally minting) directly enables the issue.

Impact: High

  • Unlimited minting destroys token value and trust.

  • Any system using BTT as an accounting asset (vaults, swaps, staking) can be catastrophically affected.

  • Downstream protocols and users will suffer economic loss.

Proof of Concept

Add this test to your test suite to reproduce the issue. It mints ONE_MINT repeatedly, showing linear supply growth per call.

// test/BriTechTokenRepeatMint.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "forge-std/Test.sol";
import "../src/briTechToken.sol";
contract BriTechTokenRepeatMintTest is Test {
BriTechToken token;
address owner = makeAddr("owner");
uint256 constant ONE_MINT = 10_000_000 * 1e18;
function setUp() public {
// Deploy the token as `owner`
vm.prank(owner);
token = new BriTechToken();
}
function test_RepeatedMintByOwner() public {
uint256 mints = 5; // demonstrate repeated minting
uint256 supplyBefore = token.totalSupply();
uint256 ownerBalBefore = token.balanceOf(owner);
vm.startPrank(owner);
for (uint256 i = 0; i < mints; ++i) {
token.mint();
}
vm.stopPrank();
uint256 supplyAfter = token.totalSupply();
uint256 ownerBalAfter = token.balanceOf(owner);
// Assertions: supply and owner balance increased by mints * ONE_MINT
assertEq(supplyAfter, supplyBefore + ONE_MINT * mints);
assertEq(ownerBalAfter, ownerBalBefore + ONE_MINT * mints);
}
}

Run with:

forge test --match-test test_RepeatedMintByOwner -vvv

Recommended Mitigation

  • Mint the full supply in the constructor and remove the external mint() function.

contract BriTechToken is ERC20, Ownable {
constructor() ERC20("BriTechLabs", "BTT") Ownable(msg.sender) {
- // no initial mint
+ _mint(msg.sender, 10_000_000 * 1e18); // fixed supply minted once
}
- function mint() public onlyOwner {
- _mint(owner(), 10_000_000 * 1e18);
- }
}

Rationale:

  • Ensures a fixed total supply, eliminating the inflation risk.

  • Preserves economic integrity and trust in the token.

  • Simple, safe, and works well for tokens that are meant to have a capped supply.

Updates

Appeal created

bube Lead Judge 21 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.

Give us feedback!