Add ERC165 interface detection to AccessControl (#2562)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
(cherry picked from commit 29ffe6f426)
This commit is contained in:
@ -3,6 +3,18 @@
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../utils/Context.sol";
|
||||
import "../utils/introspection/ERC165.sol";
|
||||
|
||||
/**
|
||||
* @dev External interface of AccessControl declared to support ERC165 detection.
|
||||
*/
|
||||
interface IAccessControl {
|
||||
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 account) external;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Contract module that allows children to implement role-based access
|
||||
@ -42,7 +54,7 @@ import "../utils/Context.sol";
|
||||
* grant and revoke this role. Extra precautions should be taken to secure
|
||||
* accounts that have been granted it.
|
||||
*/
|
||||
abstract contract AccessControl is Context {
|
||||
abstract contract AccessControl is Context, IAccessControl, ERC165 {
|
||||
struct RoleData {
|
||||
mapping (address => bool) members;
|
||||
bytes32 adminRole;
|
||||
@ -79,10 +91,18 @@ abstract contract AccessControl is Context {
|
||||
*/
|
||||
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
|
||||
|
||||
/**
|
||||
* @dev See {IERC165-supportsInterface}.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
||||
return interfaceId == type(IAccessControl).interfaceId
|
||||
|| super.supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns `true` if `account` has been granted `role`.
|
||||
*/
|
||||
function hasRole(bytes32 role, address account) public view returns (bool) {
|
||||
function hasRole(bytes32 role, address account) public view override returns (bool) {
|
||||
return _roles[role].members[account];
|
||||
}
|
||||
|
||||
@ -92,7 +112,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* To change a role's admin, use {_setRoleAdmin}.
|
||||
*/
|
||||
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
|
||||
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
|
||||
return _roles[role].adminRole;
|
||||
}
|
||||
|
||||
@ -106,7 +126,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* - the caller must have ``role``'s admin role.
|
||||
*/
|
||||
function grantRole(bytes32 role, address account) public virtual {
|
||||
function grantRole(bytes32 role, address account) public virtual override {
|
||||
require(hasRole(getRoleAdmin(role), _msgSender()), "AccessControl: sender must be an admin to grant");
|
||||
|
||||
_grantRole(role, account);
|
||||
@ -121,7 +141,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* - the caller must have ``role``'s admin role.
|
||||
*/
|
||||
function revokeRole(bytes32 role, address account) public virtual {
|
||||
function revokeRole(bytes32 role, address account) public virtual override {
|
||||
require(hasRole(getRoleAdmin(role), _msgSender()), "AccessControl: sender must be an admin to revoke");
|
||||
|
||||
_revokeRole(role, account);
|
||||
@ -141,7 +161,7 @@ abstract contract AccessControl is Context {
|
||||
*
|
||||
* - the caller must be `account`.
|
||||
*/
|
||||
function renounceRole(bytes32 role, address account) public virtual {
|
||||
function renounceRole(bytes32 role, address account) public virtual override {
|
||||
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
|
||||
|
||||
_revokeRole(role, account);
|
||||
|
||||
Reference in New Issue
Block a user