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

feat: access control #50

Merged
merged 20 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from 12 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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"package.json": "sort-package-json"
},
"dependencies": {
"@defi-wonderland/prophet-core": "0.0.0-96d1084b",
"@defi-wonderland/prophet-modules": "0.0.0-b72dcda6"
"@defi-wonderland/prophet-core": "0.0.0-8bb062e0",
"@defi-wonderland/prophet-modules": "0.0.0-86078350"
},
"devDependencies": {
"@commitlint/cli": "19.3.0",
Expand Down
3 changes: 3 additions & 0 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ contract Deploy is Script {
_requestData.nonce = 0;

// Set requester and modules

_requestData.requester = address(eboRequestCreator);
// todo : replace with HorizonOperatorAccessModule
_requestData.accessModule = address(0);
_requestData.requestModule = address(eboRequestModule);
_requestData.responseModule = address(bondedResponseModule);
_requestData.disputeModule = address(bondEscalationModule);
Expand Down
13 changes: 10 additions & 3 deletions src/contracts/CouncilArbitrator.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.26;

import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol';
import {ValidatorLib} from '@defi-wonderland/prophet-core/solidity/libraries/ValidatorLib.sol';
import {IArbitrator} from '@defi-wonderland/prophet-modules/solidity/interfaces/IArbitrator.sol';

Expand Down Expand Up @@ -48,7 +49,8 @@ contract CouncilArbitrator is ICouncilArbitrator {
function resolve(
IOracle.Request calldata _request,
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
IOracle.Dispute calldata _dispute,
IAccessController.AccessControl calldata _accessControl
) external onlyArbitratorModule returns (bytes memory /* _data */ ) {
bytes32 _disputeId = _dispute._getId();

Expand All @@ -68,16 +70,21 @@ contract CouncilArbitrator is ICouncilArbitrator {
if (getAnswer[_disputeId] != IOracle.DisputeStatus.None) revert CouncilArbitrator_DisputeAlreadyArbitrated();

getAnswer[_disputeId] = _award;
// TODO: Make sure the access control is correct
IAccessController.AccessControl memory _accessControl =
IAccessController.AccessControl({user: address(this), data: bytes('')});

ORACLE.resolveDispute(_resolutionParams.request, _resolutionParams.response, _resolutionParams.dispute);
ORACLE.resolveDispute(
_resolutionParams.request, _resolutionParams.response, _resolutionParams.dispute, _accessControl
);

// If the request was not finalized, finalize it
if (ORACLE.finalizedAt(_resolutionParams.dispute.requestId) == 0) {
// If the dispute was lost, finalize with response
if (_award != IOracle.DisputeStatus.Lost) {
_resolutionParams.response.requestId = 0;
}
ORACLE.finalize(_resolutionParams.request, _resolutionParams.response);
ORACLE.finalize(_resolutionParams.request, _resolutionParams.response, _accessControl);
}

emit DisputeArbitrated(_disputeId, _award);
Expand Down
10 changes: 8 additions & 2 deletions src/contracts/EBOFinalityModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
pragma solidity 0.8.26;

import {IModule, Module} from '@defi-wonderland/prophet-core/solidity/contracts/Module.sol';
import {ModuleAccessController} from
'@defi-wonderland/prophet-modules/solidity/contracts/modules/access/ModuleAccessController.sol';

import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';

Expand All @@ -18,7 +20,7 @@ import {
* @notice Module allowing users to index data into the subgraph
* as a result of a request being finalized
*/
contract EBOFinalityModule is Module, IEBOFinalityModule {
contract EBOFinalityModule is ModuleAccessController, IEBOFinalityModule {
using EnumerableSet for EnumerableSet.AddressSet;

/// @inheritdoc IEBOFinalityModule
Expand All @@ -35,7 +37,11 @@ contract EBOFinalityModule is Module, IEBOFinalityModule {
* @param _eboRequestCreator The address of the EBORequestCreator
* @param _arbitrable The address of the Arbitrable contract
*/
constructor(IOracle _oracle, IEBORequestCreator _eboRequestCreator, IArbitrable _arbitrable) Module(_oracle) {
constructor(
IOracle _oracle,
IEBORequestCreator _eboRequestCreator,
IArbitrable _arbitrable
) ModuleAccessController(_oracle) {
_addEBORequestCreator(_eboRequestCreator);
ARBITRABLE = _arbitrable;
}
Expand Down
7 changes: 5 additions & 2 deletions src/contracts/EBORequestCreator.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.26;

import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol';
import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';

import {
Expand Down Expand Up @@ -81,10 +82,12 @@ contract EBORequestCreator is IEBORequestCreator {
) revert EBORequestCreator_RequestAlreadyCreated();

_requestModuleData.chainId = _chainId;

_requestData.requestModuleData = abi.encode(_requestModuleData);

_requestId = ORACLE.createRequest(_requestData, bytes32(0));
// TODO: Make sure the access control is correct
IAccessController.AccessControl memory _accessControl =
IAccessController.AccessControl({user: address(this), data: bytes('')});
_requestId = ORACLE.createRequest(_requestData, bytes32(0), _accessControl);

requestIdPerChainAndEpoch[_chainId][_epoch] = _requestId;

Expand Down
11 changes: 8 additions & 3 deletions src/contracts/EBORequestModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
pragma solidity 0.8.26;

import {IModule, Module} from '@defi-wonderland/prophet-core/solidity/contracts/Module.sol';

import {ModuleAccessController} from
'@defi-wonderland/prophet-modules/solidity/contracts/modules/access/ModuleAccessController.sol';
import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';

import {IArbitrable, IEBORequestCreator, IEBORequestModule, IOracle} from 'interfaces/IEBORequestModule.sol';
Expand All @@ -11,7 +12,7 @@ import {IArbitrable, IEBORequestCreator, IEBORequestModule, IOracle} from 'inter
* @title EBORequestModule
* @notice Module allowing users to create a request for RPC data for a specific epoch
*/
contract EBORequestModule is Module, IEBORequestModule {
contract EBORequestModule is ModuleAccessController, IEBORequestModule {
using EnumerableSet for EnumerableSet.AddressSet;

/// @inheritdoc IEBORequestModule
Expand All @@ -28,7 +29,11 @@ contract EBORequestModule is Module, IEBORequestModule {
* @param _eboRequestCreator The address of the EBORequestCreator
* @param _arbitrable The address of the Arbitrable contract
*/
constructor(IOracle _oracle, IEBORequestCreator _eboRequestCreator, IArbitrable _arbitrable) Module(_oracle) {
constructor(
IOracle _oracle,
IEBORequestCreator _eboRequestCreator,
IArbitrable _arbitrable
) ModuleAccessController(_oracle) {
_addEBORequestCreator(_eboRequestCreator);
ARBITRABLE = _arbitrable;
}
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/IEBORequestCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ interface IEBORequestCreator {
* @return _disputeModule The dispute module address
* @return _resolutionModule The resolution module address
* @return _finalityModule The finality module address
* @return _accessControlModule The address of the access control module
* @return _requestModuleData The request module data
* @return _responseModuleData The response module data
* @return _disputeModuleData The dispute module data
Expand All @@ -170,6 +171,7 @@ interface IEBORequestCreator {
address _disputeModule,
address _resolutionModule,
address _finalityModule,
address _accessControlModule,
bytes memory _requestModuleData,
bytes memory _responseModuleData,
bytes memory _disputeModuleData,
Expand Down
11 changes: 8 additions & 3 deletions test/integration/arbitrum/CreateRequest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ contract IntegrationCreateRequest is IntegrationBase {

// Should revert if the requester is not the EBORequestCreator
vm.expectRevert(IEBORequestModule.EBORequestModule_InvalidRequester.selector);
vm.prank(_requester);
_requestData.requester = _requester;
oracle.createRequest(_requestData, '');
_accessControl.user = _requester;

vm.prank(_requester);
oracle.createRequest(_requestData, '', _accessControl);

// Should revert if the epoch is invalid
vm.expectRevert(IEBORequestCreator.EBORequestCreator_InvalidEpoch.selector);
Expand All @@ -42,9 +44,12 @@ contract IntegrationCreateRequest is IntegrationBase {
_requestParams.chainId = _chainId;
_requestData.requestModuleData = abi.encode(_requestParams);
_requestData.requester = address(eboRequestCreator);
_accessControl.user = address(eboRequestCreator);

// Expect the oracle to create the request
vm.expectCall(address(oracle), abi.encodeWithSelector(IOracle.createRequest.selector, _requestData, bytes32(0)));
vm.expectCall(
address(oracle), abi.encodeWithSelector(IOracle.createRequest.selector, _requestData, bytes32(0), _accessControl)
);

vm.prank(_requester);
eboRequestCreator.createRequest(_currentEpoch, _chainId);
Expand Down
16 changes: 0 additions & 16 deletions test/integration/arbitrum/FinalizeRequest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import './IntegrationBase.t.sol';

contract IntegrationFinalizeRequest is IntegrationBase {
bytes32 _requestId;

Check warning on line 7 in test/integration/arbitrum/FinalizeRequest.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Explicitly mark visibility of state

Check warning on line 7 in test/integration/arbitrum/FinalizeRequest.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Explicitly mark visibility of state
uint256 _requestCreatedAt;

Check warning on line 8 in test/integration/arbitrum/FinalizeRequest.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Explicitly mark visibility of state

Check warning on line 8 in test/integration/arbitrum/FinalizeRequest.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Explicitly mark visibility of state

function setUp() public override {
super.setUp();
Expand Down Expand Up @@ -105,8 +105,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request is finalized without response when a response without dispute exists
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_FinalizableResponseExists.selector, _responseId));
_finalizeRequest(_requestId, 0);
Expand Down Expand Up @@ -156,8 +154,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request is finalized without response when a response without dispute exists
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_FinalizableResponseExists.selector, _responseId));
_finalizeRequest(_requestId, 0);
Expand Down Expand Up @@ -210,8 +206,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request is finalized without response when a response without dispute exists
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_FinalizableResponseExists.selector, _responseId));
_finalizeRequest(_requestId, 0);
Expand Down Expand Up @@ -305,8 +299,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request is finalized without response when a response without dispute exists
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_FinalizableResponseExists.selector, _responseId));
_finalizeRequest(_requestId, 0);
Expand Down Expand Up @@ -350,8 +342,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request has not been finalized
vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidReleaseParameters.selector);
_releaseUnfinalizableResponseBond(_requestId, _responseId);
Expand Down Expand Up @@ -404,8 +394,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request has not been finalized
vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidReleaseParameters.selector);
_releaseUnfinalizableResponseBond(_requestId, _responseId);
Expand Down Expand Up @@ -457,8 +445,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request has not been finalized
vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidReleaseParameters.selector);
_releaseUnfinalizableResponseBond(_requestId, _responseId);
Expand Down Expand Up @@ -570,8 +556,6 @@
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);

uint256 _responseCreatedAt = oracle.responseCreatedAt(_responseId);

// Revert if the request has not been finalized
vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidReleaseParameters.selector);
_releaseUnfinalizableResponseBond(_requestId, _responseId);
Expand Down
42 changes: 31 additions & 11 deletions test/integration/arbitrum/IntegrationBase.t.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.26;

import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol';
import {ValidatorLib} from '@defi-wonderland/prophet-core/solidity/libraries/ValidatorLib.sol';

import {_ARBITRUM_SEPOLIA_GOVERNOR} from 'script/Constants.sol';

import 'forge-std/Test.sol';
import 'script/Deploy.s.sol';

import 'forge-std/Test.sol';
import '../../utils/Helpers.sol';

contract IntegrationBase is Deploy, Test {
contract IntegrationBase is Deploy, Test, Helpers {
using ValidatorLib for IOracle.Request;
using ValidatorLib for IOracle.Response;
using ValidatorLib for IOracle.Dispute;
Expand All @@ -36,6 +38,8 @@ contract IntegrationBase is Deploy, Test {
uint256 internal _currentEpoch;
uint256 internal _blockNumber;

IAccessController.AccessControl internal _accessControl;

function setUp() public virtual override {
vm.createSelectFork(vm.rpcUrl('arbitrum'), _ARBITRUM_SEPOLIA_FORK_BLOCK);

Expand All @@ -62,6 +66,9 @@ contract IntegrationBase is Deploy, Test {

// Set block number
_blockNumber = block.number;

// Configure the access control
_accessControl = IAccessController.AccessControl({user: address(0), data: bytes('')});
}

function _createRequest() internal returns (bytes32 _requestId) {
Expand All @@ -86,11 +93,13 @@ contract IntegrationBase is Deploy, Test {

function _proposeResponse(bytes32 _requestId) internal returns (bytes32 _responseId) {
IOracle.Request memory _requestData = _requests[_requestId];

IOracle.Response memory _responseData = _instantiateResponseData(_requestId);

// Set the caller
_accessControl.user = _proposer;

vm.prank(_proposer);
oracle.proposeResponse(_requestData, _responseData);
oracle.proposeResponse(_requestData, _responseData, _accessControl);

_responseId = _responseData._getId();
_responses[_responseId] = _responseData;
Expand All @@ -99,11 +108,13 @@ contract IntegrationBase is Deploy, Test {
function _disputeResponse(bytes32 _requestId, bytes32 _responseId) internal returns (bytes32 _disputeId) {
IOracle.Request memory _requestData = _requests[_requestId];
IOracle.Response memory _responseData = _responses[_responseId];

IOracle.Dispute memory _disputeData = _instantiateDisputeData(_requestId, _responseId);

// Set the caller
_accessControl.user = _disputer;

vm.prank(_disputer);
oracle.disputeResponse(_requestData, _responseData, _disputeData);
oracle.disputeResponse(_requestData, _responseData, _disputeData, _accessControl);

_disputeId = _disputeData._getId();
_disputes[_disputeId] = _disputeData;
Expand All @@ -115,7 +126,7 @@ contract IntegrationBase is Deploy, Test {

function _pledgeForDispute(address _sender, bytes32 _requestId, bytes32 _disputeId) internal {
vm.prank(_sender);
bondEscalationModule.pledgeForDispute(_requests[_requestId], _disputes[_disputeId]);
bondEscalationModule.pledgeForDispute(_requests[_requestId], _disputes[_disputeId], _createAccessControl());
}

function _pledgeAgainstDispute(bytes32 _requestId, bytes32 _disputeId) internal {
Expand All @@ -124,7 +135,7 @@ contract IntegrationBase is Deploy, Test {

function _pledgeAgainstDispute(address _sender, bytes32 _requestId, bytes32 _disputeId) internal {
vm.prank(_sender);
bondEscalationModule.pledgeAgainstDispute(_requests[_requestId], _disputes[_disputeId]);
bondEscalationModule.pledgeAgainstDispute(_requests[_requestId], _disputes[_disputeId], _createAccessControl());
}

function _settleBondEscalation(bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) internal {
Expand All @@ -140,15 +151,21 @@ contract IntegrationBase is Deploy, Test {
IOracle.Response memory _responseData = _responses[_responseId];
IOracle.Dispute memory _disputeData = _disputes[_disputeId];

oracle.escalateDispute(_requestData, _responseData, _disputeData);
// Set the caller
_accessControl.user = address(this);

oracle.escalateDispute(_requestData, _responseData, _disputeData, _accessControl);
}

function _resolveDispute(bytes32 _requestId, bytes32 _responseId, bytes32 _disputeId) internal {
IOracle.Request memory _requestData = _requests[_requestId];
IOracle.Response memory _responseData = _responses[_responseId];
IOracle.Dispute memory _disputeData = _disputes[_disputeId];

oracle.resolveDispute(_requestData, _responseData, _disputeData);
// Set the caller
_accessControl.user = address(this);

oracle.resolveDispute(_requestData, _responseData, _disputeData, _accessControl);
}

function _arbitrateDispute(bytes32 _disputeId, IOracle.DisputeStatus _award) internal {
Expand All @@ -160,7 +177,10 @@ contract IntegrationBase is Deploy, Test {
IOracle.Request memory _requestData = _requests[_requestId];
IOracle.Response memory _responseData = _responses[_responseId];

oracle.finalize(_requestData, _responseData);
// Set the caller
_accessControl.user = address(this);

oracle.finalize(_requestData, _responseData, _accessControl);
}

function _releaseUnfinalizableResponseBond(bytes32 _requestId, bytes32 _responseId) internal {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/Arbitrable.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ contract Arbitrable_Unit_ValidateArbitrator is Arbitrable_Unit_BaseTest {
arbitrable.validateArbitrator(_caller);
}

function test_validateArbitrator() public {
function test_validateArbitrator() public view {
arbitrable.validateArbitrator(arbitrator);
}
}
Loading
Loading