Missing _disableInitializers() call in KnowledgeMarketV2 constructor
The implementation contract constructor lacks _disableInitializers(), letting the implementation itself be initialized directly. In upgradeable patterns only the proxy should call initialize().
Description
The implementation contract constructor lacks the _disableInitializers() call, allowing the implementation contract itself to be initialized directly. In upgradeable proxy patterns, the implementation contract should never be initialized; only the proxy should call the initialize() function.
Without _disableInitializers(), an attacker could potentially initialize the implementation contract directly, which could lead to unexpected behavior or serve as a stepping stone for more complex attacks.
The current constructor only calls the parent ERC4908 constructor but doesn't prevent initialization:
constructor() ERC4908("Knowledge Market Access", "KMA") {}
Impact
Implementation contract can be directly initialized by anyone, potentially altering implementation-context state in ways that can serve as a foothold for further attacks.
Recommendation
Add _disableInitializers() to the constructor to prevent direct initialization of the implementation contract:
constructor() ERC4908("Knowledge Market Access", "KMA") {_disableInitializers();}
Resolution
Ipal Network: Confirmed. We agreed with the recommendation and have added the _disableInitializers() call to the constructor of our main implementation contract.
Zealynx: Not Fixed: The actual implementation contract KnowledgeMarket.sol still lacks _disableInitializers() in its constructor. The fix exists only in the empty KnowledgeMarketV2.sol contract that has no business logic.
UPDATE: Fixed.

