solidityethereumsecurityadvanced
Reentrancy Guard Pattern
Implement a reentrancy guard to prevent one of the most common smart contract attacks.
All snippets
Code
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
bool private _locked;
modifier nonReentrant() {
require(!_locked, "Reentrancy: locked");
_locked = true;
_;
_locked = false;
}
}
contract SafeVault is ReentrancyGuard {
mapping(address => uint256) public balances;
function deposit() external payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint256 amount) external nonReentrant {
require(balances[msg.sender] >= amount, "Insufficient");
balances[msg.sender] -= amount;
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "Failed");
}
}Explanation
Reentrancy is the most famous smart contract vulnerability (the DAO hack, 2016). A malicious contract re-enters a function before state is updated, draining funds.
How this guard works:
- A
_lockedboolean is settrueat function entry. - If the external call triggers a re-entry,
nonReentrantreverts. - The boolean resets after the function completes.
OpenZeppelin provides ReentrancyGuard — prefer it in production. Always combine with checks-effects-interactions.
securityreentrancyattackguard