Secure Smart Contract library for Solidity with battle-tested implementations of token standards, access control, governance, and essential utilities for building decentralized applications.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive access control mechanisms including single-owner patterns and flexible role-based access control systems for secure smart contract administration.
Simple ownership model with transfer and renouncement capabilities for contracts requiring single administrator access.
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*/
abstract contract Ownable is Context {
/**
* @dev Sets the initial owner to the address provided by the deployer
*/
constructor(address initialOwner);
/**
* @dev Returns the address of the current owner
*/
function owner() public view virtual returns (address);
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`)
* Can only be called by the current owner
*/
function transferOwnership(address newOwner) public virtual onlyOwner;
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner
*/
function renounceOwnership() public virtual onlyOwner;
/**
* @dev Throws if called by any account other than the owner
*/
modifier onlyOwner();
}Usage Example:
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyContract is Ownable {
uint256 private _value;
constructor(address initialOwner) Ownable(initialOwner) {}
function setValue(uint256 newValue) public onlyOwner {
_value = newValue;
}
function getValue() public view returns (uint256) {
return _value;
}
}Enhanced ownership pattern that requires new owner acceptance to prevent accidental transfers to invalid addresses.
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions, and ownership transfer is a two-step process.
*/
abstract contract Ownable2Step is Ownable {
/**
* @dev Returns the address of the pending owner
*/
function pendingOwner() public view virtual returns (address);
/**
* @dev Starts the ownership transfer of the contract to a new account
* Replaces the pending transfer if there is one
*/
function transferOwnership(address newOwner) public virtual override onlyOwner;
/**
* @dev The new owner accepts the ownership transfer
*/
function acceptOwnership() public virtual;
}Usage Example:
import "@openzeppelin/contracts/access/Ownable2Step.sol";
contract SecureContract is Ownable2Step {
constructor(address initialOwner) Ownable(initialOwner) {}
// Contract functions requiring ownership
function sensitiveOperation() public onlyOwner {
// Protected operation
}
}
// Transfer process:
// 1. Current owner calls transferOwnership(newOwnerAddress)
// 2. New owner calls acceptOwnership() to complete transferFlexible role-based access control system supporting multiple roles with hierarchical administration.
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. Roles are referred to by their `bytes32` identifier.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
/**
* @dev Returns `true` if `account` has been granted `role`
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool);
/**
* @dev Returns the admin role that controls `role`
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32);
/**
* @dev Grants `role` to `account`
* If `account` had not been already granted `role`, emits a {RoleGranted} event
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role));
/**
* @dev Revokes `role` from `account`
* If `account` had been granted `role`, emits a {RoleRevoked} event
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role));
/**
* @dev Revokes `role` from the calling account
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual;
/**
* @dev Sets `adminRole` as ``role``'s admin role
* Internal function without access restriction
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual;
/**
* @dev Grants `role` to `account`
* Internal function without access restriction
*/
function _grantRole(bytes32 role, address account) internal virtual;
/**
* @dev Revokes `role` from `account`
* Internal function without access restriction
*/
function _revokeRole(bytes32 role, address account) internal virtual;
/**
* @dev Modifier that checks that an account has a specific role
*/
modifier onlyRole(bytes32 role);
}Usage Example:
import "@openzeppelin/contracts/access/AccessControl.sol";
contract MyContract is AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
constructor(address defaultAdmin) {
_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
}
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
// Minting logic
}
function burn(uint256 amount) public onlyRole(BURNER_ROLE) {
// Burning logic
}
function setupRoles(address minter, address burner) public onlyRole(DEFAULT_ADMIN_ROLE) {
_grantRole(MINTER_ROLE, minter);
_grantRole(BURNER_ROLE, burner);
}
}Advanced access control features including enumerable roles and default admin rules.
// Enumerable Access Control - Track role members
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
/**
* @dev Returns one of the accounts that have `role`
*/
function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address);
/**
* @dev Returns the number of accounts that have `role`
*/
function getRoleMemberCount(bytes32 role) public view virtual returns (uint256);
/**
* @dev Returns an array of all accounts that have `role`
*/
function getRoleMembers(bytes32 role) public view virtual returns (address[] memory);
}
// Default Admin Rules - Enhanced admin role management
abstract contract AccessControlDefaultAdminRules is IAccessControlDefaultAdminRules, AccessControl {
/**
* @dev Returns the address of the current default admin
*/
function defaultAdmin() public view virtual returns (address);
/**
* @dev Returns the address of the pending default admin
*/
function pendingDefaultAdmin() public view virtual returns (address);
/**
* @dev Returns the remaining time in seconds until the default admin transfer delay ends
*/
function defaultAdminDelayIncreaseWait() public view virtual returns (uint48);
/**
* @dev Starts a default admin transfer by setting a pending default admin
*/
function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE);
/**
* @dev Accepts the pending default admin transfer
*/
function acceptDefaultAdminTransfer() public virtual;
/**
* @dev Cancels a pending default admin transfer
*/
function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE);
}Advanced access management system for complex authorization scenarios with time-based controls.
/**
* @dev AccessManager is a central contract to store the permissions of a system.
* It provides a flexible and modular access control mechanism.
*/
contract AccessManager is Context, Multicall, IAccessManager {
/**
* @dev Check if an account can perform an operation
*/
function canCall(address caller, address target, bytes4 selector) public view virtual returns (bool immediate, uint32 delay);
/**
* @dev Get the role of an account
*/
function getAccess(uint64 roleId, address account) public view virtual returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);
/**
* @dev Grant a role to an account
*/
function grantRole(uint64 roleId, address account, uint32 executionDelay) public virtual onlyAuthorized;
/**
* @dev Revoke a role from an account
*/
function revokeRole(uint64 roleId, address account) public virtual onlyAuthorized;
/**
* @dev Set the role required to call a function
*/
function setTargetFunctionRole(address target, bytes4[] calldata selectors, uint64 roleId) public virtual onlyAuthorized;
/**
* @dev Schedule an operation that is subject to a delay
*/
function schedule(address target, bytes calldata data, uint48 when) public virtual returns (bytes32 operationId);
/**
* @dev Execute a scheduled operation
*/
function execute(address target, bytes calldata data) public payable virtual returns (bytes32 operationId);
/**
* @dev Cancel a scheduled operation
*/
function cancel(address caller, address target, bytes calldata data) public virtual returns (bytes32 operationId);
}// Core Access Control Interface
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address callerConfirmation) external;
}
// Enumerable Access Control Interface
interface IAccessControlEnumerable is IAccessControl {
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}
// Default Admin Rules Interface
interface IAccessControlDefaultAdminRules is IAccessControl {
event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule);
event DefaultAdminTransferCanceled();
event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule);
event DefaultAdminDelayChangeCanceled();
function defaultAdmin() external view returns (address);
function pendingDefaultAdmin() external view returns (address, uint48);
function defaultAdminDelay() external view returns (uint48);
function pendingDefaultAdminDelay() external view returns (uint48, uint48);
function defaultAdminDelayIncreaseWait() external view returns (uint48);
}
// Access Manager Interface
interface IAccessManager {
event RoleGranted(uint64 indexed roleId, address indexed account, uint32 delay, uint48 since, address indexed caller);
event RoleRevoked(uint64 indexed roleId, address indexed account, address indexed caller);
event OperationScheduled(bytes32 indexed operationId, uint32 indexed nonce, uint48 schedule, address caller, address target, bytes data);
event OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce, address caller, address target, bytes data);
event OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce, address caller, address target, bytes data);
function canCall(address caller, address target, bytes4 selector) external view returns (bool allowed, uint32 delay);
function expiration() external view returns (uint32);
function minSetback() external view returns (uint32);
function isTargetClosed(address target) external view returns (bool);
function getTargetFunctionRole(address target, bytes4 selector) external view returns (uint64);
function getAccess(uint64 roleId, address account) external view returns (uint48, uint32, uint32, uint48);
function hasRole(uint64 roleId, address account) external view returns (bool, uint32);
}import "@openzeppelin/contracts/access/Ownable.sol";
contract SimpleContract is Ownable {
mapping(address => bool) public authorized;
constructor(address initialOwner) Ownable(initialOwner) {}
function authorizeUser(address user) public onlyOwner {
authorized[user] = true;
}
function revokeUser(address user) public onlyOwner {
authorized[user] = false;
}
function protectedFunction() public {
require(authorized[msg.sender], "Not authorized");
// Function logic
}
}import "@openzeppelin/contracts/access/AccessControl.sol";
contract MultiRoleContract is AccessControl {
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
bytes32 public constant USER_ROLE = keccak256("USER_ROLE");
constructor(address defaultAdmin) {
_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
_grantRole(ADMIN_ROLE, defaultAdmin);
// Set role hierarchy
_setRoleAdmin(OPERATOR_ROLE, ADMIN_ROLE);
_setRoleAdmin(USER_ROLE, OPERATOR_ROLE);
}
function adminFunction() public onlyRole(ADMIN_ROLE) {
// Admin-only functionality
}
function operatorFunction() public onlyRole(OPERATOR_ROLE) {
// Operator functionality
}
function userFunction() public onlyRole(USER_ROLE) {
// User functionality
}
}import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract HybridAccessContract is Ownable, AccessControl {
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
constructor(address initialOwner) Ownable(initialOwner) {
_grantRole(DEFAULT_ADMIN_ROLE, initialOwner);
}
// Owner can grant roles
function grantManagerRole(address account) public onlyOwner {
grantRole(MANAGER_ROLE, account);
}
// Managers can perform operations
function manageOperation() public onlyRole(MANAGER_ROLE) {
// Management functionality
}
// Owner retains ultimate control
function emergencyFunction() public onlyOwner {
// Emergency functionality
}
}Install with Tessl CLI
npx tessl i tessl/npm-openzeppelin--contracts