Skip to content

Commit bf3d888

Browse files
authored
Merge 0a90e6b into 58955d0
2 parents 58955d0 + 0a90e6b commit bf3d888

2 files changed

Lines changed: 157 additions & 82 deletions

File tree

EIPS/eip-6617.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
---
2+
eip: 6617
3+
title: Bit Based Permission
4+
description: A permission and role system based on bits
5+
author: Chiro (@chiro-hiro), Victor Dusart (@vdusart)
6+
discussions-to: https://ethereum-magicians.org/t/bit-based-permission/13065
7+
status: Draft
8+
type: Standards Track
9+
category: ERC
10+
created: 2023-02-27
11+
---
12+
13+
## Abstract
14+
15+
This EIP offers a standard for building a bit-based permission and role system. Each permission is represented by a single bit. By using an `uint256`, up to $256$ permissions and $2^{256}$ roles can be defined. We are able to specify the importance of permission based on the order of the bits.
16+
17+
## Motivation
18+
19+
Currently permission and access control are done using `string` or `keccak256(string)` comparaisons (see [ERC-5982](./eip-5982.md)).
20+
By using bitwise and bitmask operations to determine access rights, we gain in efficiency, flexibility and more.
21+
22+
### Gas cost efficiency
23+
24+
Bitwise operations are very cheap and fast. For example, doing an `AND` bitwise operation on a permission bitmask is significantly cheaper than calling any number of `LOAD` opcodes.
25+
26+
### Flexibility
27+
28+
With the 256 bits of the `uint256`, we can create up to 256 different permissions which leads to $2^{256}$ unique combinations (a.k.a. roles).
29+
*(A role is a combination of multiple permissions).* Not all roles have to be predefined.
30+
31+
Since permissions are defined as powers of two, we can use the binary OR operator to create new role based on multiple permissions.
32+
33+
### Ordering permissions by importance
34+
35+
We can use the most significant bit to represent the most important permission, the comparison between permissions can then be done easily since they all are `uint256`s.
36+
37+
## Specification
38+
39+
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
40+
41+
*Note* The following specifications use syntax from Solidity `0.8.7` (or above)
42+
43+
- Permission and role MUST be defined as an `uint256`
44+
- Permission MUST be defined as a power of two
45+
- Permission MUST be unique
46+
- `0` MUST be used for none permission
47+
48+
49+
## Implementation Reference
50+
51+
```solidity
52+
pragma solidity ^0.8.7;
53+
54+
/**
55+
@title EIP-6617 Bit Based Permission
56+
@dev See https://eips.ethereum.org/EIPS/eip-6617
57+
*/
58+
library EIP6617 {
59+
/**
60+
@notice Check if _permission is a superset of _requiredPermission
61+
@param _permission The given permission
62+
@param _requiredPermission The required permission
63+
@return True if the _permission is a superset of the _requiredPermission else False
64+
*/
65+
function permissionCheck(uint256 _permission, uint256 _requiredPermission)
66+
internal
67+
pure
68+
returns (bool)
69+
{
70+
return _permission & _requiredPermission == _requiredPermission;
71+
}
72+
73+
/**
74+
@notice Add permission
75+
@param _permission The given permission
76+
@param _permissionToAdd The permission that will be added
77+
@return The new permission with the _permissionToAdd
78+
*/
79+
function permissionGrant(uint256 _permission, uint256 _permissionToAdd)
80+
internal
81+
pure
82+
returns (uint256)
83+
{
84+
return _permission | _permissionToAdd;
85+
}
86+
87+
/**
88+
@notice Remove permission
89+
@param _permission The given permission
90+
@param _permissionToRemove The permission that will be removed
91+
@return The new permission without the _permissionToRemove
92+
*/
93+
function permissionRevoke(uint256 _permission, uint256 _permissionToRemove)
94+
internal
95+
pure
96+
returns (uint256)
97+
{
98+
return (_permission | _permissionToRemove) ^ _permissionToRemove;
99+
}
100+
}
101+
```
102+
103+
### Usage
104+
105+
```solidity
106+
pragma solidity ^0.8.7;
107+
108+
import "EIP6617.sol";
109+
110+
contract Test {
111+
using EIP6617 for uint256;
112+
113+
const PERMISSION_NONE = 0;
114+
const PERMISSION_READ = 1; // 2⁰
115+
const PERMISSION_WRITE = 2; // 2¹
116+
const PERMISSION_EXECUTE = 4; // 2²
117+
118+
// Role operator = 1 | 2 = 3
119+
const ROLE_OPERATOR = PERMISSION_READ | PERMISSION_WRITE;
120+
121+
// Role admin = 1 | 2 | 4 = 7
122+
const ROLE_ADMIN = PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXECUTE;
123+
124+
function testPermissions() external pure returns (uint256) {
125+
uint256 userPermission;
126+
127+
// adding read permission
128+
userPermission = userPermission.permissionGrant(PERMISSION_READ);
129+
130+
// adding admin role
131+
userPermission = userPermission.permissionGrant(ROLE_ADMIN);
132+
133+
// removing execute permission
134+
userPermission = userPermission.permissionRevoke(PERMISSION_EXECUTE);
135+
136+
// Checking permission
137+
if (userPermission.permissionCheck(ROLE_ADMIN)) {
138+
// Only admin can access this part
139+
}
140+
141+
return userPermission;
142+
}
143+
}
144+
```
145+
146+
## Rationale
147+
148+
Needs discussion.
149+
150+
151+
## Security Considerations
152+
153+
Need more discussion.
154+
155+
## Copyright
156+
157+
Copyright and related rights waived via [CC0](../LICENSE.md).

EIPS/eip-bit_based_permission.md

Lines changed: 0 additions & 82 deletions
This file was deleted.

0 commit comments

Comments
 (0)