★ Public initialize() without initializer modifier
Yearn Finance's assessment for RD-F-022 — scored yellow on the v1.7.0 rubric. The evidence below is the curator's reasoning for this score.
Evidence summary #
V3 VaultV3.vy exposes initialize() as an external function with a Vyper-native guard: assert self.asset == empty(address), 'initialized'. The __init__() constructor sets self.asset = self as a sentinel, preventing re-initialization. This is architecturally sound for Vyper but is not an OZ initializer modifier — Slither cannot detect it as protected. ChainSecurity audit confirmed no critical findings on initialization. Guard is confirmed from VaultV3.vy source inspection. Graded yellow because (a) Vyper-compiler-level bugs affecting initialization correctness cannot be ruled out without FV, and (b) the equivalence argument for the Vyper guard as an OZ initializer substitute relies on curator judgment.
Sources #
- URLChainSecurity Yearn V3 — no critical/high findings; two medium resolvedChainSecurity V3 audit — no critical findings on initializationretrieved 2026-05-16
- VaultV3.vy — assert self.asset == empty(address), 'initialized' guard in initialize()VaultV3.vy initialize() guardretrieved 2026-05-16
Methodology #
Determine whether any implementation contract exposes `initialize(…)` without the OpenZeppelin `initializer` modifier or equivalent initialization lock.
See the full factor methodology and distribution across all protocols →