Skip to content

Commit

Permalink
♻️ Make AccessControl Module-Friendly (#216)
Browse files Browse the repository at this point in the history
### 🕓 Changelog

This PR refactors the `AccessControl` contract to make it
module-friendly and ready for the breaking `0.4.0` release.

---------

Signed-off-by: Pascal Marco Caversaccio <[email protected]>
  • Loading branch information
pcaversaccio authored Mar 25, 2024
1 parent 19ed1e5 commit b8d0b53
Show file tree
Hide file tree
Showing 8 changed files with 748 additions and 696 deletions.
966 changes: 483 additions & 483 deletions .gas-snapshot

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [`0.1.0`](https://github.com/pcaversaccio/snekmate/releases/tag/v0.0.1) (Unreleased)

### ♻️ Refactoring

- **Authentication**
- [`AccessControl`](https://github.com/pcaversaccio/snekmate/blob/v0.1.0/src/snekmate/auth/AccessControl.vy): Make `AccessControl` module-friendly. ([#216](https://github.com/pcaversaccio/snekmate/pull/216))

### 👀 Full Changelog

- [`v0.0.5...v0.1.0`](https://github.com/pcaversaccio/snekmate/compare/v0.0.5...v0.1.0)
Expand Down
6 changes: 4 additions & 2 deletions GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Any addition or change to the code must be accompanied by relevant and comprehen

The test suite should run automatically for each change in the repository, and for pull requests, the tests must succeed before merging.

Please consider writing [Foundry](https://github.com/foundry-rs/foundry)-based unit tests, property-based tests (i.e. fuzzing), and invariant tests for all contracts, if applicable.
Please consider writing [Foundry](https://github.com/foundry-rs/foundry)-based unit tests, property-based tests (i.e. stateless fuzzing), and invariant tests (i.e. stateful fuzzing) for all contracts, if applicable.

## 🪅 Code Style

Expand Down Expand Up @@ -71,7 +71,9 @@ def _as_singleton_array(element: uint256) -> DynArray[uint256, 1]:
- All functions should be provided with full [NatSpec](https://docs.vyperlang.org/en/latest/natspec.html) comments containing the tags `@dev`, `@notice` (if applicable), `@param` for each function parameter, and `@return` if a return statement is present.
- Please note the following order of layout:
- Version pragma statement
- Interface imports
- Vyper built-in interface imports
- Custom interface imports
- Module imports
- `public` constants
- `internal` constants
- `public` immutables
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pnpm add --save-dev snekmate
## 👩🏼‍⚖️ Tests

This repository contains [Foundry](https://github.com/foundry-rs/foundry)-based unit tests, property-based tests (i.e. fuzzing), and invariant tests for all contracts, if applicable. All tests are run as part of the CI pipeline [`test-contracts`](./.github/workflows/test-contracts.yml).
This repository contains [Foundry](https://github.com/foundry-rs/foundry)-based unit tests, property-based tests (i.e. stateless fuzzing), and invariant tests (i.e. stateful fuzzing) for all contracts, if applicable. All tests are run as part of the CI pipeline [`test-contracts`](./.github/workflows/test-contracts.yml).

> [!NOTE]
> An _invariant_ is a property of a program that should always hold true. Fuzzing is a way of checking whether the invariant is falsifiable.
Expand Down
26 changes: 4 additions & 22 deletions src/snekmate/auth/AccessControl.vy
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
@notice These functions can be used to implement role-based access
control mechanisms. Roles are referred to by their `bytes32`
identifier. These should be exposed in the external API and
be unique. The best way to achieve this is by using `public
constant` hash digests:
be unique. The best way to achieve this is by using `public`
`constant` hash digests:
```vy
MY_ROLE: public(constant(bytes32)) = keccak256("MY_ROLE");
```
Expand Down Expand Up @@ -69,22 +69,6 @@ implements: IAccessControl
DEFAULT_ADMIN_ROLE: public(constant(bytes32)) = empty(bytes32)


# @dev An additional 32-byte access role.
# @notice Please adjust the naming of the variable
# according to your specific requirement,
# e.g. `MINTER_ROLE`.
ADDITIONAL_ROLE_1: public(constant(bytes32)) = keccak256("ADDITIONAL_ROLE_1")


# @dev An additional 32-byte access role.
# @notice Please adjust the naming of the variable
# according to your specific requirement,
# e.g. `PAUSER_ROLE`. Also, feel free to add more
# roles if necessary. In this case, it is important
# to extend the constructor accordingly.
ADDITIONAL_ROLE_2: public(constant(bytes32)) = keccak256("ADDITIONAL_ROLE_2")


# @dev Stores the ERC-165 interface identifier for each
# imported interface. The ERC-165 interface identifier
# is defined as the XOR of all function selectors in the
Expand Down Expand Up @@ -143,12 +127,10 @@ def __init__():
@dev To omit the opcodes for checking the `msg.value`
in the creation-time EVM bytecode, the constructor
is declared as `payable`.
@notice All predefined roles will be assigned to
the `msg.sender`.
@notice The `DEFAULT_ADMIN_ROLE` role will be assigned
to the `msg.sender`.
"""
self._grant_role(DEFAULT_ADMIN_ROLE, msg.sender)
self._grant_role(ADDITIONAL_ROLE_1, msg.sender)
self._grant_role(ADDITIONAL_ROLE_2, msg.sender)


@external
Expand Down
70 changes: 70 additions & 0 deletions src/snekmate/auth/mocks/AccessControlMock.vy
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# pragma version ~=0.4.0b5
"""
@title AccessControl Module Reference Implementation
@custom:contract-name AccessControlMock
@license GNU Affero General Public License v3.0 only
@author pcaversaccio
"""


# @dev We import and implement the `IERC165` interface,
# which is a built-in interface of the Vyper compiler.
from ethereum.ercs import IERC165
implements: IERC165


# @dev We import and implement the `IAccessControl`
# interface, which is written using standard Vyper
# syntax.
from ..interfaces import IAccessControl
implements: IAccessControl


# @dev We import and initialise the `AccessControl` module.
from .. import AccessControl as ac
initializes: ac


# @dev The 32-byte minter role.
MINTER_ROLE: public(constant(bytes32)) = keccak256("MINTER_ROLE")


# @dev The 32-byte pauser role.
PAUSER_ROLE: public(constant(bytes32)) = keccak256("PAUSER_ROLE")


# @dev We export (i.e. the runtime bytecode exposes these
# functions externally, allowing them to be called using
# the ABI encoding specification) all `external` functions
# from the `AccessControl` module.
# @notice Please note that you must always also export (if
# required by the contract logic) `public` declared `constant`,
# `immutable`, and state variables, for which Vyper automatically
# generates an `external` getter function for the variable.
exports: (
ac.supportsInterface,
ac.DEFAULT_ADMIN_ROLE,
ac.hasRole,
ac.getRoleAdmin,
ac.grantRole,
ac.revokeRole,
ac.renounceRole,
ac.set_role_admin,
)


@deploy
@payable
def __init__():
"""
@dev To omit the opcodes for checking the `msg.value`
in the creation-time EVM bytecode, the constructor
is declared as `payable`.
@notice All predefined roles will be assigned to
the `msg.sender`.
"""
# The following line assigns the `DEFAULT_ADMIN_ROLE`
# to the `msg.sender`.
ac.__init__()
ac._grant_role(MINTER_ROLE, msg.sender)
ac._grant_role(PAUSER_ROLE, msg.sender)
Loading

0 comments on commit b8d0b53

Please sign in to comment.