mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
184 lines
5.0 KiB
Solidity
184 lines
5.0 KiB
Solidity
pragma solidity 0.6.12;
|
|
|
|
import {IPermissionManager} from '../../interfaces/IPermissionManager.sol';
|
|
import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol';
|
|
|
|
/**
|
|
* @title PermissionManager contract
|
|
* @notice Implements basic whitelisting functions for different actors of the permissioned protocol
|
|
|
|
* @author Aave
|
|
**/
|
|
contract PermissionManager is IPermissionManager, Ownable {
|
|
struct UserData {
|
|
uint256 permissions;
|
|
address permissionAdmin;
|
|
}
|
|
|
|
mapping(address => UserData) _users;
|
|
mapping(address => uint256) _permissionsAdmins;
|
|
|
|
uint256 public constant MAX_NUM_OF_ROLES = 256;
|
|
|
|
modifier onlyPermissionAdmins(address user) {
|
|
require(_permissionsAdmins[user] > 0, 'CALLER_NOT_PERMISSIONS_ADMIN');
|
|
_;
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function addPermissionAdmins(address[] calldata admins) external override onlyOwner {
|
|
for (uint256 i = 0; i < admins.length; i++) {
|
|
_permissionsAdmins[admins[i]] = 1;
|
|
|
|
emit PermissionsAdminSet(admins[i], true);
|
|
}
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function removePermissionAdmins(address[] calldata admins) external override onlyOwner {
|
|
for (uint256 i = 0; i < admins.length; i++) {
|
|
_permissionsAdmins[admins[i]] = 0;
|
|
|
|
emit PermissionsAdminSet(admins[i], false);
|
|
}
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function addPermissions(uint256[] calldata roles, address[] calldata users)
|
|
external
|
|
override
|
|
onlyPermissionAdmins(msg.sender)
|
|
{
|
|
require(roles.length == users.length, 'INCONSISTENT_ARRAYS_LENGTH');
|
|
|
|
for (uint256 i = 0; i < users.length; i++) {
|
|
uint256 role = roles[i];
|
|
address user = users[i];
|
|
|
|
require(role < MAX_NUM_OF_ROLES, 'INVALID_ROLE');
|
|
|
|
uint256 permissions = _users[user].permissions;
|
|
address permissionAdmin = _users[user].permissionAdmin;
|
|
|
|
require(
|
|
(permissions != 0 && permissionAdmin == msg.sender) ||
|
|
_users[user].permissionAdmin == address(0),
|
|
'INVALID_PERMISSIONADMIN'
|
|
);
|
|
|
|
if (permissions == 0) {
|
|
_users[user].permissionAdmin = msg.sender;
|
|
}
|
|
|
|
_users[user].permissions = permissions | (1 << role);
|
|
|
|
emit RoleSet(user, role, msg.sender, true);
|
|
}
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function removePermissions(uint256[] calldata roles, address[] calldata users)
|
|
external
|
|
override
|
|
onlyPermissionAdmins(msg.sender)
|
|
{
|
|
require(roles.length == users.length, 'INCONSISTENT_ARRAYS_LENGTH');
|
|
|
|
for (uint256 i = 0; i < users.length; i++) {
|
|
uint256 role = roles[i];
|
|
address user = users[i];
|
|
|
|
require(role < MAX_NUM_OF_ROLES, 'INVALID_ROLE');
|
|
|
|
uint256 permissions = _users[user].permissions;
|
|
address permissionAdmin = _users[user].permissionAdmin;
|
|
|
|
require(
|
|
(permissions != 0 && permissionAdmin == msg.sender) ||
|
|
_users[user].permissionAdmin == address(0),
|
|
'INVALID_PERMISSIONADMIN'
|
|
);
|
|
|
|
_users[user].permissions = permissions & ~(1 << role);
|
|
|
|
if (_users[user].permissions == 0) {
|
|
//all permission have been removed
|
|
_users[user].permissionAdmin = address(0);
|
|
}
|
|
|
|
emit RoleSet(user, role, msg.sender, false);
|
|
}
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function getUserPermissions(address user)
|
|
external
|
|
view
|
|
override
|
|
returns (uint256[] memory, uint256)
|
|
{
|
|
uint256[] memory roles = new uint256[](256);
|
|
uint256 rolesCount = 0;
|
|
uint256 userPermissions = _users[user].permissions;
|
|
|
|
for (uint256 i = 0; i < 256; i++) {
|
|
if ((userPermissions >> i) & 1 > 0) {
|
|
roles[rolesCount] = i;
|
|
rolesCount++;
|
|
}
|
|
}
|
|
|
|
return (roles, rolesCount);
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function isInRole(address user, uint256 role) external view override returns (bool) {
|
|
return (_users[user].permissions >> role) & 1 > 0;
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function isInAllRoles(address user, uint256[] calldata roles)
|
|
external
|
|
view
|
|
override
|
|
returns (bool)
|
|
{
|
|
for (uint256 i = 0; i < roles.length; i++) {
|
|
if ((_users[user].permissions >> roles[i]) & 1 == 0) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function isInAnyRole(address user, uint256[] calldata roles)
|
|
external
|
|
view
|
|
override
|
|
returns (bool)
|
|
{
|
|
for (uint256 i = 0; i < roles.length; i++) {
|
|
if ((_users[user].permissions >> roles[i]) & 1 > 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function isPermissionsAdmin(address admin) public view override returns (bool) {
|
|
return _permissionsAdmins[admin] > 0;
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function getUserPermissionAdmin(address user) external view override returns (address) {
|
|
return _users[user].permissionAdmin;
|
|
}
|
|
|
|
///@inheritdoc IPermissionManager
|
|
function isUserPermissionAdminValid(address user) external view override returns (bool) {
|
|
return _permissionsAdmins[_users[user].permissionAdmin] > 0;
|
|
}
|
|
}
|