F-2025-0003·missing-visibility-restriction

Public setAccess function bypasses business logic validation enabling direct vault manipulation

Fixednfterc721erc20
TL;DR

The setAccess function on ERC4908 is declared public, letting any address modify vault access controls directly and create state inconsistencies with the higher-level KnowledgeMarketV2 subscription tracking.

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

Description

The setAccess function is declared as public, allowing any address to directly manipulate access control settings for any resource ID, bypassing the intended business logic and state management implemented in the higher-level KnowledgeMarketV2 contract.

Vulnerable Scenario:

The following steps help understand the issue:

  1. Alice creates a premium knowledge vault "alice-course-123" and sets up a paid subscription through the platform.
  2. Bob identifies Alice's vault ID and calls setAccess("alice-course-123", 0, 0, address(0), 0) directly on the ERC4908 contract.
  3. Bob's call bypasses all validation and state management in setSubscription, making Alice's premium content free.
  4. The platform's subscription tracking remains unchanged, creating inconsistency between business logic state and access control state.
  5. Users can now mint access NFTs for free while the platform still shows Alice's original subscription settings.
03Section · Impact

Impact

Enables direct manipulation of vault access controls while bypassing business logic validation and state management, creating inconsistencies between the platform's subscription tracking and actual access permissions, and allowing attackers to undermine vault monetization without updating associated metadata.

04Section · Recommendation

Recommendation

Change the setAccess function visibility from public to internal to prevent direct external calls and force all access control modifications to go through the validated business logic layer:

solidity
function setAccess(
string calldata resourceId,
uint256 price,
uint32 expirationDuration,
address coOwner,
uint32 splitFee
) internal { // Changed from public to internal
_setAccess(msg.sender, resourceId, price, expirationDuration, coOwner, splitFee);
}
05Section · Resolution

Resolution

Ipal Network: Confirmed. We agreed with the recommendation and have updated the setAccess function's visibility from public to internal.

Zealynx: Fixed. The setAccess function visibility changed from public to internal, preventing direct external manipulation and forcing all access control changes through proper business logic validation.

Status
Fixed
F-2025-0003

oog
zealynx

Smart Contract Security Digest

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

© 2026 Zealynx