Missing call to _disableInitializers in several upgradeable contracts
MATToken, MatchConfig, StakingPoolFactory, and StakingPool implementations omit _disableInitializers() in their constructors. The implementation contracts themselves remain initializable, allowing direct initialization by an attacker.
Description
Several upgradeable contracts MATToken, MatchConfig, StakingPoolFactory and StakingPool do not implement the _disableInitializers() function in their constructors, while others LiquidStakingPool.sol and FeeDistributionVault.sol do implement it correctly.
This inconsistency creates a security vulnerability where the implementation contracts of MATToken and StakingPool could potentially be initialized directly by an attacker.
When an upgradeable contract doesn't call _disableInitializers() in its constructor, the implementation contract itself remains initializable.
If an attacker initializes the implementation contract directly (not through the proxy), they could potentially gain control over it.
This is a known security issue with upgradeable contracts that OpenZeppelin explicitly warns about in their documentation.
The proper pattern, as seen in LiquidStakingPool.sol and FeeDistributionVault.sol, is:
/// @custom:oz-upgrades-unsafe-allow constructorconstructor() {_disableInitializers();}
Impact
While the proxy contracts are safe (they're initialized via the upgradeable pattern), the implementation contracts deployed at deterministic addresses can be initialized by an attacker. In the worst case, this lets the attacker assume the implementation's owner role, although they cannot affect the proxy state.
Recommendation
Add a constructor with _disableInitializers() to all upgradeable contracts in the protocol, specifically to MATToken and StakingPool:
/// @custom:oz-upgrades-unsafe-allow constructorconstructor() {_disableInitializers();}

