Constructor calls _disableInitializers()
A code & audits factor in the v1.7.0 rubric. Measured per protocol on a s cadence.
Methodology how we score #
**What this measures** This factor verifies that implementation contracts in the protocol's upgradeable proxy architecture call _disableInitializers() in their constructor, following the OpenZeppelin-recommended pattern to prevent direct initialization of the implementation contract itself. When _disableInitializers() is called in the constructor, the implementation contract's initializer is permanently locked at deployment time, preventing any subsequent caller from re-initializing it. The assessment is performed by static analysis of the implementation contract's constructor bytecode.
**Why it matters** The _disableInitializers() constructor call is the defense-in-depth complement to the initializer modifier (assessed by RD-F-022). Even if an initializer modifier is present, a missing _disableInitializers() call in the constructor leaves a narrow race-condition window at deploy time where the implementation can be initialized directly before the proxy is set up. More importantly, it prevents the class of attack where a future OpenZeppelin library upgrade or a missed initializer modifier on a newly added initializer function creates a new unguarded entry point. The pattern was introduced precisely because the modifier alone was insufficient in complex inheritance hierarchies.
**Green / Yellow / Red** Green: all implementation contracts call _disableInitializers() in their constructor, confirmed by bytecode analysis of the deployed implementation. Yellow: the constructor does not call _disableInitializers() but all initialize() functions carry the initializer modifier, reducing -- but not eliminating -- the risk. Red: the constructor omits _disableInitializers() AND any initialize() function is missing the initializer modifier (this overlaps with RD-F-022 Red).
**Common gray cases** This factor is gray for non-upgradeable protocols that do not use proxy patterns, or for protocols whose constructors cannot be inspected (unverified source).
**Notable historical examples** The factor operates as a defense-in-depth check alongside RD-F-022, which captures the more common failure mode.
Measurement what to look for #
Determine whether implementation contract constructors call `_disableInitializers()` to prevent re-initialization of the implementation directly.