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 | Belongarrow-up-right

  • 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.

circle-info

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

chevron-rightPoC: Hardhat test demonstrating mint after expiry (v1)hashtag

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?