Last Man Standing

First Flight #45
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Manual Reentrancy Guard

The contract implements a custom reentrancy guard using a `_locked` boolean variable. While functional, this approach duplicates the functionality already provided by the well-audited `ReentrancyGuard` from OpenZeppelin, introducing potential maintenance and audit risk for no benefit.

Description

Solidity developers commonly use the ReentrancyGuard from OpenZeppelin — a trusted and battle-tested implementation — to protect critical functions from reentrancy attacks.

Instead of using that, this contract manually defines:
bool private _locked; and creates a custom nonReentrant modifier to manage this state.

While technically valid, re-implementing this behavior is unnecessary and increases the surface area for human error. It's also less readable and harder to maintain compared to the OpenZeppelin standard.

Root + Impact

#Risk
Likelihood:

Every time a function with nonReentrant is called, this logic is engaged.

Since this pattern is re-implemented manually, developers may overlook nuanced edge cases or introduce bugs when modifying or extending it.

Impact:

Increases maintenance burden by duplicating existing security patterns.

Risk of inconsistent implementation if the logic is reused or modified elsewhere.

Potential loss of trust from auditors and users familiar with OpenZeppelin standards.

Proof Of Concept

modifier nonReentrant() {
require(!_locked, "ReentrancyGuard: reentrant call");
_locked = true;
_;
_locked = false;
}
// ...with the standard OpenZeppelin approach:
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract Game is Ownable, ReentrancyGuard {
function claimThrone() external nonReentrant { ... }
}

Explanation:
This duplication of critical security functionality introduces unnecessary complexity and risk. Using OpenZeppelin's library would simplify the codebase and align with industry best practices.

Recommended Mitigation

- modifier nonReentrant() {
- require(!_locked, "ReentrancyGuard: reentrant call");
- _locked = true;
- _;
- _locked = false;
- }
+ import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
+ contract Game is Ownable, ReentrancyGuard {
+ // Use inherited nonReentrant modifier from OpenZeppelin
+ }

Explanation:
This replacement removes the need to manually manage lock state and aligns with widely audited standards. It improves readability, reduces gas slightly, and simplifies future security reviews.

Updates

Appeal created

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.