QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: low
Invalid

Mint Infinite and Burn Arbitrary in `LPNFT` Contract

Summary

The LPNFT contract contains a critical vulnerability that allows the router (a centralized entity specified during deployment) to mint an infinite number of NFTs and arbitrarily burn NFTs belonging to users without their consent. This flaw results from the unrestricted nature of the mint and burn functions, which rely solely on the onlyUpliftOnlyRouter modifier for access control. If the router is malicious or compromised, it could inflate the supply or destroy NFTs at will, undermining the integrity and security of the system.

Vulnerability Details

Root Cause

The issue arises due to:

  1. Unlimited Minting (mint)
    The mint function allows the router to create NFTs without a supply cap or any validation logic. This enables infinite token issuance, which can devalue existing tokens or disrupt accounting in systems where NFTs represent assets or liquidity.

    function mint(
    address _to
    ) public onlyUpliftOnlyRouter returns (uint256 tokenId) {
    tokenId = ++numMinted; // No limit on numMinted
    _mint(_to, tokenId);
    }
  2. Arbitrary Burning (burn)
    The burn function permits the router to destroy NFTs arbitrarily, regardless of ownership or user consent. There are no checks to ensure the caller owns the token being burned.

    function burn(uint256 _tokenId) public onlyUpliftOnlyRouter {
    _burn(_tokenId); // No validation of ownership
    }

Why It’s a Problem

  • Infinite Minting:
    Allows the router to create an unlimited number of tokens, diluting the value of existing NFTs and breaking any assumptions of scarcity or token accounting.

  • Arbitrary Burning:
    Allows the router to confiscate tokens belonging to legitimate users, resulting in financial losses or loss of functionality for token holders.

Impact

The vulnerability has significant implications:

  1. Inflation of NFTs:
    Unrestricted minting enables the creation of an unlimited number of NFTs, which can undermine market trust and devalue the tokens.

  2. Loss of Ownership:
    Arbitrary burning allows NFTs owned by legitimate users to be destroyed without their approval, resulting in irreversible losses.

  3. Centralization Risks:
    The reliance on a single router introduces a central point of failure. If the router is compromised or malicious, it can exploit these functions to harm users and the protocol.

  4. Economic Disruption:
    For systems where NFTs represent liquidity or pool shares, infinite minting and burning disrupt the token accounting, potentially causing insolvency or other systemic issues.

Proof of Concept

Test

  • Add the following test to pkg/pool-hooks/test/foundry/UpliftExample.t.sol:

function testMintInfiniteAndBurnArbitrary() public {
console2.logString('------------------------------------------');
console2.logString('1) Deploying LPNFT with address(this) as router');
LPNFT nft = new LPNFT('TestNFT', 'TNFT', address(this));
console2.log('LPNFT deployed at:', address(nft));
console2.logString('------------------------------------------\n');
console2.logString('2) Minting 5 NFTs to address(0xBEEF)...');
for (uint256 i = 0; i < 5; i++) {
// Mint NFT
uint256 tokenId = nft.mint(address(0xBEEF));
console2.log(' -> Minted token with ID =', tokenId);
}
console2.logString('------------------------------------------\n');
console2.logString('3) Burning tokenId=1 (owned by 0xBEEF)...');
nft.burn(1);
console2.logString(' -> Burned tokenId=1 successfully.');
console2.logString('------------------------------------------\n');
console2.logString('4) Checking final balance of 0xBEEF...');
uint256 userBalance = nft.balanceOf(address(0xBEEF));
console2.log(' -> 0xBEEF NFT balance is now =', userBalance);
require(userBalance == 4, 'FAIL: The user should have 4 NFTs after the burn');
console2.logString('SUCCESS: 0xBEEF has 4 NFTs after burning tokenId=1!');
console2.logString('------------------------------------------\n');
}

Test Result

Logs:
------------------------------------------
1) Deploying LPNFT with address(this) as router
LPNFT deployed at: 0x3381cD18e2Fb4dB236BF0525938AB6E43Db0440f
------------------------------------------
2) Minting 5 NFTs to address(0xBEEF)...
-> Minted token with ID = 1
-> Minted token with ID = 2
-> Minted token with ID = 3
-> Minted token with ID = 4
-> Minted token with ID = 5
------------------------------------------
3) Burning tokenId=1 (owned by 0xBEEF)...
-> Burned tokenId=1 successfully.
------------------------------------------
4) Checking final balance of 0xBEEF...
-> 0xBEEF NFT balance is now = 4
SUCCESS: 0xBEEF has 4 NFTs after burning tokenId=1!
------------------------------------------

Result:

  • The router successfully mints 5 NFTs for the user 0xBEEF.

  • It then burns tokenId 1 without any ownership validation.

  • After burning, the user retains 4 NFTs, confirming that the burn operation succeeds without user consent.

Tools Used

  • Foundry: Used to develop and run tests to validate the vulnerability.

  • Manual Code Review: Confirms the issue persists within the LPNFT contract where mint and burn only check for router authorization.

Recommendations

  1. Implement a Minting Cap:
    Add a maximum supply limit for NFTs to prevent infinite minting:

    require(numMinted < maxSupply, "Max supply reached");
  2. Enforce Ownership Checks in burn:
    Validate that only the owner of the token can burn it:

    function burn(uint256 _tokenId) external {
    require(ownerOf(_tokenId) == msg.sender, 'Not the owner');
    _burn(_tokenId);
    }
  3. Introduce Access Control:
    Use OpenZeppelin’s AccessControl to assign roles like MINTER_ROLE and BURNER_ROLE for minting and burning. This provides more granular control:

    function mint(address _to) external onlyRole(MINTER_ROLE) { ... }
    function burn(uint256 _tokenId) external onlyRole(BURNER_ROLE) { ... }
  4. Enable Router Replacement:
    Allow the router to be replaced via multisig or governance in case it is compromised:

    function setRouter(address newRouter) external onlyOwner { ... }

By applying these mitigations, the protocol can safeguard against infinite minting and unauthorized burns, ensuring the security and trust of users.

Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Informational or Gas / Admin is trusted / Pool creation is trusted / User mistake / Suppositions

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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

Give us feedback!