Skip to content

Commit

Permalink
feat: refactor has access
Browse files Browse the repository at this point in the history
  • Loading branch information
ashitakah committed Nov 11, 2024
2 parents 69efe2b + 8bb062e commit 84fe5c0
Show file tree
Hide file tree
Showing 20 changed files with 579 additions and 357 deletions.
37 changes: 0 additions & 37 deletions solidity/contracts/AccessController.sol

This file was deleted.

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

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

abstract contract CommonAccessController is IAccessController {
/**
* @notice Check whether the caller is authorized for the given parameters.
* @param _accessModule The access module
* @param _typehash The typehash
* @param _typehashParams The params passed to the typehash
* @param _accessControl The access control struct
*/
function _hasAccess(
address _accessModule,
bytes32 _typehash,
bytes memory _typehashParams,
AccessControl memory _accessControl
) internal {
bool _granted = IAccessModule(_accessModule).hasAccess(
abi.encode(
IAccessModule.AccessControlParameters({
sender: msg.sender,
accessControl: _accessControl,
typehash: _typehash,
typehashParams: _typehashParams
})
)
);

if (!_granted) revert AccessController_NoAccess();
}
}
59 changes: 14 additions & 45 deletions solidity/contracts/Oracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ pragma solidity ^0.8.19;

import {IOracle} from '../interfaces/IOracle.sol';

import {IAccessModule} from '../interfaces/modules/access/IAccessModule.sol';
import {IDisputeModule} from '../interfaces/modules/dispute/IDisputeModule.sol';

import {IAccessControlModule} from '../interfaces/modules/accessControl/IAccessControlModule.sol';
import {IFinalityModule} from '../interfaces/modules/finality/IFinalityModule.sol';
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 @@ -47,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 @@ -58,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 @@ -111,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 @@ -154,8 +128,7 @@ 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)
hasAccess(_request.accessModule, PROPOSE_TYPEHASH, abi.encode(_request, _response), _accessControl)
returns (bytes32 _responseId)
{
_responseId = ValidatorLib._validateResponse(_request, _response);
Expand Down Expand Up @@ -195,8 +168,7 @@ 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)
hasAccess(_request.accessModule, DISPUTE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
returns (bytes32 _disputeId)
{
bytes32 _responseId;
Expand Down Expand Up @@ -241,8 +213,7 @@ 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)
hasAccess(_request.accessModule, ESCALATE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
{
(bytes32 _responseId, bytes32 _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

Expand Down Expand Up @@ -280,8 +251,7 @@ 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)
hasAccess(_request.accessModule, RESOLVE_TYPEHASH, abi.encode(_request, _response, _dispute), _accessControl)
{
(bytes32 _responseId, bytes32 _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

Expand Down Expand Up @@ -346,11 +316,7 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
IOracle.Request calldata _request,
IOracle.Response calldata _response,
AccessControl calldata _accessControl
)
external
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, FINALIZE_TYPEHASH, abi.encode(_request, _response), _accessControl)
{
) external hasAccess(_request.accessModule, FINALIZE_TYPEHASH, abi.encode(_request, _response), _accessControl) {
bytes32 _requestId;
bytes32 _responseId;

Expand Down Expand Up @@ -378,7 +344,11 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
IDisputeModule(_request.disputeModule).finalizeRequest(_request, _response, _accessControl.user);
IResponseModule(_request.responseModule).finalizeRequest(_request, _response, _accessControl.user);
IRequestModule(_request.requestModule).finalizeRequest(_request, _response, _accessControl.user);
IAccessControlModule(_request.accessControlModule).finalizeRequest(_request, _response, _accessControl.user);
IAccessModule(_request.accessModule).finalizeRequest(_request, _response, _accessControl.user);

if (_request.accessModule != address(0)) {
IAccessModule(_request.accessModule).finalizeRequest(_request, _response, _accessControl.user);
}

emit OracleRequestFinalized(_requestId, _responseId);
}
Expand Down Expand Up @@ -460,8 +430,7 @@ contract Oracle is IOracle, AccessController, OracleTypehash {
AccessControl calldata _accessControl
)
internal
isApproved(_accessControl.user, _request.accessControlModule)
hasAccess(_request.accessControlModule, CREATE_TYPEHASH, abi.encode(_request), _accessControl)
hasAccess(_request.accessModule, CREATE_TYPEHASH, abi.encode(_request), _accessControl)
returns (bytes32 _requestId)
{
uint256 _requestNonce = totalRequestCount++;
Expand Down
39 changes: 39 additions & 0 deletions solidity/contracts/OracleAccessController.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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
) {
if (_accessControl.user != msg.sender) {
if (_accessModule == address(0)) {
revert AccessController_NoAccess();
} else {
if (!isAccessModuleApproved[_accessControl.user][_accessModule]) {
revert OracleAccessController_AccessModuleNotApproved();
}
_hasAccess(_accessModule, _typehash, _params, _accessControl);
}
}
_;
}

/// @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);
}
}
23 changes: 6 additions & 17 deletions solidity/interfaces/IAccessController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ pragma solidity ^0.8.19;
*/
interface IAccessController {
/*///////////////////////////////////////////////////////////////
EVENTS
ERRORS
//////////////////////////////////////////////////////////////*/
/**
* @notice Thrown when the caller has no access
*/
error AccessController_NoAccess();

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

/**
* @notice The access control struct
* @param user The address of the user
Expand All @@ -22,20 +27,4 @@ interface IAccessController {
address user;
bytes data;
}

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

/*///////////////////////////////////////////////////////////////
VARIABLES
//////////////////////////////////////////////////////////////*/

/*///////////////////////////////////////////////////////////////
LOGIC
//////////////////////////////////////////////////////////////*/
}
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

0 comments on commit 84fe5c0

Please sign in to comment.