# vyper empty string nonreentrant key silently produces no reentrancy checks at runtime CVE-2023-42441: when the `@nonreentrant` lock key is an empty string (`@nonreentrant("")`), the compiler silently omits all lock code from bytecode. The function compiles without error, the decorator appears in place, but no lock is acquired or checked at runtime. The compiler's code generation treated the empty string as a valid key but produced no storage slot allocation or lock/unlock opcodes, effectively a no-op decorator. This is a "Class D: Silent Semantic Mismatch" where code appears valid, compiles without warnings, but runtime behavior differs from developer intent. Affected versions: v0.2.9 through v0.3.10. The fix in v0.3.10 added input validation rejecting invalid identifiers as nonreentrant keys (empty strings, whitespace-only strings, digit-starting strings). Contracts compiled with affected versions using empty string keys are fully vulnerable despite appearing protected. This would not be caught by source-level review; only bytecode inspection or compiler-version-aware tooling reveals the missing lock. Since [[reentrancy is possible whenever external calls precede state updates]], any contract relying on an empty-string `@nonreentrant` rather than the [[checks-effects-interactions pattern prevents reentrancy by updating state before external calls|checks-effects-interactions pattern]] is directly exploitable. --- Relevant Notes: - [[reentrancy is possible whenever external calls precede state updates]]: the vulnerability class left unprotected by this bug - [[checks-effects-interactions pattern prevents reentrancy by updating state before external calls]]: defense that works regardless of decorator correctness - [[vyper compiler reentrancy lock storage slot bug broke cross-function reentrancy protection in versions 0.2.15 through 0.3.0]]: another @nonreentrant decorator bug with a different mechanism - [[vyper nonreentrant decorator uses a single global storage lock eliminating cross-function reentrancy by design in versions 0.4.0 and later]]: the redesigned system that eliminates named lock keys entirely - [[vyper default function did not respect nonreentrancy decorator prior to v0.3.0 allowing reentrancy through the fallback path]]: a third @nonreentrant failure from the same era - [[explicit returns from solidity modifiers do not affect function return values allowing silent control flow bypasses]]: analogous silent semantic mismatch: code that appears to enforce a constraint but silently fails Topics: - [[vulnerability-patterns]]