For the complete documentation index, see llms.txt. This page is also available as Markdown.

57505 sc low missing collection expiration enforcement allows unauthorized minting

Submitted on Oct 26th 2025 at 20:04:28 UTC by @Rhaydden for Audit Comp | Belong

  • Report ID: #57505

  • Report Type: Smart Contract

  • Report severity: Low

  • Target: https://github.com/immunefi-team/audit-comp-belong/blob/feat/cairo/src/nft/nft.cairohttps://github.com/immunefi-team/audit-comp-belong/blob/feat/cairo/src/nft/nft.cairo

  • Impacts:

    • Unauthorized minting of NFTs

Description

Issue description

Both implementations (Cairo and Solidity v1/v2) store a collection-level expiration timestamp but never enforce it during minting.

  • Cairo:

    • The collection expiration is stored but not used. It's defined here: https://github.com/immunefi-team/audit-comp-belong//blob/a17f775dcc4c125704ce85d4e18b744daece65af/src/nft/interface.cairo#L14-L15

        pub collection_expires: u256, // Collection expiration period (timestamp)
    • It's set on deploy here: https://github.com/immunefi-team/audit-comp-belong//blob/a17f775dcc4c125704ce85d4e18b744daece65af/src/nftfactory/nftfactory.cairo#L304

        collection_expires: info.collection_expires,
    • It is not validated in minting in the following parts of the protocol:

      • src/nft/nft.cairo: _mint_dynamic_price_batch https://github.com/immunefi-team/audit-comp-belong//blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v1/NFT.sol#L152-L181

      • src/nft/nft.cairo: _mint_static_price_batch https://github.com/immunefi-team/audit-comp-belong//blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v1/NFT.sol#L191-L214

      • src/nft/nft.cairo: _base_mint (here it only checks max_total_supply) https://github.com/immunefi-team/audit-comp-belong//blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v1/NFT.sol#L287-L297

  • Solidity v1:

    • Defined in contracts/v1/Structures.sol: https://github.com/immunefi-team/audit-comp-belong//blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v1/Structures.sol#L33

        uint256 collectionExpire;
    • Not validated in minting:

      • contracts/v1/NFT.sol mintStaticPrice L152–181

      • contracts/v1/NFT.sol mintDynamicPrice L191–214

      • contracts/v1/NFT.sol _baseMint L287–297 (only supply cap)

    • No use of block.timestamp in those mint flows.

  • Solidity v2 (AccessToken):

    • Defined in contracts/v2/Structures.sol: https://github.com/immunefi-team/audit-comp-belong//blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v2/Structures.sol#L32-L33

        uint256 collectionExpire;
    • Not validated in minting:

      • contracts/v2/tokens/AccessToken.sol mintStaticPrice L173-L199

      • contracts/v2/tokens/AccessToken.sol mintDynamicPrice L209-L230

      • contracts/v2/tokens/AccessToken.sol _baseMint L302-L310 (only supply cap)

Because of the missing on-chain check, collections intended to be time-bound can be minted indefinitely after the intended expiration.

Impact

Critical - Unauthorized minting of NFTs The protocol intends to prevent mints after a deadline but does not enforce it on chain, allowing mints that should be disallowed.

Enforce collection expiration at mint-time. Treat 0 as “no expiry”.

  • Cairo:

    • In _base_mint or the relevant mint entrypoints, revert if collection_expires != 0 and now > collection_expires.

  • Solidity v1/v2:

    • Prefer centralizing the check in _baseMint:

Proof of Concept

PoC: Hardhat test demonstrating mint after expiry (v1)

I added a focused Hardhat test that deploys a v1 NFT with collectionExpire in the past and mints successfully.

Create a file named test/v1/nft_expiry_poc.test.ts and paste the PoC below in it. The test deploys v1 NFT with collectionExpire = 1 (past), then mints via mintStaticPrice. The mint succeeds and ownerOf(0) equals the minter.

Run test with:

Logs

Was this helpful?