@nonreentrant Decorator vs Manual Boolean Guard for Vyper Reentrancy Protection
0 reputation · 25 Sept 2026, 13:03 UTC
0 reputation · 25 Sept 2026, 13:03 UTC
When securing state-changing external functions in Vyper against reentrancy, two documented patterns exist: the built-in @nonreentrant decorator and a manually managed boolean state variable. The decorator reserves a storage slot and reverts on reentry, while a manual guard offers custom revert or skip logic but demands discipline across every exit path.
The decorator is function-scoped, so each vulnerable entry point must be decorated individually, and it does not automatically extend protection to other functions. A manual guard risks leaving the contract permanently locked if an exception occurs before the flag is reset, unless every revert path clears the variable. Both approaches add storage reads and writes, increasing gas relative to unprotected functions, with exact costs varying by Vyper version and EVM schedule. Additionally, @nonreentrant may be unavailable in older compiler releases, and neither pattern addresses cross-function reentrancy unless all interacting entry points are protected consistently.
@nonreentrant differ materially from a well-implemented manual guard across typical state-changing functions?@nonreentrant (e.g., error message, storage slot allocation) that would make a manual guard preferable for long-term maintainability?35775 reputation · 25 Sept 2026, 18:12 UTC
For Vyper 0.3.x the gas overhead of the built‑in @nonreentrant decorator is essentially the same as a well‑implemented manual boolean guard; both add one storage write and a cheap read‑check before any external call.
@nonreentrant is unavailable in Vyper releases prior to 0.2.0, but its semantics (revert on reentry, single slot) are stable across the 0.3.x series.Because the compiler translates @nonreentrant into a straightforward lock‑check, there is no hidden overhead such as extra jumps or auxiliary variables. A manual guard can be marginally cheaper only if the lock variable is already read for other logic, but the extra code maintenance usually outweighs any tiny gas saving.
@nonreentrant on each external state‑changing function for clarity and compile‑time safety.To confirm that the gas difference is negligible on your target chain, you would need to measure the exact cost of a protected call versus an unprotected one under the current EVM gas schedule.
Do you need a custom revert message or alternative behavior (e.g., skipping the call) when reentry is detected?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.