Skip to content

Commit

Permalink
Feature/dynamic set (#100)
Browse files Browse the repository at this point in the history
* Add DynamicSet library

* Remove old StringSet

* Add doc comments to the DynamicSet library

* Small fixes
  • Loading branch information
Hrom131 authored May 8, 2024
1 parent e554591 commit bb16e23
Show file tree
Hide file tree
Showing 16 changed files with 909 additions and 401 deletions.
55 changes: 31 additions & 24 deletions contracts/access/RBAC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IRBAC} from "../interfaces/access/IRBAC.sol";

import {TypeCaster} from "../libs/utils/TypeCaster.sol";
import {SetHelper} from "../libs/arrays/SetHelper.sol";
import {StringSet} from "../libs/data-structures/StringSet.sol";
import {DynamicSet} from "../libs/data-structures/DynamicSet.sol";

/**
* @notice The Role Based Access Control (RBAC) module
Expand All @@ -31,8 +31,8 @@ import {StringSet} from "../libs/data-structures/StringSet.sol";
* Where ROLE is assignable to users
*/
abstract contract RBAC is IRBAC, Initializable {
using StringSet for StringSet.Set;
using SetHelper for StringSet.Set;
using DynamicSet for DynamicSet.StringSet;
using SetHelper for DynamicSet.StringSet;
using TypeCaster for string;

string public constant MASTER_ROLE = "MASTER";
Expand All @@ -47,10 +47,11 @@ abstract contract RBAC is IRBAC, Initializable {

string public constant RBAC_RESOURCE = "RBAC_RESOURCE";

mapping(string => mapping(bool => mapping(string => StringSet.Set))) private _rolePermissions;
mapping(string => mapping(bool => StringSet.Set)) private _roleResources;
mapping(string => mapping(bool => mapping(string => DynamicSet.StringSet)))
private _rolePermissions;
mapping(string => mapping(bool => DynamicSet.StringSet)) private _roleResources;

mapping(address => StringSet.Set) private _userRoles;
mapping(address => DynamicSet.StringSet) private _userRoles;

modifier onlyPermission(string memory resource_, string memory permission_) {
require(
Expand Down Expand Up @@ -165,15 +166,15 @@ abstract contract RBAC is IRBAC, Initializable {
ResourceWithPermissions[] memory disallowed_
)
{
StringSet.Set storage _allowedResources = _roleResources[role_][true];
StringSet.Set storage _disallowedResources = _roleResources[role_][false];
DynamicSet.StringSet storage _allowedResources = _roleResources[role_][true];
DynamicSet.StringSet storage _disallowedResources = _roleResources[role_][false];

mapping(string => StringSet.Set) storage _allowedPermissions = _rolePermissions[role_][
true
];
mapping(string => StringSet.Set) storage _disallowedPermissions = _rolePermissions[role_][
false
];
mapping(string => DynamicSet.StringSet) storage _allowedPermissions = _rolePermissions[
role_
][true];
mapping(string => DynamicSet.StringSet) storage _disallowedPermissions = _rolePermissions[
role_
][false];

allowed_ = new ResourceWithPermissions[](_allowedResources.length());
disallowed_ = new ResourceWithPermissions[](_disallowedResources.length());
Expand Down Expand Up @@ -253,8 +254,10 @@ abstract contract RBAC is IRBAC, Initializable {
string[] memory permissionsToAdd_,
bool allowed_
) internal {
StringSet.Set storage _resources = _roleResources[role_][allowed_];
StringSet.Set storage _permissions = _rolePermissions[role_][allowed_][resourceToAdd_];
DynamicSet.StringSet storage _resources = _roleResources[role_][allowed_];
DynamicSet.StringSet storage _permissions = _rolePermissions[role_][allowed_][
resourceToAdd_
];

_permissions.add(permissionsToAdd_);
_resources.add(resourceToAdd_);
Expand All @@ -275,8 +278,10 @@ abstract contract RBAC is IRBAC, Initializable {
string[] memory permissionsToRemove_,
bool allowed_
) internal {
StringSet.Set storage _resources = _roleResources[role_][allowed_];
StringSet.Set storage _permissions = _rolePermissions[role_][allowed_][resourceToRemove_];
DynamicSet.StringSet storage _resources = _roleResources[role_][allowed_];
DynamicSet.StringSet storage _permissions = _rolePermissions[role_][allowed_][
resourceToRemove_
];

_permissions.remove(permissionsToRemove_);

Expand All @@ -299,10 +304,10 @@ abstract contract RBAC is IRBAC, Initializable {
string memory resource_,
string memory permission_
) internal view returns (bool) {
mapping(string => StringSet.Set) storage _resources = _rolePermissions[role_][true];
mapping(string => DynamicSet.StringSet) storage _resources = _rolePermissions[role_][true];

StringSet.Set storage _allAllowed = _resources[ALL_RESOURCE];
StringSet.Set storage _allowed = _resources[resource_];
DynamicSet.StringSet storage _allAllowed = _resources[ALL_RESOURCE];
DynamicSet.StringSet storage _allowed = _resources[resource_];

return (_allAllowed.contains(ALL_PERMISSION) ||
_allAllowed.contains(permission_) ||
Expand All @@ -322,10 +327,12 @@ abstract contract RBAC is IRBAC, Initializable {
string memory resource_,
string memory permission_
) internal view returns (bool) {
mapping(string => StringSet.Set) storage _resources = _rolePermissions[role_][false];
mapping(string => DynamicSet.StringSet) storage _resources = _rolePermissions[role_][
false
];

StringSet.Set storage _allDisallowed = _resources[ALL_RESOURCE];
StringSet.Set storage _disallowed = _resources[resource_];
DynamicSet.StringSet storage _allDisallowed = _resources[ALL_RESOURCE];
DynamicSet.StringSet storage _disallowed = _resources[resource_];

return (_allDisallowed.contains(ALL_PERMISSION) ||
_allDisallowed.contains(permission_) ||
Expand Down
12 changes: 6 additions & 6 deletions contracts/access/extensions/RBACGroupable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.4;

import {IRBACGroupable} from "../../interfaces/access/extensions/IRBACGroupable.sol";

import {StringSet} from "../../libs/data-structures/StringSet.sol";
import {DynamicSet} from "../../libs/data-structures/DynamicSet.sol";
import {SetHelper} from "../../libs/arrays/SetHelper.sol";

import {RBAC} from "../RBAC.sol";
Expand All @@ -23,13 +23,13 @@ import {RBAC} from "../RBAC.sol";
* Where ROLE and GROUP are assignable to users
*/
abstract contract RBACGroupable is IRBACGroupable, RBAC {
using StringSet for StringSet.Set;
using SetHelper for StringSet.Set;
using DynamicSet for DynamicSet.StringSet;
using SetHelper for DynamicSet.StringSet;

uint256 private _defaultGroupEnabled;

mapping(address => StringSet.Set) private _userGroups;
mapping(string => StringSet.Set) private _groupRoles;
mapping(address => DynamicSet.StringSet) private _userGroups;
mapping(string => DynamicSet.StringSet) private _groupRoles;

/**
* @notice The initialization function
Expand Down Expand Up @@ -115,7 +115,7 @@ abstract contract RBACGroupable is IRBACGroupable, RBAC {
* @return groups_ the list of user groups
*/
function getUserGroups(address who_) public view override returns (string[] memory groups_) {
StringSet.Set storage userGroups = _userGroups[who_];
DynamicSet.StringSet storage userGroups = _userGroups[who_];

uint256 userGroupsLength_ = userGroups.length();

Expand Down
2 changes: 0 additions & 2 deletions contracts/interfaces/access/IRBAC.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {StringSet} from "../../libs/data-structures/StringSet.sol";

/**
* @notice The RBAC module
*/
Expand Down
27 changes: 22 additions & 5 deletions contracts/libs/arrays/Paginator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ pragma solidity ^0.8.4;

import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {StringSet} from "../data-structures/StringSet.sol";
import {DynamicSet} from "../data-structures/DynamicSet.sol";

/**
* @notice Library for pagination.
*
* Supports the following data types `uin256[]`, `address[]`, `bytes32[]`, `UintSet`,
* `AddressSet`, `BytesSet`, `StringSet`.
* Supports the following data types `uint256[]`, `address[]`, `bytes32[]`, `UintSet`,
* `AddressSet`, `Bytes32Set`, `BytesSet`, `StringSet`.
*/
library Paginator {
using EnumerableSet for *;
using StringSet for StringSet.Set;
using DynamicSet for *;

/**
* @notice Returns part of a uint256 array
Expand Down Expand Up @@ -129,11 +129,28 @@ library Paginator {
}
}

/**
* @notice Returns part of a bytes set
*/
function part(
DynamicSet.BytesSet storage set,
uint256 offset_,
uint256 limit_
) internal view returns (bytes[] memory list_) {
uint256 to_ = getTo(set.length(), offset_, limit_);

list_ = new bytes[](to_ - offset_);

for (uint256 i = offset_; i < to_; i++) {
list_[i - offset_] = set.at(i);
}
}

/**
* @notice Returns part of a string set
*/
function part(
StringSet.Set storage set,
DynamicSet.StringSet storage set,
uint256 offset_,
uint256 limit_
) internal view returns (string[] memory list_) {
Expand Down
48 changes: 42 additions & 6 deletions contracts/libs/arrays/SetHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.4;

import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {StringSet} from "../data-structures/StringSet.sol";
import {DynamicSet} from "../data-structures/DynamicSet.sol";

/**
* @notice A simple library to work with Openzeppelin sets
Expand All @@ -12,7 +12,7 @@ library SetHelper {
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableSet for EnumerableSet.Bytes32Set;
using StringSet for StringSet.Set;
using DynamicSet for *;

/**
* @notice The function to insert an array of elements into the address set
Expand Down Expand Up @@ -43,10 +43,19 @@ library SetHelper {
}
}

/**
* @notice The function to insert an array of elements into the bytes set
*/
function add(DynamicSet.BytesSet storage set, bytes[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
set.add(array_[i]);
}
}

/**
* @notice The function to insert an array of elements into the string set
*/
function add(StringSet.Set storage set, string[] memory array_) internal {
function add(DynamicSet.StringSet storage set, string[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
set.add(array_[i]);
}
Expand Down Expand Up @@ -81,10 +90,19 @@ library SetHelper {
}
}

/**
* @notice The function for the strict insertion of an array of elements into the bytes set
*/
function strictAdd(DynamicSet.BytesSet storage set, bytes[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
require(set.add(array_[i]), "SetHelper: element already exists");
}
}

/**
* @notice The function for the strict insertion of an array of elements into the string set
*/
function strictAdd(StringSet.Set storage set, string[] memory array_) internal {
function strictAdd(DynamicSet.StringSet storage set, string[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
require(set.add(array_[i]), "SetHelper: element already exists");
}
Expand Down Expand Up @@ -119,10 +137,19 @@ library SetHelper {
}
}

/**
* @notice The function to remove an array of elements from the bytes set
*/
function remove(DynamicSet.BytesSet storage set, bytes[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
set.remove(array_[i]);
}
}

/**
* @notice The function to remove an array of elements from the string set
*/
function remove(StringSet.Set storage set, string[] memory array_) internal {
function remove(DynamicSet.StringSet storage set, string[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
set.remove(array_[i]);
}
Expand Down Expand Up @@ -157,10 +184,19 @@ library SetHelper {
}
}

/**
* @notice The function for the strict removal of an array of elements from the bytes set
*/
function strictRemove(DynamicSet.BytesSet storage set, bytes[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
require(set.remove(array_[i]), "SetHelper: no such element");
}
}

/**
* @notice The function for the strict removal of an array of elements from the string set
*/
function strictRemove(StringSet.Set storage set, string[] memory array_) internal {
function strictRemove(DynamicSet.StringSet storage set, string[] memory array_) internal {
for (uint256 i = 0; i < array_.length; i++) {
require(set.remove(array_[i]), "SetHelper: no such element");
}
Expand Down
Loading

0 comments on commit bb16e23

Please sign in to comment.