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

refactor: access module #53

Merged
merged 8 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
37 changes: 0 additions & 37 deletions solidity/contracts/AccessController.sol

This file was deleted.

41 changes: 41 additions & 0 deletions solidity/contracts/CommonAccessController.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IAccessController} from '../interfaces/IAccessController.sol';
import {IAccessModule} from '../interfaces/modules/accessControl/IAccessModule.sol';

abstract contract CommonAccessController is IAccessController {
/**
* @notice Modifier to check if the caller has access to the user
* @dev The return value of this function must always be `true`,
* otherwise it would revert.
0xJabberwock marked this conversation as resolved.
Show resolved Hide resolved
* @param _accessModule The access module
* @param _typehash The typehash
* @param _params The params passed to the typehash
* @param _accessControl The access control struct
*/
function _hasAccess(
address _accessModule,
bytes32 _typehash,
bytes memory _params,
AccessControl memory _accessControl
) internal returns (bool _granted) {
// todo: if _accessModule == address(0) we should skip this check.
_granted = msg.sender == _accessControl.user
|| (
_accessModule != address(0)
0xJabberwock marked this conversation as resolved.
Show resolved Hide resolved
&& IAccessModule(_accessModule).hasAccess(
abi.encode(
IAccessModule.AccessControlParameters({
0xJabberwock marked this conversation as resolved.
Show resolved Hide resolved
sender: msg.sender,
accessControl: _accessControl,
typehash: _typehash,
params: _params
})
)
)
);

if (!_granted) revert AccessController_NoAccess();
}
}
53 changes: 14 additions & 39 deletions solidity/contracts/Oracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import {IRequestModule} from '../interfaces/modules/request/IRequestModule.sol';
import {IResolutionModule} from '../interfaces/modules/resolution/IResolutionModule.sol';
import {IResponseModule} from '../interfaces/modules/response/IResponseModule.sol';
import {ValidatorLib} from '../libraries/ValidatorLib.sol';
import {AccessController} from './AccessController.sol';
import {OracleAccessController} from './OracleAccessController.sol';
import {OracleTypehash} from './utils/OracleTypehash.sol';

contract Oracle is IOracle, AccessController, OracleTypehash {
contract Oracle is IOracle, OracleAccessController, OracleTypehash {
using ValidatorLib for *;

/// @inheritdoc IOracle
Expand Down Expand Up @@ -46,9 +46,6 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
/// @inheritdoc IOracle
mapping(bytes32 _requestId => mapping(address _user => bool _isParticipant)) public isParticipant;

/// @inheritdoc IOracle
mapping(address _user => mapping(address _accessControlModule => bool _approved)) public isAccessControlApproved;

/// @inheritdoc IOracle
uint256 public totalRequestCount;

Expand All @@ -57,18 +54,6 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
*/
mapping(bytes32 _requestId => bytes _responseIds) internal _responseIds;

/**
* @notice Modifier to check if the user approved to the access control module
* @param _user The address of the user
* @param _accessControlModule The access control module to check if approved
*/
modifier isApproved(address _user, address _accessControlModule) {
if (_accessControlModule != address(0) && !isAccessControlApproved[_user][_accessControlModule]) {
revert Oracle_AccessControlModuleNotApproved();
}
_;
}

/// @inheritdoc IOracle
function getResponseIds(bytes32 _requestId) public view returns (bytes32[] memory _ids) {
bytes memory _responses = _responseIds[_requestId];
Expand Down Expand Up @@ -110,16 +95,6 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
}
}

/// @inheritdoc IOracle
function setAccessControlModule(address _accessControlModule, bool _approved) external {
if (isAccessControlApproved[msg.sender][_accessControlModule] == _approved) {
revert Oracle_AccessControlModuleAlreadySet();
}
isAccessControlApproved[msg.sender][_accessControlModule] = _approved;

emit AccessControlModuleSet(msg.sender, _accessControlModule, _approved);
}

/// @inheritdoc IOracle
function createRequest(
Request calldata _request,
Expand Down Expand Up @@ -153,8 +128,8 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
AccessControl calldata _accessControl
)
external
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, PROPOSE_TYPEHASH, abi.encode(_request, _response), _accessControl)
isApproved(_accessControl.user, _request.accessModule)
hasAccess(_request.accessModule, PROPOSE_TYPEHASH, abi.encode(_request, _response), _accessControl)
returns (bytes32 _responseId)
{
_responseId = ValidatorLib._validateResponse(_request, _response);
Expand Down Expand Up @@ -194,8 +169,8 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
AccessControl calldata _accessControl
)
external
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, DISPUTE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
isApproved(_accessControl.user, _request.accessModule)
hasAccess(_request.accessModule, DISPUTE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
returns (bytes32 _disputeId)
{
bytes32 _responseId;
Expand Down Expand Up @@ -240,8 +215,8 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
AccessControl calldata _accessControl
)
external
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, ESCALATE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
isApproved(_accessControl.user, _request.accessModule)
hasAccess(_request.accessModule, ESCALATE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
{
(bytes32 _responseId, bytes32 _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

Expand Down Expand Up @@ -279,8 +254,8 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
AccessControl calldata _accessControl
)
external
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, RESOLVE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
isApproved(_accessControl.user, _request.accessModule)
hasAccess(_request.accessModule, RESOLVE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
{
(bytes32 _responseId, bytes32 _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

Expand Down Expand Up @@ -347,8 +322,8 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
AccessControl calldata _accessControl
)
external
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, FINALIZE_TYPEHASH, abi.encode(_request, _response), _accessControl)
isApproved(_accessControl.user, _request.accessModule)
hasAccess(_request.accessModule, FINALIZE_TYPEHASH, abi.encode(_request, _response), _accessControl)
{
bytes32 _requestId;
bytes32 _responseId;
Expand Down Expand Up @@ -458,8 +433,8 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
AccessControl calldata _accessControl
)
internal
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, CREATE_TYPEHASH, abi.encode(_request), _accessControl)
isApproved(_accessControl.user, _request.accessModule)
hasAccess(_request.accessModule, CREATE_TYPEHASH, abi.encode(_request), _accessControl)
returns (bytes32 _requestId)
{
uint256 _requestNonce = totalRequestCount++;
Expand Down
43 changes: 43 additions & 0 deletions solidity/contracts/OracleAccessController.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IOracleAccessController} from '../interfaces/IOracleAccessController.sol';
import {CommonAccessController} from './CommonAccessController.sol';

abstract contract OracleAccessController is IOracleAccessController, CommonAccessController {
/// @inheritdoc IOracleAccessController
mapping(address _user => mapping(address _accessModule => bool _approved)) public isAccessModuleApproved;

modifier hasAccess(
address _accessModule,
bytes32 _typehash,
bytes memory _params,
AccessControl memory _accessControl
) {
// we do not care about `_hasAccess` return value, check function's @notice
_hasAccess(_accessModule, _typehash, _params, _accessControl);
xorsal marked this conversation as resolved.
Show resolved Hide resolved
_;
}

/**
* @notice Modifier to check if the user approved to the access module
* @param _user The address of setAccessModulethe user
* @param _accessModule The access module to check if approved
*/
modifier isApproved(address _user, address _accessModule) {
if (_accessModule != address(0) && !isAccessModuleApproved[_user][_accessModule]) {
revert OracleAccessController_AccessModuleNotApproved();
}
_;
}

/// @inheritdoc IOracleAccessController
function setAccessModule(address _accessModule, bool _approved) external {
if (isAccessModuleApproved[msg.sender][_accessModule] == _approved) {
revert OracleAccessController_AccessModuleAlreadySet();
}
isAccessModuleApproved[msg.sender][_accessModule] = _approved;

emit AccessModuleSet(msg.sender, _accessModule, _approved);
}
}
17 changes: 9 additions & 8 deletions solidity/interfaces/IAccessController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,18 @@ interface IAccessController {
EVENTS
//////////////////////////////////////////////////////////////*/

/*///////////////////////////////////////////////////////////////
ERRORS
//////////////////////////////////////////////////////////////*/
/**
* @notice Thrown when the caller has no access
*/
error AccessController_NoAccess();
0xJabberwock marked this conversation as resolved.
Show resolved Hide resolved

/*///////////////////////////////////////////////////////////////
STRUCTS
//////////////////////////////////////////////////////////////*/

/**
* @notice The access control struct
* @param user The address of the user
Expand All @@ -23,14 +32,6 @@ interface IAccessController {
bytes data;
}

/*///////////////////////////////////////////////////////////////
ERRORS
//////////////////////////////////////////////////////////////*/
/**
* @notice Thrown when the caller has no access
*/
error AccessController_NoAccess();

/*///////////////////////////////////////////////////////////////
VARIABLES
//////////////////////////////////////////////////////////////*/
Expand Down
43 changes: 4 additions & 39 deletions solidity/interfaces/IOracle.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IAccessController} from './IAccessController.sol';
import {IAccessController, IOracleAccessController} from './IOracleAccessController.sol';

/**
* @title Oracle
* @notice The main contract storing requests, responses and disputes, and routing the calls to the modules.
*/
interface IOracle is IAccessController {
interface IOracle is IOracleAccessController {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -66,14 +66,6 @@ interface IOracle is IAccessController {
*/
event DisputeResolved(bytes32 indexed _disputeId, Dispute _dispute);

/**
* @notice Emitted when the access control module is set
* @param _user The address of the user
* @param _accessControlModule The address of the access control module
* @param _approved If the module is approved
*/
event AccessControlModuleSet(address indexed _user, address indexed _accessControlModule, bool _approved);

/*///////////////////////////////////////////////////////////////
ERRORS
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -176,16 +168,6 @@ interface IOracle is IAccessController {
*/
error Oracle_InvalidDisputer();

/**
* @notice Thrown when user didn't approve the access control module
*/
error Oracle_AccessControlModuleNotApproved();

/**
* @notice Thrown when the access control module is already set
*/
error Oracle_AccessControlModuleAlreadySet();

/*///////////////////////////////////////////////////////////////
ENUMS
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -214,7 +196,7 @@ interface IOracle is IAccessController {
* @param disputeModule The address of the dispute module
* @param resolutionModule The address of the resolution module
* @param finalityModule The address of the finality module
* @param accessControlModule The address of the access control module
* @param accessModule The address of the access module
* @param requestModuleData The parameters for the request module
* @param responseModuleData The parameters for the response module
* @param disputeModuleData The parameters for the dispute module
Expand All @@ -231,7 +213,7 @@ interface IOracle is IAccessController {
address disputeModule;
address resolutionModule;
address finalityModule;
address accessControlModule;
address accessModule;
bytes requestModuleData;
bytes responseModuleData;
bytes disputeModuleData;
Expand Down Expand Up @@ -375,15 +357,6 @@ interface IOracle is IAccessController {
*/
function getResponseIds(bytes32 _requestId) external view returns (bytes32[] memory _ids);

/**
* @notice Checks if the given address approved the access control module
*
* @param _user The address to check
* @param _accessControlModule The address of the access control module
* @return _approved If the user approved the access control module
*/
function isAccessControlApproved(address _user, address _accessControlModule) external view returns (bool _approved);

/*///////////////////////////////////////////////////////////////
LOGIC
//////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -505,12 +478,4 @@ interface IOracle is IAccessController {
Response calldata _response,
AccessControl calldata _accessControl
) external;

/**
* @notice Sets the address of the access control module
*
* @param _accessControlModule The address of the access control module
* @param _approved If the module is approved
*/
function setAccessControlModule(address _accessControlModule, bool _approved) external;
}
Loading
Loading