Overview
Hidden Mint identifies suspicious and malicious token minting activities where additional token supply can be altered in harmful ways.
Hidden mint vulnerabilities can completely devastate token value. In 2021, Levyathan.finance lost approximately $1.5 million when an attacker exploited unlimited minting permissions.
The Risk
Minting is the process of creating new tokens and adding them to circulating supply. When supply increases without corresponding demand, token price drops.
When mint functions lack proper safeguards:
- Malicious actors can create unlimited tokens
- Token value can be crashed instantly
- Investors lose their holdings
Detection Categories
Hidden Internal Mint
Functions that exploit transaction gas fees to mint additional tokens beyond what was requested, directing excess tokens to unauthorized addresses.
Risk Level: Critical
// Dangerous: Hidden internal mint
function transfer(address to, uint256 amount) public {
_transfer(msg.sender, to, amount);
_mint(owner, amount / 100); // Hidden 1% mint to owner
}
Controlled Mint
Administrator-accessible functions permitting infinite token minting, enabling controlled liquidity manipulation and exit strategies.
Risk Level: High
// Dangerous: Unlimited owner mint
function mint(uint256 amount) public onlyOwner {
_mint(owner, amount); // No cap, no timelock
}
Supply Update (Upd Supply)
Functions manipulating totalSupply outside normal minting/burning operations.
Risk Level: High
totalSupply should only increase on minting and decrease on burning. Direct manipulation is a red flag.
// Dangerous: Direct supply manipulation
function updateSupply(uint256 newSupply) public onlyOwner {
_totalSupply = newSupply; // Bypasses mint/burn logic
}
Pre-Mint
Informational flag for tokens pre-minting amounts during deployment.
Risk Level: Informational
// Common but notable: Pre-mint at deployment
constructor() {
_mint(msg.sender, 1000000 * 10**18); // 1M tokens to deployer
}
Red Flags
| Pattern | Risk |
|---|
| Mint functions with hidden internal calls | Critical |
| Owner-controlled unlimited minting | High |
Direct totalSupply manipulation | High |
| No mint cap or rate limiting | Medium |
| Pausable minting with restricted admin | Medium |
Safe Patterns
// Safe: Capped, transparent minting
uint256 public constant MAX_SUPPLY = 1000000 * 10**18;
function mint(address to, uint256 amount) public onlyOwner {
require(totalSupply() + amount <= MAX_SUPPLY, "Exceeds max supply");
_mint(to, amount);
emit Minted(to, amount); // Transparent event
}
API Response Example
{
"issues": [
{
"tag": "hidden_mint",
"severity": "high",
"description": "Contract contains hidden internal mint function",
"location": "transfer(address,uint256)"
}
]
}