Skip to content
Solidity

Modifiers and Access Control

Reuse validation logic with modifiers.

By EZ4Code Team
modifieraccess-controlsecurity

Code

contract AccessControl {
    address public owner;
    mapping(address => bool) public admins;
    uint256 public pausedAt;

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner");
        _;
    }

    modifier onlyAdmin() {
        require(admins[msg.sender], "Only admin");
        _;
    }

    modifier whenNotPaused() {
        require(pausedAt == 0, "Paused");
        _;
    }

    // Reentrancy guard (prevents reentrancy attacks)
    uint256 private _status;
    modifier nonReentrant() {
        require(_status != 2, "Reentrant");
        _status = 2;
        _;
        _status = 1;
    }

    constructor() {
        owner = msg.sender;
        _status = 1;
    }

    function addAdmin(address a) external onlyOwner {
        admins[a] = true;
    }

    function criticalOp() external onlyAdmin whenNotPaused nonReentrant {
        // ... sensitive logic
    }

    function pause() external onlyOwner {
        pausedAt = block.timestamp;
    }
}

Explanation

Modifiers wrap functions with reusable pre/post checks — _; marks where the function body runs. Common patterns: onlyOwner (access control), whenNotPaused (circuit breaker), nonReentrant (reentrancy guard — prevents callbacks during execution). Stack modifiers to combine. Always put nonReentrant on functions that call external contracts to prevent reentrancy attacks.

More Solidity Snippets