57201 sc low missing collection expiry enforcement
Submitted on Oct 24th 2025 at 10:38:54 UTC by @OxPrince for Audit Comp | Belong
Report ID: #57201
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
Brief/Intro
The NFT contract persists the
collection_expirestimestamp during initialization (src/nft/nft.cairo:140-147) and exposes it through the publicnftParametersgetter (src/nft/nft.cairo:181-183), signalling to integrators that the collection has an on-chain expiry.Neither minting path (
mintDynamicPrice/mintStaticPrice) nor their internal helpers ever read this field (src/nft/nft.cairo:254-347); there is also no alternate entry point that enforces the deadline.As a result, any caller that obtained a valid mint signature before the advertised deadline can continue minting indefinitely after the sale should have closed, up to
max_total_supply. This contradicts the intended lifecycle and misleads downstream integrations that rely on the expiry field.
Vulnerability Details
collection_expires is written to storage when the factory initializes a collection (src/nft/nft.cairo:140-147) and recorded in the factory flow as part of NftParameters (src/nftfactory/nftfactory.cairo:304-334).
The minting helpers
_mint_dynamic_price_batchand_mint_static_price_batchonly validate signatures, payment tokens, and prices before minting (src/nft/nft.cairo:254-347). They never consultcollection_expires, nor is there any timestamp verification elsewhere in the contract.Tests assert that
collection_expiresis returned fromnftParameters()(src/tests/test_nft.cairo:189-207), reinforcing that the expiry is expected to be meaningful, yet no behavioural test exercises an expiry guard.
Impact Details
A buyer who received a valid pre-signed mint authorization (static or dynamic price) can wait until after the expected deadline and continue minting tokens as long as supply remains. This extends sales windows, defeats time-limited scarcity, and can lead to unexpected revenue splits or regulatory exposure for creators relying on time-boxed raises.
Because the expiry is stored on-chain and surfaced in the ABI, integrators are likely to treat it as authoritative.
References
Add any relevant links to documentation or code
Proof of Concept
The following PoC demonstrates a test that creates a collection with an expiry, waits past that expiry, and successfully mints using a pre-signed static-price authorization — showing expiry is not enforced.
Notes for remediation (not exhaustive):
Enforce
collection_expiresin the minting paths by comparing current block timestamp to the stored expiry before accepting a signed mint.Ensure both single and batch mint helpers consult the expiry.
Consider adding tests that assert minting fails after expiry for both static and dynamic flows.
Was this helpful?