F-2025-0012·missing-validation

Missing active subscription validation in mint function leads to accidental duplicate purchases

Fixednfterc721erc20
TL;DR

The mint function lacks validation to prevent users from purchasing multiple subscriptions for the same vault while they already have active access, allowing accidental duplicate paid purchases.

Severity
LOW
Impact
LOW
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
LOW
Exploitability
LOW
02Section · Description

Description

The mint function lacks validation to prevent users from purchasing multiple subscriptions for the same vault while they already have active access. This allows users to accidentally waste funds by purchasing redundant access to content they can already access.

The current implementation only checks if a subscription offering exists but does not verify whether the recipient already has active access to that vault:

solidity
function mint(
address payable vaultOwner,
string calldata vaultId,
address to
) public payable nonReentrant {
// ... validation checks ...
bytes32 hash = _hash(vaultOwner, vaultId);
if (!this.existAccess(hash)) revert MintUnavailable(hash);
// Missing: Check if `to` already has active access
// Always mints new NFT and charges user regardless of existing access
_safeMint(to, tokenId);
}

This enables scenarios where users can accidentally purchase the same subscription multiple times, paying full price each time for access they already possess.

03Section · Impact

Impact

User funds wasted on redundant subscriptions and a poor UX where mistaken or repeated UI clicks lead to multiple paid purchases for the same vault.

04Section · Recommendation

Recommendation

Add a validation check to prevent minting when the user already has active access to the vault:

solidity
function mint(...) public payable nonReentrant {
// ... existing validation checks ...
bytes32 hash = _hash(vaultOwner, vaultId);
if (!this.existAccess(hash)) revert MintUnavailable(hash);
// NEW: Prevent minting if user already has active access
(bool hasActiveAccess,,) = this.hasAccess(vaultOwner, vaultId, to);
if (hasActiveAccess) revert AlreadyHasActiveAccess();
// ... rest of minting logic ...
}

Additionally, implement a custom error AlreadyHasActiveAccess().

05Section · Resolution

Resolution

Ipal Network: Confirmed. We agreed with the recommendation and have added a validation check to the mint function.

Zealynx: Fixed. Added active subscription validation in the mint function to prevent users from accidentally purchasing duplicate access to the same vault while they already have active access.

Status
Fixed
F-2025-0012

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx