Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ Make AccessControl Module-Friendly #216

Merged
merged 8 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
pcaversaccio marked this conversation as resolved.
Show resolved Hide resolved
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