How to Prevent Infinite Mint Attacks in Solidity

Article author

An infinite mint attack occurs when a token contract lets an attacker create tokens without valid authorization, without enforcing a maximum supply, or both. The attacker mints an arbitrary balance, then sells, swaps, deposits, or collateralises the newly created tokens before markets and integrations can react.

The consequence is not merely inflation. Infinite minting can destroy a token’s exchange value, drain liquidity pools, and create unbacked collateral in lending or treasury systems. Elrond was recorded as losing $113.0M on 2022-06-05 in an incident classified as Infinite Mint, showing how a broken issuance boundary can become an ecosystem-level loss.

What is an infinite mint attack and how does it work?

An infinite mint attack exploits a token issuance path that does not reliably prove who may mint and how much may exist. A public or incorrectly protected mint function lets an attacker create balances that the rest of the protocol treats as legitimate ERC-20 tokens.

A mint function is safe only when its caller authorization, issuance conditions, and supply accounting match the protocol’s economic design. If any caller can reach _mint-equivalent logic, or a privileged caller can bypass a supply ceiling, the token’s scarcity is only an assumption.

A typical infinite mint attack follows this sequence:

  1. The attacker identifies an externally callable mint path or bypassable access check.
  2. The attacker calls the function with an attacker-controlled recipient and amount.
  3. The contract increases the attacker’s balance and often totalSupply.
  4. The attacker transfers the minted tokens into a DEX pool, lending market, bridge, or vault.
  5. The attacker exchanges artificial tokens for real assets or uses them as collateral.
  6. Liquidity providers, lenders, and token holders absorb the resulting economic loss.

Infinite mint vulnerabilities are especially dangerous where token balances are accepted by other contracts without independently checking how those balances were created. A lending protocol does not distinguish between tokens minted through intended emissions and tokens minted through a missing access-control check.

Which Solidity patterns cause infinite mint vulnerabilities?

Infinite mint vulnerabilities usually arise from missing authorization, missing supply limits, or authorization that is correct in appearance but reachable through an unintended administrative path. Review every function that can increase a balance, directly or indirectly.

The most obvious pattern is a public mint function with no caller restriction:

function mint(address to, uint256 amount) external {
    balanceOf[to] += amount;
    totalSupply += amount;
}

The same risk exists when a developer checks the wrong identity. For example, tx.origin should not define mint authority because an attacker can induce a privileged wallet to call a malicious intermediary contract. Similarly, checking whether a recipient is privileged does not prove that the caller is allowed to issue tokens.

Other common causes include:

  • A setMinter function callable by any account, allowing attackers to grant themselves issuance rights.
  • An upgradeable proxy whose upgrade authority can replace mint restrictions.
  • A bridge or cross-chain handler that trusts arbitrary messages as mint instructions.
  • A cap enforced in one mint function but not in another issuance route, such as reward claims or migration functions.
  • Arithmetic or unit conversion mistakes that make a nominal cap ineffective.
  • Burn-and-mint accounting where burns are not actually verified before replacement tokens are issued.

A totalSupply variable alone is not a supply control. The contract must reject every mint that would make totalSupply + amount exceed the intended maximum supply. That invariant must apply across every issuance route, including administrative recovery, bridge minting, rewards, and migrations.

What does vulnerable and fixed infinite mint Solidity code look like?

A vulnerable infinite mint contract exposes an unrestricted issuance function. Any externally owned account can mint any amount to itself, and no maximum supply limits the damage.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract VulnerableInfiniteMintToken {
    string public constant name = "Vulnerable Token";
    string public constant symbol = "VULN";

    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;

    event Transfer(address indexed from, address indexed to, uint256 amount);

    function mint(address to, uint256 amount) external {
        // VULNERABLE: any caller can create arbitrary tokens.
        totalSupply += amount;
        balanceOf[to] += amount;
        emit Transfer(address(0), to, amount);
    }

    function transfer(address to, uint256 amount) external returns (bool) {
        require(balanceOf[msg.sender] >= amount, "insufficient balance");

        unchecked {
            balanceOf[msg.sender] -= amount;
        }
        balanceOf[to] += amount;

        emit Transfer(msg.sender, to, amount);
        return true;
    }
}

The fixed version separates the administrator from authorized minters and enforces a maximum supply before every balance increase. The cap is not a substitute for authorization, and authorization is not a substitute for a cap. Both controls address different failure modes.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract CappedRoleMintToken {
    string public constant name = "Capped Token";
    string public constant symbol = "CAP";

    address public immutable admin;
    uint256 public immutable maxSupply;
    uint256 public totalSupply;

    mapping(address => bool) public isMinter;
    mapping(address => uint256) public balanceOf;

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event MinterUpdated(address indexed minter, bool allowed);

    modifier onlyAdmin() {
        require(msg.sender == admin, "not admin");
        _;
    }

    modifier onlyMinter() {
        require(isMinter[msg.sender], "not minter");
        _;
    }

    constructor(uint256 maxSupply_) {
        require(maxSupply_ > 0, "zero cap");
        admin = msg.sender;
        maxSupply = maxSupply_;
        isMinter[msg.sender] = true;
    }

    function setMinter(address minter, bool allowed) external onlyAdmin {
        isMinter[minter] = allowed;
        emit MinterUpdated(minter, allowed);
    }

    function mint(address to, uint256 amount) external onlyMinter {
        // FIX: authorized issuance cannot exceed the immutable cap.
        require(totalSupply + amount <= maxSupply, "cap exceeded");

        totalSupply += amount;
        balanceOf[to] += amount;
        emit Transfer(address(0), to, amount);
    }

    function transfer(address to, uint256 amount) external returns (bool) {
        require(balanceOf[msg.sender] >= amount, "insufficient balance");

        unchecked {
            balanceOf[msg.sender] -= amount;
        }
        balanceOf[to] += amount;

        emit Transfer(msg.sender, to, amount);
        return true;
    }
}

If your protocol has minting through rewards, bridging, vault shares, or migrations, a smart-contract audit and security review can trace each issuance route back to its authorization and supply invariant before deployment.

How do you prevent infinite mint attacks in Solidity?

Preventing infinite mint attacks requires a layered issuance design: explicit authority, enforced supply constraints, narrow administrative powers, and tests that prove no other path can create balances. The appropriate design depends on whether supply is fixed, capped, emissions-based, collateral-backed, or bridge-backed.

Technique What it stops Gas or complexity cost Limitation
Role-gated mint Arbitrary external callers minting tokens Storage read for the role check A compromised minter can still mint within its authority
Immutable maximum supply Minting beyond the designed token supply One arithmetic check per mint Does not prevent an authorized party from minting the full cap prematurely
Separate admin and minter roles A minter silently granting itself more authority Additional role-management code The admin remains a critical trust boundary
Multisignature or timelocked administration Single-key changes to minters or issuance configuration Operational delay and governance overhead Does not correct flawed mint logic already deployed
Centralised internal _mint path Cap checks being omitted in secondary issuance functions Refactoring effort Reviewers must still find every external route into _mint
Event monitoring for mint activity Delayed detection of abnormal issuance Off-chain monitoring infrastructure Monitoring cannot reverse an already valid malicious mint

For fixed-supply tokens, the strongest pattern is often to mint the entire allocation during deployment and remove all later mint capability. For emissions-based tokens, define a measurable schedule, enforce the aggregate cap in the shared internal issuance function, and ensure each external function has a distinct authorization purpose.

Soken methodology treats minting as an asset-creation boundary, not a convenience function. Every route that increases token balances should have a documented authority model, an explicit economic limit, and a testable invariant.

Which real incidents were classified as infinite mint attacks?

Recorded infinite mint incidents show that token issuance flaws affect established assets and newer protocols across several chains. The incidents below are classified as Infinite Mint in the DefiLlama hacks database.

Protocol Date Amount lost Chain
Elrond 2022-06-05 $113.0M Elrond
Paid Network 2021-03-05 $27.0M Ethereum
Gala 2024-05-20 $22.3M Ethereum
Haven Protocol 2021-07-03 $8.2M Haven
OcelotDex 2024-09-20 $4.9M Ethereum
TSR 2026-06-01 $2.5M BSC
Raydium AMM 2026-06-10 $1.3M Solana
Flooring Protocol 2026-06-08 $500K Ethereum

These incidents share a core economic property: once unbacked tokens enter an integrated market, the attack extends beyond the token contract. Liquidity pools buy the artificial supply, lending markets may accept it as collateral, and bridges or vaults may propagate the balance into further systems.

The relevant review question is therefore broader than, “Can an attacker call mint?” It is, “Can any untrusted or excessively trusted path cause the protocol to recognise unbacked tokens as valid assets?”

How do you detect an infinite mint vulnerability before deployment?

Detecting infinite mint vulnerabilities requires mapping all balance-increasing state transitions, then proving that each transition is authorized and preserves the intended supply invariant. A manual review should begin with token contracts, but must continue into bridges, vaults, reward distributors, upgrade modules, and administrative helpers.

Use this review checklist:

  1. Find every write to balances, shares, supply counters, and internal mint functions.
  2. Verify each external issuance path has caller authorization appropriate to its purpose.
  3. Confirm every path enforces the same cap or emissions constraint.
  4. Review functions that add, remove, or replace minters and administrators.
  5. Trace upgrade, bridge, migration, and callback paths that can reach mint logic.
  6. Check whether privileged accounts can change the cap, issuer, or accounting unit unexpectedly.
  7. Verify that mint events and totalSupply match actual balance creation.
  8. Test integrations that accept the token as collateral, liquidity, or vault assets.

Slither is useful for enumerating externally callable functions, privileged state changes, and suspicious access-control patterns, but it cannot establish that a protocol’s supply model is economically correct. Manual reasoning is essential for indirect mint paths and cross-contract authority.

Foundry fuzzing can test that arbitrary callers cannot mint and that supply never exceeds the cap. Invariant tests are particularly effective because they express the security property directly:

function invariant_supplyNeverExceedsCap() public view {
    require(token.totalSupply() <= token.maxSupply(), "supply cap broken");
}

A second invariant should assert that only approved actors can increase supply. In Soken review methodology, that property is tested across all public functions, not only the function named mint. For additional research on access control, token accounting, and related contract risks, visit the Soken Hub.

Security insight: Soken methodology treats each new token unit as a liability created by the protocol. If the contract cannot prove who authorized that liability and why it remains within the issuance model, the mint path is a security boundary requiring redesign.

A role check and supply cap turn unrestricted issuance into a bounded, accountable operation, but only if every mint route uses them. The critical engineering task is to centralise balance creation and make bypasses impossible by construction.

Before launch or upgrade, write the intended supply invariant in plain language, implement it in the shared mint path, and enforce it with Foundry invariant tests.

Article author

Frequently Asked Questions

What is an infinite mint attack in Solidity?

An infinite mint attack in a Solidity token contract occurs when an attacker can create tokens without valid authorization, without a maximum supply limit, or both. The attacker can obtain an arbitrary balance that protocol components and integrations treat as legitimate ERC-20 tokens.

How does an infinite mint attack work?

An infinite mint attack exploits a token issuance path that does not reliably prove who may mint tokens or how much supply may exist. A public or incorrectly protected mint function can let an attacker create balances that the protocol treats as legitimate ERC-20 tokens.

What damage can an infinite mint attack cause?

An infinite mint attack can destroy a token's exchange value through uncontrolled inflation. Newly minted tokens can be sold, swapped, deposited, or used as collateral, draining liquidity pools and creating unbacked collateral in lending or treasury systems before markets and integrations react.

What happened in the Elrond infinite mint incident?

Elrond was recorded as losing $113.0M on 2022-06-05 in an incident classified as Infinite Mint. The Elrond incident shows that a broken token issuance boundary can become an ecosystem-level loss when markets and integrations accept newly minted token balances.

How can Solidity developers prevent infinite mint attacks?

To prevent an infinite mint attack, a Solidity token contract must reliably prove who is permitted to mint and how much supply may exist. Protect every mint path with valid authorization and enforce a maximum supply so attackers cannot create arbitrary token balances.

Chat