Skip to content

Commit 36c0341

Browse files
authorize docs
1 parent b41d519 commit 36c0341

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/interface/IAuthorizeV1.sol

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,56 @@
22
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
33
pragma solidity ^0.8.25;
44

5+
/// MUST be thrown by an `IAuthorizeV1` contract if the user is not authorized.
6+
/// @param user The address of the user that was not authorized.
7+
/// @param permission The permission that was not granted.
8+
/// @param data The data that was passed to the authorization contract.
59
error Unauthorized(address user, bytes32 permission, bytes data);
610

11+
/// Minimal interface for a contract to provide authorization for another.
12+
/// The contract implementing this is expected to REVERT if the user is not
13+
/// authorized for the given permission. There are no return values.
14+
///
15+
/// There's no assumption that the authorization works in any particular way. A
16+
/// simple example would be an RBAC such as implemented by Open Zeppelin's
17+
/// standard contracts. A more complex example would be handing over the
18+
/// authorization to a rainlang expression that could be voted on and deployed
19+
/// by a DAO.
20+
///
21+
/// The point is that the calling contract can decouple its basic workflows and
22+
/// associated state from the authorization logic. This is in contract to the
23+
/// `Ownable` pattern where the calling contract would expect itself to be owned
24+
/// by some contract that implements the authorization logic as a wrapper. The
25+
/// main benefit of `IAuthorizeV1` is that the authorization contract can be
26+
/// passed contextual data about state changes from the caller, without
27+
/// duplication of sensitive internal logic.
28+
///
29+
/// If the `Ownable` pattern is desirable for whatever reason, the `IAuthorizeV1`
30+
/// contract can simply revert whenever the caller is not the owner.
31+
///
32+
/// Obviously, setting the `IAuthorizeV1` contract on the caller is an extremely
33+
/// sensitive operation and should be done with care, such as through a multisig
34+
/// and/or dedicated governance contract.
735
interface IAuthorizeV1 {
36+
/// Authorize a user for a caller-specified permission.
37+
///
38+
/// The authorization contract is expected to be implemented to be compatible
39+
/// with a specific caller only. It MUST be aware of and handle all
40+
/// `permission` values that the caller may send.
41+
///
42+
/// Authorization MAY CHANGE STATE as `view` is NOT mandated at the interface
43+
/// level, however it is RECOMMENDED. For example, a user may only be
44+
/// authorized to perform an action a specified number of times, and so the
45+
/// authorization contract will need to maintain a counter. However, if state
46+
/// changes are allowed, the authorization contract MUST enforce that the
47+
/// caller is the expected contract, otherwise it is very likely that state
48+
/// will be corrupted by a malicious caller.
49+
///
50+
/// @param user The address of the user to authorize. Most likely will be
51+
/// the `msg.sender` from the calling contract's perspective, but MAY NOT be.
52+
/// @param permission The permission to authorize.
53+
/// @param data Arbitrary data to pass to the authorization contract. Most
54+
/// likely to be an abi encoded representation of the state change that the
55+
/// caller needs to authorize.
856
function authorize(address user, bytes32 permission, bytes memory data) external;
957
}

0 commit comments

Comments
 (0)