ERC-6617 Bit-based permission standard (Bit Based Permission)

Review · Other · created 2023-02-27

A standard that represents a single smart contract permission as a single bit of a number. One uint256 can define up to 256 permissions and 2^256 possible roles.

Why it is needed

Permission management for smart contracts, which determines who can do what, has mainly been handled in two ways so far: giving a contract a single owner (ERC-173), or assigning each role a 32-byte identifier (bytes32) (ERC-5982). However, these approaches require a storage read operation to check permissions, which is relatively expensive in gas, and they lack flexibility for combining permissions into new roles. This standard represents each permission as a single bit of a 256-bit number (uint256), so permissions can be checked and combined using only cheap bitwise operations. This improves gas efficiency and allows roles that were not predefined to be freely created as combinations of permissions.

What to implement

In depth

Permission representation rules

A compliant contract must implement the IEIP6617 interface. Permissions are represented as uint256, and since each permission must occupy exactly one bit of the uint256, it must be a power of two. Each permission must be unique, and 0 must be used to mean no permission. These rules allow a single uint256 to hold up to 256 permissions.

Inclusion check in hasPermission

hasPermission(_user, _requiredPermission) returns true if the user's permissions are a superset of the required permission, and false otherwise. In other words, every bit set in the required permission must also be set in the user's permissions for the check to pass. Since permissions are all uint256 values, this check is handled with bitwise operations.

Granting, revoking, and event obligations

grantPermission(_user, _permissionToAdd) adds a permission to a user, and revokePermission(_user, _permissionToRevoke) revokes a permission. A PermissionGranted event must be emitted when a permission is granted, and a PermissionRevoked event must be emitted when it is revoked. Both events record the granter or revoker, the target permission, and the target user as indexed arguments.

Metadata extension IEIP6617Meta

An optional extension that addresses the weakness that permissions as numbers are not immediately meaningful. Implementation is RECOMMENDED, and names and descriptions SHOULD be defined for base permissions and major combinations, but descriptions SHOULD NOT be defined for every possible subcombination. The PermissionDescription struct has permission, name, and description fields, and setPermissionDescription must return true on success and must emit an UpdatePermissionDescription event.

Why the bitwise approach was chosen

Access control was previously done with a single owner (ERC-173) or bytes32 roles (ERC-5982), but using bits and bitmask operations gives better gas efficiency and flexibility. A single AND operation on a permission bitmask is much cheaper than multiple calls to the LOAD opcode. Also, 256 permissions allow for 2^256 possible combinations (roles), and new roles can be created by combining multiple permissions with a binary OR operation without needing to predefine every role.

Ordering permissions by importance

Bit order can encode the importance of permissions, for example by placing the most important permission at the most significant bit. Since permissions are all uint256 values, comparing their magnitude is as simple as comparing numbers.

A proposal still under review

This proposal's status is Review. It is not yet a finalized standard, and its content may change during review. The source document provides a basic implementation example as a reference implementation.

Original ERC · ← ERCs