From 822962a02ea0d5cab5a32b0e9c911081fa4f345f Mon Sep 17 00:00:00 2001 From: xorsal Date: Tue, 12 Nov 2024 10:46:04 -0500 Subject: [PATCH] feat: access control (#74) Co-authored-by: Ashitaka Co-authored-by: Gas One Cent <86567384+gas1cent@users.noreply.github.com> --- package.json | 2 +- .../extensions/BondEscalationAccounting.sol | 1 + .../modules/access/ModuleAccessController.sol | 51 +++++ .../modules/dispute/BondEscalationModule.sol | 63 ++++-- .../modules/dispute/CircuitResolverModule.sol | 15 +- .../dispute/RootVerificationModule.sol | 14 +- .../modules/resolution/ArbitratorModule.sol | 7 +- .../BondEscalationResolutionModule.sol | 187 ++++++++++------ .../resolution/ERC20ResolutionModule.sol | 66 ++++-- .../PrivateERC20ResolutionModule.sol | 80 +++++-- .../modules/response/BondedResponseModule.sol | 6 +- solidity/contracts/utils/ModuleTypehash.sol | 26 +++ solidity/interfaces/IArbitrator.sol | 1 + .../access/IModuleAccessController.sol | 35 +++ .../modules/dispute/IBondEscalationModule.sol | 15 +- .../IBondEscalationResolutionModule.sol | 18 +- .../resolution/IERC20ResolutionModule.sol | 12 +- .../IPrivateERC20ResolutionModule.sol | 10 +- .../integration/AccountingExtension.t.sol | 2 +- solidity/test/integration/Arbitration.t.sol | 12 +- .../test/integration/BondEscalation.t.sol | 82 +++---- .../test/integration/CallbackModule.t.sol | 8 +- .../integration/ContractCallRequest.t.sol | 13 +- .../test/integration/EscalateDispute.t.sol | 79 ++++--- solidity/test/integration/Finalization.t.sol | 14 +- solidity/test/integration/HttpRequest.t.sol | 10 +- solidity/test/integration/IntegrationBase.sol | 10 +- .../integration/MultipleCallbacksModule.t.sol | 10 +- solidity/test/integration/Payments.t.sol | 4 +- .../test/integration/RequestCreation.t.sol | 20 +- .../test/integration/ResponseDispute.t.sol | 16 +- .../test/integration/ResponseProposal.t.sol | 24 +-- .../test/integration/RootVerification.t.sol | 14 +- solidity/test/mocks/MockArbitrator.sol | 2 + solidity/test/mocks/MockAtomicArbitrator.sol | 3 +- .../dispute/BondEscalationModule.t.sol | 201 ++++++++++++++++-- .../dispute/CircuitResolverModule.t.sol | 32 +-- .../dispute/RootVerificationModule.t.sol | 12 +- .../BondEscalationResolutionModule.t.sol | 58 +++-- .../resolution/ERC20ResolutionModule.t.sol | 16 +- .../PrivateERC20ResolutionModule.t.sol | 45 ++-- .../response/BondedResponseModule.t.sol | 2 + solidity/test/utils/Helpers.sol | 19 ++ yarn.lock | 8 +- 44 files changed, 943 insertions(+), 382 deletions(-) create mode 100644 solidity/contracts/modules/access/ModuleAccessController.sol create mode 100644 solidity/contracts/utils/ModuleTypehash.sol create mode 100644 solidity/interfaces/modules/access/IModuleAccessController.sol diff --git a/package.json b/package.json index 3a191166..7e90eff5 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "package.json": "sort-package-json" }, "dependencies": { - "@defi-wonderland/prophet-core": "0.0.0-4d28a0ec", + "@defi-wonderland/prophet-core": "0.0.0-0e46031c", "@openzeppelin/contracts": "4.9.5", "solmate": "https://github.com/transmissions11/solmate.git#bfc9c25865a274a7827fea5abf6e4fb64fc64e6c" }, diff --git a/solidity/contracts/extensions/BondEscalationAccounting.sol b/solidity/contracts/extensions/BondEscalationAccounting.sol index cd0d4fb4..7465039c 100644 --- a/solidity/contracts/extensions/BondEscalationAccounting.sol +++ b/solidity/contracts/extensions/BondEscalationAccounting.sol @@ -29,6 +29,7 @@ contract BondEscalationAccounting is AccountingExtension, IBondEscalationAccount } } + /// @notice Checks if the caller is an authorized caller modifier onlyAuthorizedCaller() { if (!authorizedCallers[msg.sender]) revert BondEscalationAccounting_UnauthorizedCaller(); _; diff --git a/solidity/contracts/modules/access/ModuleAccessController.sol b/solidity/contracts/modules/access/ModuleAccessController.sol new file mode 100644 index 00000000..58d09859 --- /dev/null +++ b/solidity/contracts/modules/access/ModuleAccessController.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {CommonAccessController} from '@defi-wonderland/prophet-core/solidity/contracts/CommonAccessController.sol'; + +import {IModuleAccessController} from '../../../interfaces/modules/access/IModuleAccessController.sol'; +import {Module} from '@defi-wonderland/prophet-core/solidity/contracts/Module.sol'; +import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; + +abstract contract ModuleAccessController is IModuleAccessController, CommonAccessController, Module { + constructor(IOracle _oracle) Module(_oracle) {} + + /** + * @notice Returns an access control object using the contract address as user and the given data + * @dev should only be used by modules as the self-access-control object + * @param _data Arbitrary data + * @return _accessControl The self access control for this contract. + */ + function _defaultAccessControl(bytes memory _data) internal view returns (AccessControl memory _accessControl) { + _accessControl = AccessControl({user: address(this), data: _data}); + } + + /** + * @notice Returns an access control object using the contract address as user, and empty data + * + * @dev should only be used by modules as the self-access-control object + * @return _accessControl The self access control for this contract. + */ + function _defaultAccessControl() internal view returns (AccessControl memory _accessControl) { + _accessControl = _defaultAccessControl(bytes('')); + } + + 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 (!ORACLE.isAccessModuleApproved(_accessControl.user, _accessModule)) { + revert ModuleAccessController_AccessModuleNotApproved(); + } + _hasAccess(_accessModule, _typehash, _params, _accessControl); + } + } + _; + } +} diff --git a/solidity/contracts/modules/dispute/BondEscalationModule.sol b/solidity/contracts/modules/dispute/BondEscalationModule.sol index 35e5f652..72ec4689 100644 --- a/solidity/contracts/modules/dispute/BondEscalationModule.sol +++ b/solidity/contracts/modules/dispute/BondEscalationModule.sol @@ -7,7 +7,11 @@ import {FixedPointMathLib} from 'solmate/src/utils/FixedPointMathLib.sol'; import {IBondEscalationModule} from '../../../interfaces/modules/dispute/IBondEscalationModule.sol'; -contract BondEscalationModule is Module, IBondEscalationModule { +import {ModuleAccessController} from '../access/ModuleAccessController.sol'; + +import {ModuleTypehash} from '../../utils/ModuleTypehash.sol'; + +contract BondEscalationModule is ModuleAccessController, IBondEscalationModule { /// @inheritdoc IBondEscalationModule mapping(bytes32 _requestId => mapping(address _pledger => uint256 pledges)) public pledgesForDispute; @@ -19,7 +23,7 @@ contract BondEscalationModule is Module, IBondEscalationModule { */ mapping(bytes32 _requestId => BondEscalation) internal _escalations; - constructor(IOracle _oracle) Module(_oracle) {} + constructor(IOracle _oracle) ModuleAccessController(_oracle) {} /// @inheritdoc IModule function moduleName() external pure returns (string memory _moduleName) { @@ -61,7 +65,7 @@ contract BondEscalationModule is Module, IBondEscalationModule { _escalation.disputeId = _disputeId; emit BondEscalationStatusUpdated(_dispute.requestId, _disputeId, BondEscalationStatus.Active); } else if (_disputeId != _escalation.disputeId) { - ORACLE.escalateDispute(_request, _response, _dispute); + ORACLE.escalateDispute(_request, _response, _dispute, _defaultAccessControl()); } } @@ -208,39 +212,67 @@ contract BondEscalationModule is Module, IBondEscalationModule { //////////////////////////////////////////////////////////////////// /// @inheritdoc IBondEscalationModule - function pledgeForDispute(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external { + function pledgeForDispute( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._PLEDGE_FOR_DISPUTE_TYPEHASH, + abi.encode(_request, _dispute), + _accessControl + ) + { bytes32 _disputeId = _getId(_dispute); RequestParameters memory _params = _pledgeChecks(_request, _dispute, true); + address _pledger = _accessControl.user; + _escalations[_dispute.requestId].amountOfPledgesForDispute += 1; - pledgesForDispute[_dispute.requestId][msg.sender] += 1; + pledgesForDispute[_dispute.requestId][_pledger] += 1; _params.accountingExtension.pledge({ - _pledger: msg.sender, + _pledger: _pledger, _request: _request, _dispute: _dispute, _token: _params.bondToken, _amount: _params.bondSize }); - emit PledgedForDispute(_disputeId, msg.sender, _params.bondSize); + emit PledgedForDispute(_disputeId, _pledger, _params.bondSize); } /// @inheritdoc IBondEscalationModule - function pledgeAgainstDispute(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external { + function pledgeAgainstDispute( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._PLEDGE_AGAINST_DISPUTE_TYPEHASH, + abi.encode(_request, _dispute), + _accessControl + ) + { bytes32 _disputeId = _getId(_dispute); RequestParameters memory _params = _pledgeChecks(_request, _dispute, false); + address _pledger = _accessControl.user; + _escalations[_dispute.requestId].amountOfPledgesAgainstDispute += 1; - pledgesAgainstDispute[_dispute.requestId][msg.sender] += 1; + pledgesAgainstDispute[_dispute.requestId][_pledger] += 1; _params.accountingExtension.pledge({ - _pledger: msg.sender, + _pledger: _pledger, _request: _request, _dispute: _dispute, _token: _params.bondToken, _amount: _params.bondSize }); - emit PledgedAgainstDispute(_disputeId, msg.sender, _params.bondSize); + emit PledgedAgainstDispute(_disputeId, _pledger, _params.bondSize); } /// @inheritdoc IBondEscalationModule @@ -274,9 +306,12 @@ contract BondEscalationModule is Module, IBondEscalationModule { emit BondEscalationStatusUpdated(_dispute.requestId, _disputeId, _escalation.status); - ORACLE.updateDisputeStatus( - _request, _response, _dispute, _disputersWon ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost - ); + ORACLE.updateDisputeStatus({ + _request: _request, + _response: _response, + _dispute: _dispute, + _status: _disputersWon ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost + }); } /** diff --git a/solidity/contracts/modules/dispute/CircuitResolverModule.sol b/solidity/contracts/modules/dispute/CircuitResolverModule.sol index e4c955d9..c7d06d7b 100644 --- a/solidity/contracts/modules/dispute/CircuitResolverModule.sol +++ b/solidity/contracts/modules/dispute/CircuitResolverModule.sol @@ -7,11 +7,13 @@ import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle import {IProphetVerifier} from '../../../interfaces/IProphetVerifier.sol'; import {ICircuitResolverModule} from '../../../interfaces/modules/dispute/ICircuitResolverModule.sol'; -contract CircuitResolverModule is Module, ICircuitResolverModule { +import {ModuleAccessController} from '../access/ModuleAccessController.sol'; + +contract CircuitResolverModule is ModuleAccessController, ICircuitResolverModule { /// @notice Keeps track of the correct responses to requests mapping(bytes32 _requestId => bytes _correctResponse) internal _correctResponses; - constructor(IOracle _oracle) Module(_oracle) {} + constructor(IOracle _oracle) ModuleAccessController(_oracle) {} /// @inheritdoc IModule function moduleName() external pure returns (string memory _moduleName) { @@ -32,6 +34,7 @@ contract CircuitResolverModule is Module, ICircuitResolverModule { ) external onlyOracle { RequestParameters memory _params = decodeRequestData(_request.disputeModuleData); IOracle.DisputeStatus _status = ORACLE.disputeStatus(_disputeId); + AccessControl memory _accessControl = _defaultAccessControl(); if (_status == IOracle.DisputeStatus.Won) { _params.accountingExtension.pay({ @@ -50,12 +53,12 @@ contract CircuitResolverModule is Module, ICircuitResolverModule { emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Won}); - ORACLE.proposeResponse(_request, _newResponse); - ORACLE.finalize(_request, _newResponse); + ORACLE.proposeResponse(_request, _newResponse, _accessControl); + ORACLE.finalize(_request, _newResponse, _accessControl); } else { emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Lost}); - ORACLE.finalize(_request, _response); + ORACLE.finalize(_request, _response, _accessControl); } delete _correctResponses[_dispute.requestId]; @@ -88,7 +91,7 @@ contract CircuitResolverModule is Module, ICircuitResolverModule { _dispute: _dispute }); - ORACLE.updateDisputeStatus(_request, _response, _dispute, _status); + ORACLE.updateDisputeStatus({_request: _request, _response: _response, _dispute: _dispute, _status: _status}); } /// @inheritdoc IModule diff --git a/solidity/contracts/modules/dispute/RootVerificationModule.sol b/solidity/contracts/modules/dispute/RootVerificationModule.sol index 775d26b7..24e164a6 100644 --- a/solidity/contracts/modules/dispute/RootVerificationModule.sol +++ b/solidity/contracts/modules/dispute/RootVerificationModule.sol @@ -6,8 +6,9 @@ import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle import {IRootVerificationModule} from '../../../interfaces/modules/dispute/IRootVerificationModule.sol'; import {MerkleLib} from '../../libraries/MerkleLib.sol'; +import {ModuleAccessController} from '../access/ModuleAccessController.sol'; -contract RootVerificationModule is Module, IRootVerificationModule { +contract RootVerificationModule is ModuleAccessController, IRootVerificationModule { using MerkleLib for MerkleLib.Tree; /** @@ -15,7 +16,7 @@ contract RootVerificationModule is Module, IRootVerificationModule { */ mapping(bytes32 _requestId => bytes32 _correctRoot) internal _correctRoots; - constructor(IOracle _oracle) Module(_oracle) {} + constructor(IOracle _oracle) ModuleAccessController(_oracle) {} /// @inheritdoc IModule function moduleName() external pure returns (string memory _moduleName) { @@ -36,6 +37,7 @@ contract RootVerificationModule is Module, IRootVerificationModule { ) external onlyOracle { RequestParameters memory _params = decodeRequestData(_request.disputeModuleData); IOracle.DisputeStatus _status = ORACLE.disputeStatus(_disputeId); + AccessControl memory _accessControl = _defaultAccessControl(); if (_status == IOracle.DisputeStatus.Won) { _params.accountingExtension.pay({ @@ -54,11 +56,11 @@ contract RootVerificationModule is Module, IRootVerificationModule { emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Won}); - ORACLE.proposeResponse(_request, _newResponse); - ORACLE.finalize(_request, _newResponse); + ORACLE.proposeResponse(_request, _newResponse, _accessControl); + ORACLE.finalize(_request, _newResponse, _accessControl); } else { emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Lost}); - ORACLE.finalize(_request, _response); + ORACLE.finalize(_request, _response, _accessControl); } delete _correctRoots[_dispute.requestId]; @@ -86,7 +88,7 @@ contract RootVerificationModule is Module, IRootVerificationModule { _dispute: _dispute }); - ORACLE.updateDisputeStatus(_request, _response, _dispute, _status); + ORACLE.updateDisputeStatus({_request: _request, _response: _response, _dispute: _dispute, _status: _status}); } /// @inheritdoc IModule diff --git a/solidity/contracts/modules/resolution/ArbitratorModule.sol b/solidity/contracts/modules/resolution/ArbitratorModule.sol index 4dd8fe01..497dfa16 100644 --- a/solidity/contracts/modules/resolution/ArbitratorModule.sol +++ b/solidity/contracts/modules/resolution/ArbitratorModule.sol @@ -6,14 +6,15 @@ import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle import {IArbitrator} from '../../../interfaces/IArbitrator.sol'; import {IArbitratorModule} from '../../../interfaces/modules/resolution/IArbitratorModule.sol'; +import {ModuleAccessController} from '../access/ModuleAccessController.sol'; -contract ArbitratorModule is Module, IArbitratorModule { +contract ArbitratorModule is ModuleAccessController, IArbitratorModule { /** * @notice The status of all disputes */ mapping(bytes32 _disputeId => ArbitrationStatus _status) internal _disputeData; - constructor(IOracle _oracle) Module(_oracle) {} + constructor(IOracle _oracle) ModuleAccessController(_oracle) {} /// @inheritdoc IModule function moduleName() external pure returns (string memory _moduleName) { @@ -61,7 +62,7 @@ contract ArbitratorModule is Module, IArbitratorModule { if (_status <= IOracle.DisputeStatus.Escalated) revert ArbitratorModule_InvalidResolutionStatus(); _disputeData[_disputeId] = ArbitrationStatus.Resolved; - ORACLE.updateDisputeStatus(_request, _response, _dispute, _status); + ORACLE.updateDisputeStatus({_request: _request, _response: _response, _dispute: _dispute, _status: _status}); emit DisputeResolved(_dispute.requestId, _disputeId, _status); } diff --git a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol index ca12c694..63002a90 100644 --- a/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol +++ b/solidity/contracts/modules/resolution/BondEscalationResolutionModule.sol @@ -16,8 +16,11 @@ import {IResolutionModule} from import {IBondEscalationResolutionModule} from '../../../interfaces/modules/resolution/IBondEscalationResolutionModule.sol'; +import {ModuleAccessController} from '../access/ModuleAccessController.sol'; -contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModule { +import {ModuleTypehash} from '../../utils/ModuleTypehash.sol'; + +contract BondEscalationResolutionModule is ModuleAccessController, IBondEscalationResolutionModule { using SafeERC20 for IERC20; /// @inheritdoc IBondEscalationResolutionModule @@ -35,7 +38,7 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu /// @inheritdoc IBondEscalationResolutionModule mapping(bytes32 _disputeId => mapping(address _pledger => uint256 pledges)) public pledgesAgainstDispute; - constructor(IOracle _oracle) Module(_oracle) {} + constructor(IOracle _oracle) ModuleAccessController(_oracle) {} /// @inheritdoc IModule function moduleName() external pure returns (string memory _moduleName) { @@ -62,18 +65,48 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu function pledgeForDispute( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, - uint256 _pledgeAmount - ) external { - _pledge(_request, _dispute, _pledgeAmount, true); + uint256 _pledgeAmount, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._PLEDGE_FOR_DISPUTE_TYPEHASH, + abi.encode(_request, _dispute, _pledgeAmount), + _accessControl + ) + { + _pledge({ + _request: _request, + _dispute: _dispute, + _pledgeAmount: _pledgeAmount, + _pledgingFor: true, + _pledger: _accessControl.user + }); } /// @inheritdoc IBondEscalationResolutionModule function pledgeAgainstDispute( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, - uint256 _pledgeAmount - ) external { - _pledge(_request, _dispute, _pledgeAmount, false); + uint256 _pledgeAmount, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._PLEDGE_AGAINST_DISPUTE_TYPEHASH, + abi.encode(_request, _dispute, _pledgeAmount), + _accessControl + ) + { + _pledge({ + _request: _request, + _dispute: _dispute, + _pledgeAmount: _pledgeAmount, + _pledgingFor: false, + _pledger: _accessControl.user + }); } /// @inheritdoc IResolutionModule @@ -116,75 +149,102 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu _disputeStatus = IOracle.DisputeStatus.Lost; } - ORACLE.updateDisputeStatus(_request, _response, _dispute, _disputeStatus); + ORACLE.updateDisputeStatus({_request: _request, _response: _response, _dispute: _dispute, _status: _disputeStatus}); emit DisputeResolved(_dispute.requestId, _disputeId, _disputeStatus); } /// @inheritdoc IBondEscalationResolutionModule - function claimPledge(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external { + function claimPledge( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._CLAIM_PLEDGE_TYPEHASH, + abi.encode(_request, _dispute), + _accessControl + ) + { bytes32 _disputeId = _validateDispute(_request, _dispute); Escalation storage _escalation = escalations[_disputeId]; if (_escalation.resolution == Resolution.Unresolved) revert BondEscalationResolutionModule_NotResolved(); - uint256 _pledgerBalanceBefore; - uint256 _pledgerProportion; - uint256 _amountToRelease; - uint256 _reward; RequestParameters memory _params = decodeRequestData(_request.resolutionModuleData); - if (_escalation.resolution == Resolution.DisputerWon) { - _pledgerBalanceBefore = pledgesForDispute[_disputeId][msg.sender]; - pledgesForDispute[_disputeId][msg.sender] -= _pledgerBalanceBefore; - _pledgerProportion = FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesFor); - _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesAgainst, _pledgerProportion, BASE); - _amountToRelease = _reward + _pledgerBalanceBefore; - _claimPledge({ - _request: _request, - _dispute: _dispute, - _amountToRelease: _amountToRelease, - _resolution: _escalation.resolution, - _params: _params - }); - } else if (_escalation.resolution == Resolution.DisputerLost) { - _pledgerBalanceBefore = pledgesAgainstDispute[_disputeId][msg.sender]; - pledgesAgainstDispute[_disputeId][msg.sender] -= _pledgerBalanceBefore; - _pledgerProportion = FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesAgainst); - _reward = FixedPointMathLib.mulDivDown(_escalation.pledgesFor, _pledgerProportion, BASE); - _amountToRelease = _reward + _pledgerBalanceBefore; - _claimPledge({ - _request: _request, - _dispute: _dispute, - _amountToRelease: _amountToRelease, - _resolution: _escalation.resolution, - _params: _params - }); - } else if (_escalation.resolution == Resolution.NoResolution) { - uint256 _pledgerBalanceFor = pledgesForDispute[_disputeId][msg.sender]; - uint256 _pledgerBalanceAgainst = pledgesAgainstDispute[_disputeId][msg.sender]; + address _pledger = _accessControl.user; - if (_pledgerBalanceFor > 0) { - pledgesForDispute[_disputeId][msg.sender] -= _pledgerBalanceFor; + { + uint256 _pledgerBalanceBefore; + uint256 _reward; + + if (_escalation.resolution == Resolution.DisputerWon) { + _pledgerBalanceBefore = pledgesForDispute[_disputeId][_pledger]; + pledgesForDispute[_disputeId][_pledger] -= _pledgerBalanceBefore; + _reward = FixedPointMathLib.mulDivDown( + _escalation.pledgesAgainst, + FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesFor), + BASE + ); _claimPledge({ _request: _request, _dispute: _dispute, - _amountToRelease: _pledgerBalanceFor, + _amountToRelease: _reward + _pledgerBalanceBefore, + _pledger: _pledger, _resolution: _escalation.resolution, _params: _params }); - } - - if (_pledgerBalanceAgainst > 0) { - pledgesAgainstDispute[_disputeId][msg.sender] -= _pledgerBalanceAgainst; + } else if (_escalation.resolution == Resolution.DisputerLost) { + _pledgerBalanceBefore = pledgesAgainstDispute[_disputeId][_pledger]; + pledgesAgainstDispute[_disputeId][_pledger] -= _pledgerBalanceBefore; + _reward = FixedPointMathLib.mulDivDown( + _escalation.pledgesFor, + FixedPointMathLib.mulDivDown(_pledgerBalanceBefore, BASE, _escalation.pledgesAgainst), + BASE + ); _claimPledge({ _request: _request, _dispute: _dispute, - _amountToRelease: _pledgerBalanceAgainst, + _amountToRelease: _reward + _pledgerBalanceBefore, + _pledger: _pledger, _resolution: _escalation.resolution, _params: _params }); } } + + if (_escalation.resolution == Resolution.NoResolution) { + { + uint256 _pledgerBalanceFor = pledgesForDispute[_disputeId][_pledger]; + if (_pledgerBalanceFor > 0) { + pledgesForDispute[_disputeId][_pledger] -= _pledgerBalanceFor; + _claimPledge({ + _request: _request, + _dispute: _dispute, + _amountToRelease: _pledgerBalanceFor, + _pledger: _pledger, + _resolution: _escalation.resolution, + _params: _params + }); + } + } + { + uint256 _pledgerBalanceAgainst = pledgesAgainstDispute[_disputeId][_pledger]; + if (_pledgerBalanceAgainst > 0) { + pledgesAgainstDispute[_disputeId][_pledger] -= _pledgerBalanceAgainst; + _claimPledge({ + _request: _request, + _dispute: _dispute, + _amountToRelease: _pledgerBalanceAgainst, + _pledger: _pledger, + _resolution: _escalation.resolution, + _params: _params + }); + } + } + } } /** @@ -194,12 +254,14 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu * @param _dispute The dispute to vote for or against * @param _pledgeAmount The amount to pledge * @param _pledgingFor Whether the pledger is pledging for or against the dispute + * @param _pledger The address of the pledger */ function _pledge( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, uint256 _pledgeAmount, - bool _pledgingFor + bool _pledgingFor, + address _pledger ) internal { bytes32 _disputeId = _validateDispute(_request, _dispute); Escalation storage _escalation = escalations[_disputeId]; @@ -209,9 +271,9 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu InequalityData storage _inequalityData = inequalityData[_disputeId]; RequestParameters memory _params = decodeRequestData(_request.resolutionModuleData); - uint256 _pledgingDeadline = _escalation.startTime + _params.timeUntilDeadline; - - if (block.timestamp >= _pledgingDeadline) revert BondEscalationResolutionModule_PledgingPhaseOver(); + if (block.timestamp >= _escalation.startTime + _params.timeUntilDeadline) { + revert BondEscalationResolutionModule_PledgingPhaseOver(); + } // Revert if the inequality timer has passed if (_inequalityData.time != 0 && block.timestamp >= _inequalityData.time + _params.timeToBreakInequality) { @@ -219,7 +281,7 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu } _params.accountingExtension.pledge({ - _pledger: msg.sender, + _pledger: _pledger, _request: _request, _dispute: _dispute, _token: _params.bondToken, @@ -232,16 +294,16 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu } _escalation.pledgesFor += _pledgeAmount; - pledgesForDispute[_disputeId][msg.sender] += _pledgeAmount; - emit PledgedForDispute(msg.sender, _dispute.requestId, _disputeId, _pledgeAmount); + pledgesForDispute[_disputeId][_pledger] += _pledgeAmount; + emit PledgedForDispute(_pledger, _dispute.requestId, _disputeId, _pledgeAmount); } else { if (_inequalityData.inequalityStatus == InequalityStatus.ForTurnToEqualize) { revert BondEscalationResolutionModule_ForTurnToEqualize(); } _escalation.pledgesAgainst += _pledgeAmount; - pledgesAgainstDispute[_disputeId][msg.sender] += _pledgeAmount; - emit PledgedAgainstDispute(msg.sender, _dispute.requestId, _disputeId, _pledgeAmount); + pledgesAgainstDispute[_disputeId][_pledger] += _pledgeAmount; + emit PledgedAgainstDispute(_pledger, _dispute.requestId, _disputeId, _pledgeAmount); } if (_escalation.pledgesFor + _escalation.pledgesAgainst >= _params.pledgeThreshold) { @@ -318,13 +380,14 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, uint256 _amountToRelease, + address _pledger, Resolution _resolution, RequestParameters memory _params ) internal { _params.accountingExtension.releasePledge({ _request: _request, _dispute: _dispute, - _pledger: msg.sender, + _pledger: _pledger, _token: _params.bondToken, _amount: _amountToRelease }); @@ -332,7 +395,7 @@ contract BondEscalationResolutionModule is Module, IBondEscalationResolutionModu emit PledgeClaimed({ _requestId: _getId(_request), _disputeId: _getId(_dispute), - _pledger: msg.sender, + _pledger: _pledger, _token: _params.bondToken, _pledgeReleased: _amountToRelease, _resolution: _resolution diff --git a/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol b/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol index b2bfad3f..9e187af0 100644 --- a/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol +++ b/solidity/contracts/modules/resolution/ERC20ResolutionModule.sol @@ -11,7 +11,10 @@ import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle import {IERC20ResolutionModule} from '../../../interfaces/modules/resolution/IERC20ResolutionModule.sol'; -contract ERC20ResolutionModule is Module, IERC20ResolutionModule { +import {ModuleTypehash} from '../../utils/ModuleTypehash.sol'; +import {ModuleAccessController} from '../access/ModuleAccessController.sol'; + +contract ERC20ResolutionModule is ModuleAccessController, IERC20ResolutionModule { using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.AddressSet; @@ -26,7 +29,7 @@ contract ERC20ResolutionModule is Module, IERC20ResolutionModule { */ mapping(bytes32 _disputeId => EnumerableSet.AddressSet _votersSet) internal _voters; - constructor(IOracle _oracle) Module(_oracle) {} + constructor(IOracle _oracle) ModuleAccessController(_oracle) {} /// @inheritdoc IModule function moduleName() external pure returns (string memory _moduleName) { @@ -53,8 +56,17 @@ contract ERC20ResolutionModule is Module, IERC20ResolutionModule { function castVote( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, - uint256 _numberOfVotes - ) public { + uint256 _numberOfVotes, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._CAST_VOTE_TYPEHASH, + abi.encode(_request, _dispute, _numberOfVotes, _numberOfVotes), + _accessControl + ) + { bytes32 _disputeId = _validateDispute(_request, _dispute); Escalation memory _escalation = escalations[_disputeId]; if (_escalation.startTime == 0) revert ERC20ResolutionModule_DisputeNotEscalated(); @@ -63,16 +75,19 @@ contract ERC20ResolutionModule is Module, IERC20ResolutionModule { } RequestParameters memory _params = decodeRequestData(_request.resolutionModuleData); - uint256 _deadline = _escalation.startTime + _params.timeUntilDeadline; - if (block.timestamp >= _deadline) revert ERC20ResolutionModule_VotingPhaseOver(); + if (block.timestamp >= _escalation.startTime + _params.timeUntilDeadline) { + revert ERC20ResolutionModule_VotingPhaseOver(); + } + + address _voter = _accessControl.user; - votes[_disputeId][msg.sender] += _numberOfVotes; + votes[_disputeId][_voter] += _numberOfVotes; - _voters[_disputeId].add(msg.sender); + _voters[_disputeId].add(_voter); escalations[_disputeId].totalVotes += _numberOfVotes; - _params.accountingExtension.bond(msg.sender, _dispute.requestId, _params.votingToken, _numberOfVotes); - emit VoteCast(msg.sender, _disputeId, _numberOfVotes); + _params.accountingExtension.bond(_voter, _dispute.requestId, _params.votingToken, _numberOfVotes); + emit VoteCast(_voter, _disputeId, _numberOfVotes); } /// @inheritdoc IERC20ResolutionModule @@ -100,16 +115,33 @@ contract ERC20ResolutionModule is Module, IERC20ResolutionModule { // Update status if (_quorumReached == 1) { - ORACLE.updateDisputeStatus(_request, _response, _dispute, IOracle.DisputeStatus.Won); + ORACLE.updateDisputeStatus({ + _request: _request, + _response: _response, + _dispute: _dispute, + _status: IOracle.DisputeStatus.Won + }); emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Won); } else { - ORACLE.updateDisputeStatus(_request, _response, _dispute, IOracle.DisputeStatus.Lost); + ORACLE.updateDisputeStatus({ + _request: _request, + _response: _response, + _dispute: _dispute, + _status: IOracle.DisputeStatus.Lost + }); emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Lost); } } /// @inheritdoc IERC20ResolutionModule - function claimVote(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external { + function claimVote( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + AccessControl calldata _accessControl + ) + external + hasAccess(_request.accessModule, ModuleTypehash._CLAIM_VOTE_TYPEHASH, abi.encode(_request, _dispute), _accessControl) + { bytes32 _disputeId = _validateDispute(_request, _dispute); Escalation memory _escalation = escalations[_disputeId]; @@ -117,12 +149,12 @@ contract ERC20ResolutionModule is Module, IERC20ResolutionModule { RequestParameters memory _params = decodeRequestData(_request.resolutionModuleData); uint256 _deadline = _escalation.startTime + _params.timeUntilDeadline; if (block.timestamp < _deadline) revert ERC20ResolutionModule_OnGoingVotingPhase(); - + address _voter = _accessControl.user; // Transfer the tokens back to the voter - uint256 _amount = votes[_disputeId][msg.sender]; - _params.accountingExtension.release(msg.sender, _dispute.requestId, _params.votingToken, _amount); + uint256 _amount = votes[_disputeId][_voter]; + _params.accountingExtension.release(_voter, _dispute.requestId, _params.votingToken, _amount); - emit VoteClaimed(msg.sender, _disputeId, _amount); + emit VoteClaimed(_voter, _disputeId, _amount); } /// @inheritdoc IERC20ResolutionModule diff --git a/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol b/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol index 40286566..172fb46c 100644 --- a/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol +++ b/solidity/contracts/modules/resolution/PrivateERC20ResolutionModule.sol @@ -6,12 +6,14 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import {ModuleTypehash} from '../../utils/ModuleTypehash.sol'; import {IModule, Module} from '@defi-wonderland/prophet-core/solidity/contracts/Module.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; import {IPrivateERC20ResolutionModule} from '../../../interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol'; +import {ModuleAccessController} from '../access/ModuleAccessController.sol'; -contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { +contract PrivateERC20ResolutionModule is ModuleAccessController, IPrivateERC20ResolutionModule { using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.AddressSet; @@ -26,7 +28,7 @@ contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { */ mapping(bytes32 _disputeId => EnumerableSet.AddressSet _votersSet) internal _voters; - constructor(IOracle _oracle) Module(_oracle) {} + constructor(IOracle _oracle) ModuleAccessController(_oracle) {} /// @inheritdoc IModule function moduleName() external pure returns (string memory _moduleName) { @@ -50,7 +52,20 @@ contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { } /// @inheritdoc IPrivateERC20ResolutionModule - function commitVote(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, bytes32 _commitment) public { + function commitVote( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + bytes32 _commitment, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._COMMIT_VOTE_TYPEHASH, + abi.encode(_request, _dispute, _commitment), + _accessControl + ) + { bytes32 _disputeId = _validateDispute(_request, _dispute); if (ORACLE.disputeStatus(_disputeId) != IOracle.DisputeStatus.Escalated) { revert PrivateERC20ResolutionModule_AlreadyResolved(); @@ -62,11 +77,11 @@ contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { RequestParameters memory _params = decodeRequestData(_request.resolutionModuleData); uint256 _committingDeadline = _startTime + _params.committingTimeWindow; if (block.timestamp >= _committingDeadline) revert PrivateERC20ResolutionModule_CommittingPhaseOver(); - + address _voter = _accessControl.user; if (_commitment == bytes32('')) revert PrivateERC20ResolutionModule_EmptyCommitment(); - _votersData[_disputeId][msg.sender] = VoterData({numOfVotes: 0, commitment: _commitment}); + _votersData[_disputeId][_voter] = VoterData({numOfVotes: 0, commitment: _commitment}); - emit VoteCommitted(msg.sender, _disputeId, _commitment); + emit VoteCommitted(_voter, _disputeId, _commitment); } /// @inheritdoc IPrivateERC20ResolutionModule @@ -74,34 +89,47 @@ contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, uint256 _numberOfVotes, - bytes32 _salt - ) public { + bytes32 _salt, + AccessControl calldata _accessControl + ) + external + hasAccess( + _request.accessModule, + ModuleTypehash._REVEAL_VOTE_TYPEHASH, + abi.encode(_request, _dispute, _numberOfVotes, _salt), + _accessControl + ) + { bytes32 _disputeId = _validateDispute(_request, _dispute); Escalation memory _escalation = escalations[_disputeId]; if (_escalation.startTime == 0) revert PrivateERC20ResolutionModule_DisputeNotEscalated(); RequestParameters memory _params = decodeRequestData(_request.resolutionModuleData); - (uint256 _revealStartTime, uint256 _revealEndTime) = ( - _escalation.startTime + _params.committingTimeWindow, - _escalation.startTime + _params.committingTimeWindow + _params.revealingTimeWindow - ); - if (block.timestamp < _revealStartTime) revert PrivateERC20ResolutionModule_OnGoingCommittingPhase(); - if (block.timestamp >= _revealEndTime) revert PrivateERC20ResolutionModule_RevealingPhaseOver(); - VoterData storage _voterData = _votersData[_disputeId][msg.sender]; + { + (uint256 _revealStartTime, uint256 _revealEndTime) = ( + _escalation.startTime + _params.committingTimeWindow, + _escalation.startTime + _params.committingTimeWindow + _params.revealingTimeWindow + ); + if (block.timestamp < _revealStartTime) revert PrivateERC20ResolutionModule_OnGoingCommittingPhase(); + if (block.timestamp >= _revealEndTime) revert PrivateERC20ResolutionModule_RevealingPhaseOver(); + } + + address _voter = _accessControl.user; + VoterData storage _voterData = _votersData[_disputeId][_voter]; - if (_voterData.commitment != keccak256(abi.encode(msg.sender, _disputeId, _numberOfVotes, _salt))) { + if (_voterData.commitment != keccak256(abi.encode(_voter, _disputeId, _numberOfVotes, _salt))) { revert PrivateERC20ResolutionModule_WrongRevealData(); } _voterData.numOfVotes = _numberOfVotes; _voterData.commitment = bytes32(''); - _voters[_disputeId].add(msg.sender); + _voters[_disputeId].add(_voter); escalations[_disputeId].totalVotes += _numberOfVotes; - _params.votingToken.safeTransferFrom(msg.sender, address(this), _numberOfVotes); + _params.votingToken.safeTransferFrom(_voter, address(this), _numberOfVotes); - emit VoteRevealed(msg.sender, _disputeId, _numberOfVotes); + emit VoteRevealed(_voter, _disputeId, _numberOfVotes); } /// @inheritdoc IPrivateERC20ResolutionModule @@ -130,10 +158,20 @@ contract PrivateERC20ResolutionModule is Module, IPrivateERC20ResolutionModule { uint256 _quorumReached = _escalation.totalVotes >= _params.minVotesForQuorum ? 1 : 0; if (_quorumReached == 1) { - ORACLE.updateDisputeStatus(_request, _response, _dispute, IOracle.DisputeStatus.Won); + ORACLE.updateDisputeStatus({ + _request: _request, + _response: _response, + _dispute: _dispute, + _status: IOracle.DisputeStatus.Won + }); emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Won); } else { - ORACLE.updateDisputeStatus(_request, _response, _dispute, IOracle.DisputeStatus.Lost); + ORACLE.updateDisputeStatus({ + _request: _request, + _response: _response, + _dispute: _dispute, + _status: IOracle.DisputeStatus.Lost + }); emit DisputeResolved(_dispute.requestId, _disputeId, IOracle.DisputeStatus.Lost); } diff --git a/solidity/contracts/modules/response/BondedResponseModule.sol b/solidity/contracts/modules/response/BondedResponseModule.sol index 13d85978..cb52b7cb 100644 --- a/solidity/contracts/modules/response/BondedResponseModule.sol +++ b/solidity/contracts/modules/response/BondedResponseModule.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IBondedResponseModule} from '../../../interfaces/modules/response/IBondedResponseModule.sol'; - import {IModule, Module} from '@defi-wonderland/prophet-core/solidity/contracts/Module.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; +import {IBondedResponseModule} from '../../../interfaces/modules/response/IBondedResponseModule.sol'; + contract BondedResponseModule is Module, IBondedResponseModule { constructor(IOracle _oracle) Module(_oracle) {} @@ -74,8 +74,8 @@ contract BondedResponseModule is Module, IBondedResponseModule { ) external override(IBondedResponseModule, Module) onlyOracle { RequestParameters memory _params = decodeRequestData(_request.responseModuleData); + // review: _finalizer is Oracle:finalize's accessControl.user bytes32 _requestId = _getId(_request); - bool _isModule = ORACLE.allowedModule(_requestId, _finalizer); if (!_isModule && block.timestamp < ORACLE.requestCreatedAt(_requestId) + _params.deadline) { diff --git a/solidity/contracts/utils/ModuleTypehash.sol b/solidity/contracts/utils/ModuleTypehash.sol new file mode 100644 index 00000000..b70bbb5a --- /dev/null +++ b/solidity/contracts/utils/ModuleTypehash.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +library ModuleTypehash { + bytes32 internal constant _PLEDGE_FOR_DISPUTE_TYPEHASH = + keccak256('pledgeForDispute(Request _request,Dispute _dispute,IAccessController.AccessControl _accessControl)'); + + bytes32 internal constant _PLEDGE_AGAINST_DISPUTE_TYPEHASH = + keccak256('pledgeAgainstDispute(Request _request,Dispute _dispute,IAccessController.AccessControl _accessControl)'); + + bytes32 internal constant _CLAIM_PLEDGE_TYPEHASH = + keccak256('claimPledge(Request _request,Dispute _dispute,AccessControl _accessControl)'); + + bytes32 internal constant _CLAIM_VOTE_TYPEHASH = + keccak256('claimVote(Request _request,Dispute _dispute,AccessControl _accessControl)'); + + bytes32 internal constant _CAST_VOTE_TYPEHASH = + keccak256('castVote(Request _request,Dispute _dispute,uint256 _numberOfVotes,AccessControl _accessControl)'); + + bytes32 internal constant _COMMIT_VOTE_TYPEHASH = + keccak256('commitVote(Request _request,Dispute _dispute,bytes32 _commitment,AccessControl _accessControl)'); + + bytes32 internal constant _REVEAL_VOTE_TYPEHASH = keccak256( + 'revealVote(Request _request,Dispute _dispute,uint256 _numberOfVotes,bytes32 _salt,AccessControl _accessControl)' + ); +} diff --git a/solidity/interfaces/IArbitrator.sol b/solidity/interfaces/IArbitrator.sol index c5fdc6cd..f323ddc8 100644 --- a/solidity/interfaces/IArbitrator.sol +++ b/solidity/interfaces/IArbitrator.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; interface IArbitrator { diff --git a/solidity/interfaces/modules/access/IModuleAccessController.sol b/solidity/interfaces/modules/access/IModuleAccessController.sol new file mode 100644 index 00000000..1713b7de --- /dev/null +++ b/solidity/interfaces/modules/access/IModuleAccessController.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; + +/** + * @title Module Access Controller Interface + * @notice Interface for the module access controller + */ +interface IModuleAccessController is IAccessController { + /*/////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////*/ + + /*/////////////////////////////////////////////////////////////// + STRUCTS + //////////////////////////////////////////////////////////////*/ + + /*/////////////////////////////////////////////////////////////// + ERRORS + //////////////////////////////////////////////////////////////*/ + + /** + * @notice Thrown when user has not approved the access module + */ + error ModuleAccessController_AccessModuleNotApproved(); + + /*/////////////////////////////////////////////////////////////// + VARIABLES + //////////////////////////////////////////////////////////////*/ + + /*/////////////////////////////////////////////////////////////// + LOGIC + //////////////////////////////////////////////////////////////*/ +} diff --git a/solidity/interfaces/modules/dispute/IBondEscalationModule.sol b/solidity/interfaces/modules/dispute/IBondEscalationModule.sol index 4ee78546..dcc41d5d 100644 --- a/solidity/interfaces/modules/dispute/IBondEscalationModule.sol +++ b/solidity/interfaces/modules/dispute/IBondEscalationModule.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; import {IDisputeModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/dispute/IDisputeModule.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; @@ -240,19 +241,25 @@ interface IBondEscalationModule is IDisputeModule { * * @param _request The request data. * @param _dispute The dispute data. + * @param _accessControl The access control data * * @dev If the bond escalation is not tied at the end of its deadline, a tying buffer is added * to avoid scenarios where one of the parties breaks the tie very last second. * During the tying buffer, the losing party can only tie, and once the escalation is tied * no further funds can be pledged. */ - function pledgeForDispute(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external; + function pledgeForDispute( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + IAccessController.AccessControl calldata _accessControl + ) external; /** * @notice Pledges funds against a given disputeId during its bond escalation process. * * @param _request The request data. * @param _dispute The dispute data. + * @param _accessControl The access control data * * @dev Will revert if the disputeId is not going through the bond escalation process. * @dev If the bond escalation is not tied at the end of its deadline, a tying buffer is added @@ -260,7 +267,11 @@ interface IBondEscalationModule is IDisputeModule { * During the tying buffer, the losing party can only tie, and once the escalation is tied * no further funds can be pledged. */ - function pledgeAgainstDispute(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external; + function pledgeAgainstDispute( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + IAccessController.AccessControl calldata _accessControl + ) external; /** * @notice Settles the bond escalation process of a given requestId. diff --git a/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol b/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol index ea32729b..b976c8af 100644 --- a/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/IBondEscalationResolutionModule.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; import {IResolutionModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/resolution/IResolutionModule.sol'; @@ -276,11 +277,13 @@ interface IBondEscalationResolutionModule is IResolutionModule { * @param _request The request data * @param _dispute The dispute data * @param _pledgeAmount The amount of pledges to pledge. + * @param _accessControl The access control data */ function pledgeForDispute( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, - uint256 _pledgeAmount + uint256 _pledgeAmount, + IAccessController.AccessControl calldata _accessControl ) external; /** @@ -289,12 +292,14 @@ interface IBondEscalationResolutionModule is IResolutionModule { * * @param _request The request data * @param _dispute The dispute data - * @param _pledgeAmount The amount of pledges to pledge. + * @param _pledgeAmount The amount of pledges to pledge + * @param _accessControl The access control data */ function pledgeAgainstDispute( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, - uint256 _pledgeAmount + uint256 _pledgeAmount, + IAccessController.AccessControl calldata _accessControl ) external; /** @@ -302,9 +307,14 @@ interface IBondEscalationResolutionModule is IResolutionModule { * * @param _request The request data * @param _dispute The dispute data + * @param _accessControl The access control data * * @dev Winning pledgers will claim their pledges along with their reward. In case of no resolution, users can * claim their pledges back. Losing pledgers will go to the rewards of the winning pledgers. */ - function claimPledge(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external; + function claimPledge( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + IAccessController.AccessControl calldata _accessControl + ) external; } diff --git a/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol b/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol index f4fe7bbe..365b7e01 100644 --- a/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/IERC20ResolutionModule.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; import {IResolutionModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/resolution/IResolutionModule.sol'; @@ -152,11 +153,13 @@ interface IERC20ResolutionModule is IResolutionModule { * @param _request The request for which the dispute was created * @param _dispute The dispute for which the vote is being cast * @param _numberOfVotes The number of votes to cast + * @param _accessControl The access control data */ function castVote( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, - uint256 _numberOfVotes + uint256 _numberOfVotes, + IAccessController.AccessControl calldata _accessControl ) external; /** @@ -179,8 +182,13 @@ interface IERC20ResolutionModule is IResolutionModule { * * @param _request The request for which the dispute was created * @param _dispute The resolved dispute + * @param _accessControl The access control data */ - function claimVote(IOracle.Request calldata _request, IOracle.Dispute calldata _dispute) external; + function claimVote( + IOracle.Request calldata _request, + IOracle.Dispute calldata _dispute, + IAccessController.AccessControl calldata _accessControl + ) external; /** * @notice Gets the voters of a dispute diff --git a/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol b/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol index 51ae24e6..692b7877 100644 --- a/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol +++ b/solidity/interfaces/modules/resolution/IPrivateERC20ResolutionModule.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.19; import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; + +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; import {IResolutionModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/resolution/IResolutionModule.sol'; @@ -162,11 +164,13 @@ interface IPrivateERC20ResolutionModule is IResolutionModule { * @param _request The request data * @param _dispute The dispute being voted on * @param _commitment The commitment computed from the provided data and the user's address + * @param _accessControl The access control data */ function commitVote( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, - bytes32 _commitment + bytes32 _commitment, + IAccessController.AccessControl calldata _accessControl ) external; /** @@ -176,12 +180,14 @@ interface IPrivateERC20ResolutionModule is IResolutionModule { * @param _dispute The dispute being voted on * @param _numberOfVotes The amount of votes being revealed * @param _salt The salt used to compute the commitment + * @param _accessControl The access control data */ function revealVote( IOracle.Request calldata _request, IOracle.Dispute calldata _dispute, uint256 _numberOfVotes, - bytes32 _salt + bytes32 _salt, + IAccessController.AccessControl calldata _accessControl ) external; /** diff --git a/solidity/test/integration/AccountingExtension.t.sol b/solidity/test/integration/AccountingExtension.t.sol index 3ea7348c..7e63988e 100644 --- a/solidity/test/integration/AccountingExtension.t.sol +++ b/solidity/test/integration/AccountingExtension.t.sol @@ -121,7 +121,7 @@ contract Integration_AccountingExtension is IntegrationBase { vm.startPrank(user); _accountingExtension.approveModule(address(_requestModule)); - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); // Check: does it revert if trying to withdraw an amount that is bonded to a request? vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); diff --git a/solidity/test/integration/Arbitration.t.sol b/solidity/test/integration/Arbitration.t.sol index d0732b69..fc48ba9e 100644 --- a/solidity/test/integration/Arbitration.t.sol +++ b/solidity/test/integration/Arbitration.t.sol @@ -25,14 +25,14 @@ contract Integration_Arbitration is IntegrationBase { // First step: escalating the dispute vm.prank(disputer); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); // Check: is the dispute status active after starting the resolution? assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); // Second step: resolving the dispute vm.prank(disputer); - oracle.resolveDispute(mockRequest, mockResponse, mockDispute); + oracle.resolveDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // Check: is the dispute status resolved after calling resolve? assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); @@ -58,7 +58,7 @@ contract Integration_Arbitration is IntegrationBase { // First step: escalating the dispute vm.prank(disputer); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); // Check: is the dispute status resolved after calling resolve? assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); @@ -83,7 +83,7 @@ contract Integration_Arbitration is IntegrationBase { // First step: escalating the dispute vm.prank(disputer); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); // Check: is the dispute status active after starting the resolution? assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Active)); @@ -97,7 +97,7 @@ contract Integration_Arbitration is IntegrationBase { // Second step: resolving the dispute vm.prank(disputer); - oracle.resolveDispute(mockRequest, mockResponse, mockDispute); + oracle.resolveDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // Check: is the dispute status resolved after calling resolve? assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); @@ -130,7 +130,7 @@ contract Integration_Arbitration is IntegrationBase { // First step: escalating and resolving the dispute vm.prank(disputer); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); // Check: is the dispute status resolved after calling escalate? assertEq(uint256(_arbitratorModule.getStatus(_disputeId)), uint256(IArbitratorModule.ArbitrationStatus.Resolved)); diff --git a/solidity/test/integration/BondEscalation.t.sol b/solidity/test/integration/BondEscalation.t.sol index f68c5d55..7a2360db 100644 --- a/solidity/test/integration/BondEscalation.t.sol +++ b/solidity/test/integration/BondEscalation.t.sol @@ -96,34 +96,34 @@ contract Integration_BondEscalation is IntegrationBase { // Requester creates a request _deposit(_bondEscalationAccounting, requester, usdc, _expectedReward); vm.prank(requester); - _requestId = oracle.createRequest(mockRequest, _ipfsHash); + _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); // Proposer proposes a response _deposit(_bondEscalationAccounting, proposer, usdc, _expectedBondSize); vm.prank(proposer); - _responseId = oracle.proposeResponse(mockRequest, mockResponse); + _responseId = oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl(proposer)); // Disputer disputes the response _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); } function test_proposerWins() public { // Step 1: Proposer pledges against the dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 2: Disputer doubles down _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(disputer)); // Step 3: Proposer doubles down _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 4: Disputer runs out of capital // Step 5: External parties see that Disputer's dispute was wrong so they don't join to escalate @@ -153,7 +153,7 @@ contract Integration_BondEscalation is IntegrationBase { // Step 8: Finalize request and check balances again vm.warp(block.timestamp + _expectedDeadline + 1 days); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); // Test: The requester has no balance because he has paid the proposer assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); @@ -173,17 +173,17 @@ contract Integration_BondEscalation is IntegrationBase { // Step 1: Proposer pledges against the dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl()); // Step 2: Disputer doubles down _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Step 3: Another party joins the dispute _deposit(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize); vm.prank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Step 4: Proposer runs out of capital and doesn't pledge anymore // External parties see that Proposer's proposal was wrong so they don't join to escalate @@ -225,31 +225,31 @@ contract Integration_BondEscalation is IntegrationBase { IOracle.Response({proposer: _secondProposer, requestId: _requestId, response: abi.encode('second response')}); _deposit(_bondEscalationAccounting, _secondProposer, usdc, _pledgeSize); vm.prank(_secondProposer); - _responseId = oracle.proposeResponse(mockRequest, _secondResponse); + _responseId = oracle.proposeResponse(mockRequest, _secondResponse, _createAccessControl(_secondProposer)); // Step 8: Disputer disputes Another proposer's answer // _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); IOracle.Dispute memory _secondDispute = IOracle.Dispute({disputer: disputer, responseId: _responseId, requestId: _requestId, proposer: _secondProposer}); vm.prank(disputer); - _disputeId = oracle.disputeResponse(mockRequest, _secondResponse, _secondDispute); + _disputeId = oracle.disputeResponse(mockRequest, _secondResponse, _secondDispute, _createAccessControl()); // Step 9: Shouldn't be able to pledge for or against the dispute due to the bond escalation deadline being over _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, _secondDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, _secondDispute, _createAccessControl()); // Step 10: Because Another proposer's answer is disputed, a third party can propose a new answer IOracle.Response memory _thirdResponse = IOracle.Response({proposer: _thirdProposer, requestId: _requestId, response: abi.encode('third response')}); _deposit(_bondEscalationAccounting, _thirdProposer, usdc, _expectedBondSize); vm.prank(_thirdProposer); - _responseId = oracle.proposeResponse(mockRequest, _thirdResponse); + _responseId = oracle.proposeResponse(mockRequest, _thirdResponse, _createAccessControl()); // Step 11: It goes undisputed for three days, therefore it's deemed correct and final vm.warp(block.timestamp + _expectedDeadline + 1); - oracle.finalize(mockRequest, _thirdResponse); + oracle.finalize(mockRequest, _thirdResponse, _createAccessControl(address(this))); // Test: The requester has paid out the reward assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); @@ -285,7 +285,7 @@ contract Integration_BondEscalation is IntegrationBase { // So Another proposer gets paid Disputer's bond vm.warp(block.timestamp + _expectedDeadline + 2 days); _mockArbitrator.setAnswer(IOracle.DisputeStatus.Lost); - oracle.resolveDispute(mockRequest, _secondResponse, _secondDispute); + oracle.resolveDispute(mockRequest, _secondResponse, _secondDispute, _createAccessControl(address(this))); // Test: The requester still has nothing assertEq(_bondEscalationAccounting.balanceOf(requester, usdc), 0, 'Mismatch: Requester balance'); @@ -326,17 +326,17 @@ contract Integration_BondEscalation is IntegrationBase { // Step 1: Proposer pledges against the dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 2: Disputer doubles down _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(disputer)); // Step 3: Proposer doubles down _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 4: Disputer runs out of capital // Step 5: The tying buffer kicks in @@ -345,21 +345,23 @@ contract Integration_BondEscalation is IntegrationBase { // Step 6: An external party sees that Proposer's response is incorrect, so they bond the required WETH _deposit(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize); vm.prank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(_secondDisputer)); // Step 7: They go into the dispute resolution module - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + address _escalator = makeAddr('escalator'); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl(_escalator)); // Step 8: At this point, new answers can be proposed IOracle.Response memory _secondResponse = IOracle.Response({proposer: _secondProposer, requestId: _requestId, response: abi.encode('second response')}); _deposit(_bondEscalationAccounting, _secondProposer, usdc, _expectedBondSize); vm.prank(_secondProposer); - _responseId = oracle.proposeResponse(mockRequest, _secondResponse); + _responseId = oracle.proposeResponse(mockRequest, _secondResponse, _createAccessControl(_secondProposer)); // Step 9: After some time, the resolution module deems Disputer's dispute as correct _mineBlocks(100); - oracle.resolveDispute(mockRequest, mockResponse, mockDispute); + oracle.resolveDispute(mockRequest, mockResponse, mockDispute, _createAccessControl(address(this))); IOracle.DisputeStatus _disputeStatus = oracle.disputeStatus(_disputeId); assertEq(uint256(_disputeStatus), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); @@ -400,29 +402,35 @@ contract Integration_BondEscalation is IntegrationBase { // Step 1: Proposer pledges against the dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 2: Disputer doesn't have money // Step 3: External actor sees that Proposer's answer was incorrect so they pledge in favor of the dispute _deposit(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize); vm.prank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(_secondDisputer)); // Step 4: Proposer doubles down _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 5: External actor sees that Proposer's answer was incorrect so they pledge in favor of the dispute, tying the bond escalation address _thirdDisputer = makeAddr('thirdDisputer'); _deposit(_bondEscalationAccounting, _thirdDisputer, usdc, _pledgeSize); vm.prank(_thirdDisputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(_thirdDisputer)); // Step 6: Proposer loses in resolution + address _escalator = makeAddr('escalator'); + address _resolver = makeAddr('resolver'); + vm.warp(block.timestamp + _bondEscalationDeadline + 1); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); - oracle.resolveDispute(mockRequest, mockResponse, mockDispute); + + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl(_escalator)); + vm.prank(_resolver); + oracle.resolveDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); IOracle.DisputeStatus _disputeStatus = oracle.disputeStatus(_disputeId); assertEq(uint256(_disputeStatus), uint256(IOracle.DisputeStatus.Won), 'Mismatch: Dispute status'); @@ -456,17 +464,17 @@ contract Integration_BondEscalation is IntegrationBase { // Step 1: Proposer pledges against the dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 2: Disputer doubles down _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(disputer)); // Step 3: Proposer doubles down _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 4: Disputer runs out of capital // Step 5: The tying buffer kicks in @@ -475,7 +483,7 @@ contract Integration_BondEscalation is IntegrationBase { // Step 6: An external party sees that Proposer's response is incorrect, so they bond the required WETH _deposit(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize); vm.prank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(_secondDisputer)); ////////////////// NEW MALICIOUS REQUEST //////////////////////// @@ -517,17 +525,17 @@ contract Integration_BondEscalation is IntegrationBase { // Step 1: Proposer pledges against the dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 2: Disputer doubles down _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(disputer)); // Step 3: Proposer doubles down _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(proposer)); // Step 4: Disputer runs out of capital // Step 5: The tying buffer kicks in @@ -536,7 +544,7 @@ contract Integration_BondEscalation is IntegrationBase { // Step 6: An external party sees that Proposer's response is incorrect, so they bond the required WETH _deposit(_bondEscalationAccounting, _secondDisputer, usdc, _pledgeSize); vm.prank(_secondDisputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(_secondDisputer)); ////////////////// NEW MALICIOUS REQUEST //////////////////////// diff --git a/solidity/test/integration/CallbackModule.t.sol b/solidity/test/integration/CallbackModule.t.sol index b285db6d..60422525 100644 --- a/solidity/test/integration/CallbackModule.t.sol +++ b/solidity/test/integration/CallbackModule.t.sol @@ -25,7 +25,7 @@ contract Integration_CallbackModule is IntegrationBase { // advance time past deadline vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); } function test_callbacksNeverRevert() public { @@ -38,7 +38,7 @@ contract Integration_CallbackModule is IntegrationBase { vm.expectCall(address(_target), abi.encodeCall(IProphetCallback.prophetCallback, (_expectedData))); vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); } function _setupRequest() internal { @@ -47,14 +47,14 @@ contract Integration_CallbackModule is IntegrationBase { _deposit(_accountingExtension, requester, usdc, _expectedReward); vm.startPrank(requester); _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(mockRequest, _ipfsHash); + _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); _deposit(_accountingExtension, proposer, usdc, _expectedBondSize); vm.startPrank(proposer); _accountingExtension.approveModule(address(_responseModule)); mockResponse.response = abi.encode(proposer, _requestId, bytes('')); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); vm.stopPrank(); } } diff --git a/solidity/test/integration/ContractCallRequest.t.sol b/solidity/test/integration/ContractCallRequest.t.sol index 598ff0dc..8c917c04 100644 --- a/solidity/test/integration/ContractCallRequest.t.sol +++ b/solidity/test/integration/ContractCallRequest.t.sol @@ -46,7 +46,7 @@ contract Integration_ContractCallRequest is IntegrationBase { function test_createRequest_finalizeEmptyResponse() public { vm.prank(requester); - bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); uint256 _requestCreatedAt = oracle.requestCreatedAt(_requestId); // mock an empty response @@ -60,20 +60,23 @@ contract Integration_ContractCallRequest is IntegrationBase { abi.encodeCall(IAccountingExtension.release, (mockRequest.requester, _requestId, usdc, _expectedReward)) ); + // assert the empty response does not exist + assertEq(oracle.responseCreatedAt(_getId(mockResponse)), 0); + vm.warp(_requestCreatedAt + _expectedDeadline); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); } function test_createRequest_finalizeValidResponse() public { vm.prank(requester); - bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); mockResponse = IOracle.Response({proposer: proposer, requestId: _requestId, response: bytes('good-answer')}); vm.startPrank(proposer); _accountingExtension.approveModule(address(_responseModule)); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); vm.stopPrank(); // expect call to accounting to pay the proposer @@ -87,6 +90,6 @@ contract Integration_ContractCallRequest is IntegrationBase { vm.warp(block.timestamp + _expectedDeadline); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); } } diff --git a/solidity/test/integration/EscalateDispute.t.sol b/solidity/test/integration/EscalateDispute.t.sol index 552bc00c..d707a776 100644 --- a/solidity/test/integration/EscalateDispute.t.sol +++ b/solidity/test/integration/EscalateDispute.t.sol @@ -11,6 +11,9 @@ contract Integration_EscalateDispute is IntegrationBase { uint256 internal _expectedResponseDeadline = _expectedDeadline * 2; uint256 internal _disputeCreatedAt; + address internal _escalator = makeAddr('escalator'); + address internal _resolver = makeAddr('resolver'); + function setUp() public override { super.setUp(); @@ -56,20 +59,20 @@ contract Integration_EscalateDispute is IntegrationBase { vm.startPrank(requester); _bondEscalationAccounting.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(mockRequest, _ipfsHash); + _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); // Propose a response and dispute it _deposit(_bondEscalationAccounting, proposer, usdc, _expectedBondSize); vm.startPrank(proposer); _bondEscalationAccounting.approveModule(address(_responseModule)); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl(proposer)); vm.stopPrank(); _deposit(_bondEscalationAccounting, disputer, usdc, _expectedBondSize); vm.startPrank(disputer); _bondEscalationAccounting.approveModule(address(_bondEscalationModule)); - _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); vm.stopPrank(); _disputeCreatedAt = oracle.disputeCreatedAt(_disputeId); @@ -87,11 +90,11 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge for dispute _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize * 3); vm.startPrank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Pledge revert if can be only surpassed by 1 vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); vm.stopPrank(); // Bond escalation should call pledge @@ -103,7 +106,7 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge for dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl()); // Get the bond escalation IBondEscalationModule.BondEscalation memory _bondEscalation = _bondEscalationModule.getEscalation(_requestId); @@ -117,22 +120,22 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge revert if break tie during tying buffer vm.warp(_disputeCreatedAt + _expectedDeadline + 1); vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Pledge revert if bond escalation is over vm.warp(_disputeCreatedAt + _expectedDeadline + _tyingBuffer + 1); vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Roll back the timestamp because we need to simulate the custom error "break tie during tying buffer" and "bond escalation over" vm.warp(_disputeCreatedAt); // Pledge second time for dispute - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Pledge revert if the maximum number of escalations is reached vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Get the bond escalation _bondEscalation = _bondEscalationModule.getEscalation(_requestId); @@ -196,11 +199,11 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge for dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize * 3); vm.startPrank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl()); // Pledge revert if can be only surpassed by 1 vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl()); vm.stopPrank(); // Bond escalation should call pledge @@ -212,7 +215,7 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge for dispute _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Get the bond escalation IBondEscalationModule.BondEscalation memory _bondEscalation = _bondEscalationModule.getEscalation(_requestId); @@ -223,9 +226,9 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge revert if the maximum number of escalations is reached vm.startPrank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl()); vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl()); // Get the bond escalation _bondEscalation = _bondEscalationModule.getEscalation(_requestId); @@ -282,13 +285,15 @@ contract Integration_EscalateDispute is IntegrationBase { // Escalate dispute reverts if dispute does not exist mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); mockDispute.requestId = _requestId; // Escalate dispute reverts if escalation is not over vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationNotOver.selector); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // Check that the dispute is active assertTrue( @@ -298,14 +303,15 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge for dispute _deposit(_bondEscalationAccounting, disputer, usdc, _pledgeSize); vm.prank(disputer); - _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl()); // Warp blocks to pass the escalation deadline vm.warp(_disputeCreatedAt + _expectedResponseDeadline + 1); // Escalate dispute reverts if dispute is not escalatable vm.expectRevert(IBondEscalationModule.BondEscalationModule_NotEscalatable.selector); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // Roll back the timestamp because we need to simulate the custom error "not escalatable" vm.warp(_disputeCreatedAt); @@ -313,7 +319,7 @@ contract Integration_EscalateDispute is IntegrationBase { // Pledge against dispute _deposit(_bondEscalationAccounting, proposer, usdc, _pledgeSize); vm.prank(proposer); - _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + _bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl()); // Warp blocks to pass the escalation deadline vm.warp(_disputeCreatedAt + _expectedDeadline + _tyingBuffer + 1); @@ -343,7 +349,8 @@ contract Integration_EscalateDispute is IntegrationBase { ); // We escalate the dispute - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // We check that the dispute was escalated IOracle.DisputeStatus _disputeStatus = oracle.disputeStatus(_disputeId); @@ -358,7 +365,8 @@ contract Integration_EscalateDispute is IntegrationBase { // Escalate dispute reverts if dispute is not active vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_CannotEscalate.selector, _disputeId)); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // Revert if bond escalation cant be settled vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationCantBeSettled.selector); @@ -374,7 +382,8 @@ contract Integration_EscalateDispute is IntegrationBase { // Resolve the dispute escalated with no resolution _mockArbitrator.setAnswer(IOracle.DisputeStatus.NoResolution); - oracle.resolveDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_resolver); + oracle.resolveDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // The arbitrator module should have updated the status of the dispute assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Resolved); @@ -391,7 +400,7 @@ contract Integration_EscalateDispute is IntegrationBase { _deposit(_bondEscalationAccounting, proposer, usdc, _expectedBondSize); mockResponse.response = bytes('new response'); vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); // Get the new response id mockDispute.responseId = _getId(mockResponse); @@ -400,7 +409,13 @@ contract Integration_EscalateDispute is IntegrationBase { bytes32 _newDisputeId = _getId(mockDispute); // The oracle should call the dispute module - vm.expectCall(address(oracle), abi.encodeCall(IOracle.escalateDispute, (mockRequest, mockResponse, mockDispute))); + vm.expectCall( + address(oracle), + abi.encodeCall( + IOracle.escalateDispute, + (mockRequest, mockResponse, mockDispute, _createAccessControl(address(_bondEscalationModule))) + ) + ); vm.expectCall( address(_bondEscalationModule), @@ -409,7 +424,7 @@ contract Integration_EscalateDispute is IntegrationBase { _deposit(_bondEscalationAccounting, disputer, usdc, _expectedBondSize); vm.prank(disputer); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl()); // We check that the dispute was escalated _disputeStatus = oracle.disputeStatus(_newDisputeId); @@ -442,7 +457,8 @@ contract Integration_EscalateDispute is IntegrationBase { // We escalate the dispute vm.warp(_disputeCreatedAt + _expectedDeadline + 1); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // We check that the dispute was escalated IOracle.DisputeStatus _disputeStatus = oracle.disputeStatus(_disputeId); @@ -465,7 +481,8 @@ contract Integration_EscalateDispute is IntegrationBase { // Resolve the dispute escalated with no resolution _mockArbitrator.setAnswer(IOracle.DisputeStatus.Lost); - oracle.resolveDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_resolver); + oracle.resolveDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // The arbitrator module should have updated the status of the dispute assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Resolved); @@ -501,7 +518,8 @@ contract Integration_EscalateDispute is IntegrationBase { // We escalate the dispute vm.warp(_disputeCreatedAt + _expectedDeadline + 1); - oracle.escalateDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_escalator); + oracle.escalateDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // We check that the dispute was escalated IOracle.DisputeStatus _disputeStatus = oracle.disputeStatus(_disputeId); @@ -532,7 +550,8 @@ contract Integration_EscalateDispute is IntegrationBase { // Resolve the dispute escalated with no resolution _mockArbitrator.setAnswer(IOracle.DisputeStatus.Won); - oracle.resolveDispute(mockRequest, mockResponse, mockDispute); + vm.prank(_resolver); + oracle.resolveDispute(mockRequest, mockResponse, mockDispute, _createAccessControl()); // The arbitrator module should have updated the status of the dispute assertTrue(_arbitratorModule.getStatus(_disputeId) == IArbitratorModule.ArbitrationStatus.Resolved); diff --git a/solidity/test/integration/Finalization.t.sol b/solidity/test/integration/Finalization.t.sol index be4c2d0a..d4a70557 100644 --- a/solidity/test/integration/Finalization.t.sol +++ b/solidity/test/integration/Finalization.t.sol @@ -33,7 +33,7 @@ contract Integration_Finalization is IntegrationBase { vm.expectCall(address(_mockCallback), abi.encodeWithSelector(IProphetCallback.prophetCallback.selector, _calldata)); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); // Check: is response finalized? bytes32 _finalizedResponseId = oracle.finalizedResponseId(_getId(mockRequest)); @@ -50,7 +50,7 @@ contract Integration_Finalization is IntegrationBase { vm.expectRevert(IOracle.Oracle_InvalidResponse.selector); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); } /** @@ -61,9 +61,9 @@ contract Integration_Finalization is IntegrationBase { _proposeResponse(); _disputeResponse(); - vm.prank(_finalizer); vm.expectRevert(IOracle.Oracle_InvalidFinalizedResponse.selector); - oracle.finalize(mockRequest, mockResponse); + vm.prank(_finalizer); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); } /** @@ -80,7 +80,7 @@ contract Integration_Finalization is IntegrationBase { // Check: reverts if called during the dispute window? vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); } /** @@ -100,7 +100,7 @@ contract Integration_Finalization is IntegrationBase { vm.expectCall(address(_mockCallback), abi.encodeWithSelector(IProphetCallback.prophetCallback.selector, _calldata)); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); // Check: is response finalized? bytes32 _finalizedResponseId = oracle.finalizedResponseId(_getId(mockRequest)); @@ -123,7 +123,7 @@ contract Integration_Finalization is IntegrationBase { vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooEarlyToFinalize.selector); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); } /** diff --git a/solidity/test/integration/HttpRequest.t.sol b/solidity/test/integration/HttpRequest.t.sol index 894d3097..331b0ca9 100644 --- a/solidity/test/integration/HttpRequest.t.sol +++ b/solidity/test/integration/HttpRequest.t.sol @@ -33,7 +33,7 @@ contract Integration_HttpRequest is IntegrationBase { function test_createRequest_finalizeEmptyResponse() public { vm.prank(requester); - bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); // mock an empty response mockResponse = @@ -48,18 +48,18 @@ contract Integration_HttpRequest is IntegrationBase { vm.warp(block.timestamp + _expectedDeadline); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl()); } function test_createRequest_finalizeValidResponse() public { vm.prank(requester); - bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); mockResponse = IOracle.Response({proposer: proposer, requestId: _requestId, response: bytes('good-answer')}); vm.startPrank(proposer); _accountingExtension.approveModule(address(_responseModule)); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); vm.stopPrank(); // expect call to accounting to pay the proposer @@ -74,6 +74,6 @@ contract Integration_HttpRequest is IntegrationBase { vm.warp(block.timestamp + _expectedDeadline); vm.prank(_finalizer); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(_finalizer)); } } diff --git a/solidity/test/integration/IntegrationBase.sol b/solidity/test/integration/IntegrationBase.sol index 4eb7f84c..21e0edbc 100644 --- a/solidity/test/integration/IntegrationBase.sol +++ b/solidity/test/integration/IntegrationBase.sol @@ -5,6 +5,10 @@ pragma solidity ^0.8.19; // solhint-disable-next-line no-console import {console} from 'forge-std/console.sol'; +import { + CommonAccessController, + IAccessController +} from '@defi-wonderland/prophet-core/solidity/contracts/CommonAccessController.sol'; import {IOracle, Oracle} from '@defi-wonderland/prophet-core/solidity/contracts/Oracle.sol'; import {IDisputeModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/dispute/IDisputeModule.sol'; import {IFinalityModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/finality/IFinalityModule.sol'; @@ -221,7 +225,7 @@ contract IntegrationBase is DSTestPlus, TestConstants, Helpers { function _createRequest() internal returns (bytes32 _requestId) { vm.startPrank(requester); _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(mockRequest, _ipfsHash); + _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); } @@ -232,7 +236,7 @@ contract IntegrationBase is DSTestPlus, TestConstants, Helpers { function _proposeResponse() internal returns (bytes32 _responseId) { vm.startPrank(proposer); _accountingExtension.approveModule(address(_responseModule)); - _responseId = oracle.proposeResponse(mockRequest, mockResponse); + _responseId = oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); vm.stopPrank(); } @@ -243,7 +247,7 @@ contract IntegrationBase is DSTestPlus, TestConstants, Helpers { function _disputeResponse() internal returns (bytes32 _disputeId) { vm.startPrank(disputer); _accountingExtension.approveModule(address(_bondedDisputeModule)); - _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl()); vm.stopPrank(); } diff --git a/solidity/test/integration/MultipleCallbacksModule.t.sol b/solidity/test/integration/MultipleCallbacksModule.t.sol index aaf7d584..3e1b35ac 100644 --- a/solidity/test/integration/MultipleCallbacksModule.t.sol +++ b/solidity/test/integration/MultipleCallbacksModule.t.sol @@ -31,7 +31,7 @@ contract Integration_MultipleCallbackModule is IntegrationBase { } vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); } function test_callbacksNeverRevert() public { @@ -50,7 +50,7 @@ contract Integration_MultipleCallbackModule is IntegrationBase { } vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); } function _setupRequest() internal { @@ -59,21 +59,21 @@ contract Integration_MultipleCallbackModule is IntegrationBase { _deposit(_accountingExtension, requester, usdc, _expectedReward); vm.startPrank(requester); _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(mockRequest, _ipfsHash); + _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); _deposit(_accountingExtension, proposer, usdc, _expectedBondSize); vm.startPrank(proposer); _accountingExtension.approveModule(address(_responseModule)); mockResponse.response = abi.encode(proposer, _requestId, bytes('')); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); vm.stopPrank(); } function _createCallbacksData( address _target, uint256 _length - ) internal returns (address[] memory _targets, bytes[] memory _datas) { + ) internal pure returns (address[] memory _targets, bytes[] memory _datas) { _targets = new address[](_length); _datas = new bytes[](_length); for (uint256 _i; _i < _length; _i++) { diff --git a/solidity/test/integration/Payments.t.sol b/solidity/test/integration/Payments.t.sol index ecee5489..1917890e 100644 --- a/solidity/test/integration/Payments.t.sol +++ b/solidity/test/integration/Payments.t.sol @@ -29,7 +29,7 @@ contract Integration_Payments is IntegrationBase { vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); // Finalize request/response - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); // Check: requester has paid for response? assertEq(_accountingExtension.balanceOf(requester, usdc), 0); @@ -68,7 +68,7 @@ contract Integration_Payments is IntegrationBase { // Warp to finalization time. vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); // Finalize request/response. - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); // Check: requester has paid for response? assertEq(_accountingExtension.balanceOf(requester, weth), 0); diff --git a/solidity/test/integration/RequestCreation.t.sol b/solidity/test/integration/RequestCreation.t.sol index 30b0474f..629b00bc 100644 --- a/solidity/test/integration/RequestCreation.t.sol +++ b/solidity/test/integration/RequestCreation.t.sol @@ -26,7 +26,7 @@ contract Integration_RequestCreation is IntegrationBase { // Create the request vm.prank(requester); - bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); // Check: saved the correct id? assertEq(_requestId, _getId(mockRequest)); @@ -52,7 +52,7 @@ contract Integration_RequestCreation is IntegrationBase { function test_createRequest_withAllModules() public { // Create the request vm.prank(requester); - bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); // Check: saved the correct id? assertEq(_requestId, _getId(mockRequest)); @@ -92,7 +92,7 @@ contract Integration_RequestCreation is IntegrationBase { // Check: should not revert as user has set no rewards and bonded? vm.prank(requester); - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); } /** @@ -113,7 +113,7 @@ contract Integration_RequestCreation is IntegrationBase { // Check: doesn't revert if the reward is 0 and the user has not bonded? vm.prank(requester); - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); } /** @@ -135,7 +135,7 @@ contract Integration_RequestCreation is IntegrationBase { // Check: should revert with `InsufficientFunds` as user has not deposited? vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); vm.prank(requester); - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); } /** @@ -147,11 +147,11 @@ contract Integration_RequestCreation is IntegrationBase { // Create the first request vm.startPrank(requester); - bytes32 _firstRequestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _firstRequestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); // Set the new nonce and create the second request mockRequest.nonce += 1; - bytes32 _secondRequestId = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _secondRequestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); // Check: saved different ids? @@ -174,7 +174,7 @@ contract Integration_RequestCreation is IntegrationBase { // Check: reverts due to the invalid token address? vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); vm.prank(requester); - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); } /** @@ -188,7 +188,7 @@ contract Integration_RequestCreation is IntegrationBase { // Check: reverts with `EVM error`? vm.expectRevert(); - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); // Reset the modules back and configure an invalid dispute module. mockRequest.requestModule = address(_requestModule); @@ -196,7 +196,7 @@ contract Integration_RequestCreation is IntegrationBase { mockRequest.disputeModule = makeAddr('NON-EXISTENT DISPUTE MODULE'); // Check: doesn't revert if any module but the request module is invalid? - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); } diff --git a/solidity/test/integration/ResponseDispute.t.sol b/solidity/test/integration/ResponseDispute.t.sol index bcea40bd..30c04825 100644 --- a/solidity/test/integration/ResponseDispute.t.sol +++ b/solidity/test/integration/ResponseDispute.t.sol @@ -27,7 +27,7 @@ contract Integration_ResponseDispute is IntegrationBase { _deposit(_accountingExtension, disputer, usdc, _expectedBondSize); vm.prank(disputer); - bytes32 _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + bytes32 _disputeId = oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); // Check: the disputer is a participant now? assertTrue(oracle.isParticipant(_getId(mockRequest), disputer)); @@ -52,7 +52,7 @@ contract Integration_ResponseDispute is IntegrationBase { vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); vm.prank(disputer); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); } /** @@ -66,7 +66,7 @@ contract Integration_ResponseDispute is IntegrationBase { vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); vm.prank(disputer); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); } /** @@ -76,7 +76,7 @@ contract Integration_ResponseDispute is IntegrationBase { vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); vm.prank(disputer); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); } /** @@ -84,12 +84,12 @@ contract Integration_ResponseDispute is IntegrationBase { */ function test_disputeResponse_alreadyFinalized() public { vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, _getId(mockRequest))); vm.prank(disputer); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); } /** @@ -99,10 +99,10 @@ contract Integration_ResponseDispute is IntegrationBase { _deposit(_accountingExtension, disputer, usdc, _expectedBondSize); vm.prank(disputer); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); vm.prank(disputer); vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_ResponseAlreadyDisputed.selector, _getId(mockResponse))); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); } } diff --git a/solidity/test/integration/ResponseProposal.t.sol b/solidity/test/integration/ResponseProposal.t.sol index ea0d0e10..62ecdde4 100644 --- a/solidity/test/integration/ResponseProposal.t.sol +++ b/solidity/test/integration/ResponseProposal.t.sol @@ -16,7 +16,7 @@ contract Integration_ResponseProposal is IntegrationBase { // Create the request vm.startPrank(requester); _accountingExtension.approveModule(address(_requestModule)); - _requestId = oracle.createRequest(mockRequest, _ipfsHash); + _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); // Approve the response module on behalf of the proposer @@ -31,7 +31,7 @@ contract Integration_ResponseProposal is IntegrationBase { mockResponse.response = _responseBytes; vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); // Check: the proposer is a participant now? assertTrue(oracle.isParticipant(_requestId, proposer)); @@ -59,7 +59,7 @@ contract Integration_ResponseProposal is IntegrationBase { vm.expectRevert(IBondedResponseModule.BondedResponseModule_TooLateToPropose.selector); vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); } /** @@ -70,7 +70,7 @@ contract Integration_ResponseProposal is IntegrationBase { // First response vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); mockResponse.response = abi.encode('second response'); @@ -79,7 +79,7 @@ contract Integration_ResponseProposal is IntegrationBase { // Second response vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); } /** @@ -95,7 +95,7 @@ contract Integration_ResponseProposal is IntegrationBase { vm.expectRevert(ValidatorLib.ValidatorLib_InvalidResponseBody.selector); vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); } /** @@ -119,7 +119,7 @@ contract Integration_ResponseProposal is IntegrationBase { // Creates the request vm.prank(requester); - oracle.createRequest(mockRequest, _ipfsHash); + oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl(requester)); mockResponse.response = _responseBytes; _resetMockIds(); @@ -128,7 +128,7 @@ contract Integration_ResponseProposal is IntegrationBase { vm.expectRevert(IAccountingExtension.AccountingExtension_InsufficientFunds.selector); vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl(proposer)); } /** @@ -162,7 +162,7 @@ contract Integration_ResponseProposal is IntegrationBase { vm.startPrank(_otherRequester); // Create a new request with another dispute module _accountingExtension.approveModule(mockRequest.requestModule); - bytes32 _requestIdApprovedDisputeModule = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestIdApprovedDisputeModule = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); changePrank(_approvedDisputeModule); @@ -171,7 +171,7 @@ contract Integration_ResponseProposal is IntegrationBase { mockResponse.proposer = proposer; mockResponse.requestId = _requestIdApprovedDisputeModule; - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); vm.stopPrank(); uint256 _newProposerBalance = _accountingExtension.balanceOf(proposer, usdc); @@ -203,7 +203,7 @@ contract Integration_ResponseProposal is IntegrationBase { // Attacker creates a request with their own address as the dispute module mockRequest.disputeModule = _attacker; _accountingExtension.approveModule(mockRequest.requestModule); - bytes32 _requestIdAttacker = oracle.createRequest(mockRequest, _ipfsHash); + bytes32 _requestIdAttacker = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); // Attacker proposes a response from their address (the dispute module) and using another user as the proposer mockResponse.response = _responseBytes; @@ -212,6 +212,6 @@ contract Integration_ResponseProposal is IntegrationBase { // Should revert as the dispute module is not approved vm.expectRevert(IAccountingExtension.AccountingExtension_NotAllowed.selector); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); } } diff --git a/solidity/test/integration/RootVerification.t.sol b/solidity/test/integration/RootVerification.t.sol index 52792fde..9d501b68 100644 --- a/solidity/test/integration/RootVerification.t.sol +++ b/solidity/test/integration/RootVerification.t.sol @@ -89,7 +89,7 @@ contract Integration_RootVerification is IntegrationBase { vm.startPrank(requester); _accountingExtension.approveModule(address(_sparseMerkleTreeModule)); - _requestId = oracle.createRequest(mockRequest, _ipfsHash); + _requestId = oracle.createRequest(mockRequest, _ipfsHash, _createAccessControl()); vm.stopPrank(); vm.prank(proposer); @@ -104,11 +104,11 @@ contract Integration_RootVerification is IntegrationBase { mockResponse.response = abi.encode(_correctRoot); vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl()); vm.warp(block.timestamp + _expectedDeadline + _baseDisputeWindow); - oracle.finalize(mockRequest, mockResponse); + oracle.finalize(mockRequest, mockResponse, _createAccessControl(address(this))); } function test_disputeResponse_incorrectResponse(bytes32 _invalidRoot) public { @@ -119,13 +119,13 @@ contract Integration_RootVerification is IntegrationBase { mockResponse.response = abi.encode(_invalidRoot); vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl(proposer)); _resetMockIds(); vm.startPrank(disputer); _accountingExtension.approveModule(address(_responseModule)); _accountingExtension.approveModule(address(mockRequest.disputeModule)); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); vm.stopPrank(); uint256 _requesterBondedBalance = _accountingExtension.bondedAmountOf(requester, usdc, _requestId); @@ -150,12 +150,12 @@ contract Integration_RootVerification is IntegrationBase { mockResponse.response = abi.encode(_correctRoot); vm.prank(proposer); - oracle.proposeResponse(mockRequest, mockResponse); + oracle.proposeResponse(mockRequest, mockResponse, _createAccessControl(proposer)); _resetMockIds(); vm.startPrank(disputer); _accountingExtension.approveModule(address(_responseModule)); - oracle.disputeResponse(mockRequest, mockResponse, mockDispute); + oracle.disputeResponse(mockRequest, mockResponse, mockDispute, _createAccessControl(disputer)); vm.stopPrank(); assertEq(_accountingExtension.bondedAmountOf(requester, usdc, _requestId), 0); diff --git a/solidity/test/mocks/MockArbitrator.sol b/solidity/test/mocks/MockArbitrator.sol index 828e1dda..0ed3624d 100644 --- a/solidity/test/mocks/MockArbitrator.sol +++ b/solidity/test/mocks/MockArbitrator.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; + import {IArbitrator, IOracle} from '../../interfaces/IArbitrator.sol'; contract MockArbitrator is IArbitrator { diff --git a/solidity/test/mocks/MockAtomicArbitrator.sol b/solidity/test/mocks/MockAtomicArbitrator.sol index 94323d0e..710da1bc 100644 --- a/solidity/test/mocks/MockAtomicArbitrator.sol +++ b/solidity/test/mocks/MockAtomicArbitrator.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.19; import {IArbitrator} from '../../interfaces/IArbitrator.sol'; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; contract MockAtomicArbitrator is IArbitrator { @@ -19,7 +20,7 @@ contract MockAtomicArbitrator is IArbitrator { ) external returns (bytes memory _result) { _result = new bytes(0); answer = IOracle.DisputeStatus.Won; - oracle.resolveDispute(_request, _response, _dispute); + oracle.resolveDispute(_request, _response, _dispute, IAccessController.AccessControl(address(this), bytes(''))); } function getAnswer(bytes32 /* _dispute */ ) external view returns (IOracle.DisputeStatus _answer) { diff --git a/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol b/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol index d45444d4..bdd9957b 100644 --- a/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol +++ b/solidity/test/unit/modules/dispute/BondEscalationModule.t.sol @@ -5,8 +5,11 @@ import 'forge-std/Test.sol'; import {Helpers} from '../../../utils/Helpers.sol'; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IModule} from '@defi-wonderland/prophet-core/solidity/interfaces/IModule.sol'; -import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; + +import {IOracle, IOracleAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; +import {IAccessModule} from '@defi-wonderland/prophet-core/solidity/interfaces/modules/access/IAccessModule.sol'; import {ValidatorLib} from '@defi-wonderland/prophet-core/solidity/libraries/ValidatorLib.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {Strings} from '@openzeppelin/contracts/utils/Strings.sol'; @@ -15,8 +18,10 @@ import { BondEscalationModule, IBondEscalationModule } from '../../../../contracts/modules/dispute/BondEscalationModule.sol'; +import {ModuleTypehash} from '../../../../contracts/utils/ModuleTypehash.sol'; import {IAccountingExtension} from '../../../../interfaces/extensions/IAccountingExtension.sol'; import {IBondEscalationAccounting} from '../../../../interfaces/extensions/IBondEscalationAccounting.sol'; +import {IModuleAccessController} from '../../../../interfaces/modules/access/IModuleAccessController.sol'; /** * @dev Harness to set an entry in the requestData mapping, without triggering setup request hooks @@ -94,7 +99,7 @@ contract BaseTest is Test, Helpers { /** * @notice Deploy the target and mock oracle+accounting extension */ - function setUp() public { + function setUp() public virtual { oracle = IOracle(makeAddr('Oracle')); vm.etch(address(oracle), hex'069420'); @@ -924,7 +929,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { function test_revertIfInvalidDisputeBody() public { // Check: does it revert if the dispute body is invalid? vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - bondEscalationModule.pledgeForDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _createAccessControl(address(this))); } /** @@ -935,7 +940,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the dispute is not escalated yet? vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); - bondEscalationModule.pledgeForDispute(mockRequest, _dispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -961,7 +966,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the bond escalation is over? vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeForDispute(mockRequest, _dispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -990,7 +995,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the maximum number of escalations is reached? vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - bondEscalationModule.pledgeForDispute(mockRequest, _dispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1018,7 +1023,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if trying to pledge in a dispute that is already surpassed? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - bondEscalationModule.pledgeForDispute(mockRequest, _dispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1051,7 +1056,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if trying to tie outside of the tying buffer? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); - bondEscalationModule.pledgeForDispute(mockRequest, _dispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1082,7 +1087,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { vm.warp(disputeCreatedAt + _params.bondEscalationDeadline + _params.tyingBuffer + 1); vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeForDispute(mockRequest, _dispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1123,7 +1128,7 @@ contract BondEscalationModule_Unit_PledgeForDispute is BaseTest { vm.expectEmit(true, true, true, true, address(bondEscalationModule)); emit PledgedForDispute(_disputeId, address(this), _params.bondSize); - bondEscalationModule.pledgeForDispute(mockRequest, _dispute); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _createAccessControl(address(this))); uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesForDispute; // Check: is the number of pledges for the dispute properly updated? @@ -1142,7 +1147,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { function test_revertIfInvalidDisputeBody() public { // Check: does it revert if the dispute body is invalid? vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, mockDispute, _createAccessControl(address(this))); } /** @@ -1153,7 +1158,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the dispute is not escalated yet? vm.expectRevert(IBondEscalationModule.BondEscalationModule_InvalidDispute.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1179,7 +1184,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the bond escalation is over? vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1209,7 +1214,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the maximum number of escalations is reached? vm.expectRevert(IBondEscalationModule.BondEscalationModule_MaxNumberOfEscalationsReached.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1240,7 +1245,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if trying to pledge in a dispute that is already surpassed? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CanOnlySurpassByOnePledge.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1273,7 +1278,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if trying to tie outside of the tying buffer? vm.expectRevert(IBondEscalationModule.BondEscalationModule_CannotBreakTieDuringTyingBuffer.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1304,7 +1309,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { vm.warp(disputeCreatedAt + _params.bondEscalationDeadline + _params.tyingBuffer + 1); vm.expectRevert(IBondEscalationModule.BondEscalationModule_BondEscalationOver.selector); - bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _createAccessControl(address(this))); } /** @@ -1343,7 +1348,7 @@ contract BondEscalationModule_Unit_PledgeAgainstDispute is BaseTest { vm.expectEmit(true, true, true, true, address(bondEscalationModule)); emit PledgedAgainstDispute(_disputeId, address(this), _params.bondSize); - bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _createAccessControl(address(this))); uint256 _pledgesForDispute = bondEscalationModule.getEscalation(_requestId).amountOfPledgesAgainstDispute; // Check: is the number of pledges for the dispute properly updated? @@ -1558,3 +1563,163 @@ contract BondEscalationModule_Unit_SettleBondEscalation is BaseTest { ); } } + +contract BondEscalationModule_Unit_AccessControl is BaseTest { + address internal _accessModule = makeAddr('accessModule'); + + function setUp() public override { + mockRequest.accessModule = _accessModule; + super.setUp(); + } + + function test_pledgeForDispute_accessControl_granted( + address _caller, + address _user, + bytes memory _data, + IBondEscalationModule.RequestParameters memory _params + ) public assumeFuzzable(address(_params.accountingExtension)) { + vm.assume(_caller != _user); + + _params.bondSize = 1000; + _params.maxNumberOfEscalations = 3; + _params.bondEscalationDeadline = bondEscalationDeadline; + _params.tyingBuffer = 1000; + mockRequest.disputeModuleData = abi.encode(_params); + + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + + bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + + uint256 _numForPledgers = 2; + uint256 _numAgainstPledgers = _numForPledgers + 1; + _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + + // expect a call checking whether the access module has been approved by the user + _mockAndExpect( + address(oracle), + abi.encodeCall(IOracleAccessController.isAccessModuleApproved, (_user, _accessModule)), + abi.encode(true) + ); + + IAccessController.AccessControl memory _accessControl = IAccessController.AccessControl({user: _user, data: _data}); + + // Mock and expect call to access control module + vm.mockCall( + _accessModule, + abi.encodeCall( + IAccessModule.hasAccess, + ( + abi.encode( + IAccessModule.AccessControlParameters({ + sender: _caller, + accessControl: _accessControl, + typehash: ModuleTypehash._PLEDGE_FOR_DISPUTE_TYPEHASH, + typehashParams: abi.encode(mockRequest, _dispute) + }) + ) + ) + ), + abi.encode(true) + ); + + _mockAndExpect( + address(_params.accountingExtension), + abi.encodeCall( + IBondEscalationAccounting.pledge, (_user, mockRequest, _dispute, _params.bondToken, _params.bondSize) + ), + abi.encode(true) + ); + + vm.prank(_caller); + bondEscalationModule.pledgeForDispute(mockRequest, _dispute, _accessControl); + } + + function test_pledgeForDispute_accessControl_notGranted( + address _caller, + address _user, + bytes memory _data, + IBondEscalationModule.RequestParameters memory _params + ) public assumeFuzzable(address(_params.accountingExtension)) { + vm.assume(_caller != _user); + + // mock and expect a call checking whether the access module has been approved by the user + _mockAndExpect( + address(oracle), + abi.encodeCall(IOracleAccessController.isAccessModuleApproved, (_user, _accessModule)), + abi.encode(false) + ); + + IAccessController.AccessControl memory _accessControl = IAccessController.AccessControl({user: _user, data: _data}); + + vm.expectRevert(IModuleAccessController.ModuleAccessController_AccessModuleNotApproved.selector); + vm.prank(_caller); + bondEscalationModule.pledgeForDispute(mockRequest, mockDispute, _accessControl); + } + + function test_pledgeAgainstDispute_accessControl_granted( + address _caller, + address _user, + bytes memory _data, + IBondEscalationModule.RequestParameters memory _params + ) public assumeFuzzable(address(_params.accountingExtension)) { + vm.assume(_caller != _user); + + _params.bondSize = 1000; + _params.maxNumberOfEscalations = 3; + _params.bondEscalationDeadline = bondEscalationDeadline; + _params.tyingBuffer = 1000; + mockRequest.disputeModuleData = abi.encode(_params); + + (, IOracle.Dispute memory _dispute) = _getResponseAndDispute(oracle); + bytes32 _requestId = _getId(mockRequest); + bytes32 _disputeId = _getId(_dispute); + + bondEscalationModule.forTest_setEscalatedDispute(_requestId, _disputeId); + + uint256 _numAgainstPledgers = 2; + uint256 _numForPledgers = _numAgainstPledgers + 1; + + _setBondEscalation(_requestId, _numForPledgers, _numAgainstPledgers); + + _mockAndExpect( + address(oracle), + abi.encodeCall(IOracleAccessController.isAccessModuleApproved, (_user, _accessModule)), + abi.encode(true) + ); + + _mockAndExpect( + address(_params.accountingExtension), + abi.encodeCall( + IBondEscalationAccounting.pledge, (_user, mockRequest, _dispute, _params.bondToken, _params.bondSize) + ), + abi.encode(true) + ); + + IAccessController.AccessControl memory _accessControl = IAccessController.AccessControl({user: _user, data: _data}); + + // Mock and expect call to access control module + vm.mockCall( + _accessModule, + abi.encodeCall( + IAccessModule.hasAccess, + ( + abi.encode( + IAccessModule.AccessControlParameters({ + sender: _caller, + accessControl: _accessControl, + typehash: ModuleTypehash._PLEDGE_AGAINST_DISPUTE_TYPEHASH, + typehashParams: abi.encode(mockRequest, _dispute) + }) + ) + ) + ), + abi.encode(true) + ); + + vm.prank(_caller); + bondEscalationModule.pledgeAgainstDispute(mockRequest, _dispute, _accessControl); + } +} diff --git a/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol b/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol index 7d071dfd..144a5e2d 100644 --- a/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol +++ b/solidity/test/unit/modules/dispute/CircuitResolverModule.t.sol @@ -159,9 +159,7 @@ contract CircuitResolverModule_Unit_DisputeResponse is BaseTest { // Mock and expect the call the oracle, updating the dispute's status _mockAndExpect( address(oracle), - abi.encodeWithSelector( - oracle.updateDisputeStatus.selector, mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won - ), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won)), abi.encode(true) ); @@ -201,9 +199,7 @@ contract CircuitResolverModule_Unit_DisputeResponse is BaseTest { // Mock and expect the call the oracle, updating the dispute's status _mockAndExpect( address(oracle), - abi.encodeWithSelector( - oracle.updateDisputeStatus.selector, mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won - ), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won)), abi.encode(true) ); @@ -254,9 +250,7 @@ contract CircuitResolverModule_Unit_DisputeResponse is BaseTest { // Mock and expect the call the oracle, updating the dispute's status _mockAndExpect( address(oracle), - abi.encodeWithSelector( - oracle.updateDisputeStatus.selector, mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Lost - ), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Lost)), abi.encode(true) ); @@ -314,7 +308,13 @@ contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { _mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(_status)); // Mock and expect the call to the oracle, finalizing the request - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.finalize, (mockRequest, mockResponse)), abi.encode()); + _mockAndExpect( + address(oracle), + abi.encodeCall( + IOracle.finalize, (mockRequest, mockResponse, _createAccessControl(address(circuitResolverModule))) + ), + abi.encode() + ); // Check: is the event emitted? vm.expectEmit(true, true, true, true, address(circuitResolverModule)); @@ -377,12 +377,20 @@ contract CircuitResolverModule_Unit_OnDisputeStatusChange is BaseTest { // Mock and expect the call to the oracle, proposing the correct response _mockAndExpect( address(oracle), - abi.encodeCall(IOracle.proposeResponse, (mockRequest, _newResponse)), + abi.encodeCall( + IOracle.proposeResponse, (mockRequest, _newResponse, _createAccessControl(address(circuitResolverModule))) + ), abi.encode(_getId(_newResponse)) ); // Mock and expect the call to the accounting extension, paying the disputer - _mockAndExpect(address(oracle), abi.encodeCall(IOracle.finalize, (mockRequest, _newResponse)), abi.encode()); + _mockAndExpect( + address(oracle), + abi.encodeCall( + IOracle.finalize, (mockRequest, _newResponse, _createAccessControl(address(circuitResolverModule))) + ), + abi.encode() + ); vm.prank(address(oracle)); circuitResolverModule.onDisputeStatusChange(_disputeId, mockRequest, mockResponse, mockDispute); diff --git a/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol b/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol index bf74e3bb..1205386f 100644 --- a/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol +++ b/solidity/test/unit/modules/dispute/RootVerificationModule.t.sol @@ -207,9 +207,7 @@ contract RootVerificationModule_Unit_DisputeResponse is BaseTest { // Mock and expect the call the oracle, updating the dispute's status _mockAndExpect( address(oracle), - abi.encodeWithSelector( - oracle.updateDisputeStatus.selector, mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won - ), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won)), abi.encode(true) ); @@ -250,9 +248,7 @@ contract RootVerificationModule_Unit_DisputeResponse is BaseTest { // Mock and expect the call the oracle, updating the dispute's status _mockAndExpect( address(oracle), - abi.encodeWithSelector( - oracle.updateDisputeStatus.selector, mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won - ), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Won)), abi.encode(true) ); @@ -305,9 +301,7 @@ contract RootVerificationModule_Unit_DisputeResponse is BaseTest { // Mock and expect the call the oracle, updating the dispute's status _mockAndExpect( address(oracle), - abi.encodeWithSelector( - oracle.updateDisputeStatus.selector, mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Lost - ), + abi.encodeCall(IOracle.updateDisputeStatus, (mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus.Lost)), abi.encode(true) ); diff --git a/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol b/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol index 3362cac0..3570c120 100644 --- a/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/BondEscalationResolutionModule.t.sol @@ -272,7 +272,8 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the dispute body is invalid? mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + vm.prank(pledgerFor); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); // 1. BondEscalationResolutionModule_NotEscalated (_requestId,, _disputeId) = _setResolutionModuleData(_params); @@ -282,7 +283,8 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the dispute is not escalated? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + vm.prank(pledgerFor); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); // 2. BondEscalationResolutionModule_PledgingPhaseOver _params.timeUntilDeadline = block.timestamp - 1; @@ -293,7 +295,8 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if the pledging phase is over? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseOver.selector); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + vm.prank(pledgerFor); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); // 3. BondEscalationResolutionModule_MustBeResolved _params.timeUntilDeadline = 10_000; @@ -313,7 +316,8 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if inequality timer has passed? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_MustBeResolved.selector); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + vm.prank(pledgerFor); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); // 4. BondEscalationResolutionModule_AgainstTurnToEqualize vm.warp(block.timestamp - _params.timeToBreakInequality - 1); // Not past the deadline anymore @@ -331,13 +335,14 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { // Check: does it revert if status == AgainstTurnToEqualize? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_AgainstTurnToEqualize.selector); vm.prank(pledgerFor); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); } function test_earlyReturnIfThresholdNotSurpassed( uint256 _pledgeAmount, IBondEscalationResolutionModule.RequestParameters memory _params ) public assumeFuzzable(address(_params.accountingExtension)) { + vm.skip(false); vm.assume(_pledgeAmount < type(uint256).max - 1000); // _pledgeThreshold > _updatedTotalVotes; @@ -373,7 +378,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); vm.startPrank(pledgerFor); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status,) = module.inequalityData(_disputeId); @@ -390,6 +395,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { * @notice Testing _forPercentageDifference >= _scaledPercentageDiffAsInt */ function test_changesStatusIfForSideIsWinning(uint256 _pledgeAmount) public { + vm.skip(false); _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); // I'm setting the values so that the percentage diff is 20% in favor of pledgesFor. @@ -421,7 +427,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); vm.startPrank(pledgerFor); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); @@ -440,6 +446,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { * @notice Testing _againstPercentageDifference >= _scaledPercentageDiffAsInt */ function test_changesStatusIfAgainstSideIsWinning(uint256 _pledgeAmount) public { + vm.skip(false); _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); // Making the against percentage 60% of the total as percentageDiff is 20% @@ -472,7 +479,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); vm.prank(pledgerFor); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); @@ -491,6 +498,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { * @notice Testing _status == forTurnToEqualize && both diffs < percentageDiff */ function test_changesStatusIfSidesAreEqual(uint256 _pledgeAmount) public { + vm.skip(false); _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); // Making both the same so the percentage diff is not reached @@ -520,7 +528,7 @@ contract BondEscalationResolutionModule_Unit_PledgeForDispute is BaseTest { emit PledgedForDispute(pledgerFor, _requestId, _disputeId, _pledgeAmount); vm.prank(pledgerFor); - module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeForDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerFor)); (,, uint256 _realPledgesFor,) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); @@ -558,7 +566,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the dispute body is invalid? mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(address(this))); // 1. BondEscalationResolutionModule_NotEscalated (_requestId,, _disputeId) = _setResolutionModuleData(_params); @@ -568,7 +576,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the dispute is not escalated? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotEscalated.selector); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(address(this))); // 2. BondEscalationResolutionModule_PledgingPhaseOver _params.timeUntilDeadline = block.timestamp - 1; @@ -578,7 +586,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if the pledging phase is over? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_PledgingPhaseOver.selector); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(address(this))); // 3. BondEscalationResolutionModule_MustBeResolved _params.timeUntilDeadline = 10_000; @@ -599,7 +607,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if inequality timer has passed? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_MustBeResolved.selector); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(address(this))); // 4. BondEscalationResolutionModule_AgainstTurnToEqualize vm.warp(block.timestamp - _params.timeToBreakInequality - 1); // Not past the deadline anymore @@ -617,7 +625,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { // Check: does it revert if status == AgainstTurnToEqualize? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_ForTurnToEqualize.selector); vm.prank(pledgerAgainst); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerAgainst)); } function test_earlyReturnIfThresholdNotSurpassed(uint256 _pledgeAmount) public { @@ -658,7 +666,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); vm.startPrank(pledgerAgainst); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerAgainst)); (,,, uint256 _realPledgesAgainst) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status,) = module.inequalityData(_disputeId); @@ -675,6 +683,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { * @notice Testing _againstPercentageDifference >= _scaledPercentageDiffAsInt */ function test_changesStatusIfAgainstSideIsWinning(uint256 _pledgeAmount) public { + vm.skip(false); _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); // I'm setting the values so that the percentage diff is 20% in favor of pledgesAgainst. @@ -706,7 +715,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); vm.startPrank(pledgerAgainst); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerAgainst)); (,,, uint256 _realPledgesAgainst) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); @@ -725,6 +734,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { * @notice Testing _forPercentageDifference >= _scaledPercentageDiffAsInt */ function test_changesStatusIfForSideIsWinning(uint256 _pledgeAmount) public { + vm.skip(false); _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); // Making the against percentage 60% of the total as percentageDiff is 20% @@ -757,7 +767,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); vm.prank(pledgerAgainst); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerAgainst)); (,,, uint256 _realPledgesAgainst) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); @@ -776,6 +786,8 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { * @notice Testing _status == againstTurnToEqualize && both diffs < percentageDiff */ function test_changesStatusIfSidesAreEqual(uint256 _pledgeAmount) public { + vm.skip(false); + _pledgeAmount = bound(_pledgeAmount, 1, type(uint192).max); // Making both the same so the percentage diff is not reached @@ -805,7 +817,7 @@ contract BondEscalationResolutionModule_Unit_PledgeAgainstDispute is BaseTest { emit PledgedAgainstDispute(pledgerAgainst, _requestId, _disputeId, _pledgeAmount); vm.prank(pledgerAgainst); - module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount); + module.pledgeAgainstDispute(mockRequest, mockDispute, _pledgeAmount, _createAccessControl(pledgerAgainst)); (,, uint256 _realPledgesAgainst,) = module.escalations(_disputeId); (IBondEscalationResolutionModule.InequalityStatus _status, uint256 _timer) = module.inequalityData(_disputeId); @@ -1032,7 +1044,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { // Check: does it revert if the dispute body is invalid? mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - module.claimPledge(mockRequest, mockDispute); + module.claimPledge(mockRequest, mockDispute, _createAccessControl(address(this))); (,, bytes32 _disputeId) = _setResolutionModuleData(_params); @@ -1046,7 +1058,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { // Check: does it revert if trying to claim a pledge of a not resolved escalation? vm.expectRevert(IBondEscalationResolutionModule.BondEscalationResolutionModule_NotResolved.selector); - module.claimPledge(mockRequest, mockDispute); + module.claimPledge(mockRequest, mockDispute, _createAccessControl(address(this))); } function test_disputerWon( @@ -1097,7 +1109,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { ); vm.prank(_randomPledger); - module.claimPledge(mockRequest, mockDispute); + module.claimPledge(mockRequest, mockDispute, _createAccessControl(_randomPledger)); // Check: are the pledges for dispute for the dispute and pledger set to 0? assertEq(module.pledgesForDispute(_disputeId, _randomPledger), 0); @@ -1151,7 +1163,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { ); vm.prank(_randomPledger); - module.claimPledge(mockRequest, mockDispute); + module.claimPledge(mockRequest, mockDispute, _createAccessControl(_randomPledger)); // Check: is the pledges against dispute for this dispute and pledger set to 0? assertEq(module.pledgesAgainstDispute(_disputeId, _randomPledger), 0); @@ -1217,7 +1229,7 @@ contract BondEscalationResolutionModule_Unit_ClaimPledge is BaseTest { ); vm.prank(_randomPledger); - module.claimPledge(mockRequest, mockDispute); + module.claimPledge(mockRequest, mockDispute, _createAccessControl(address(_randomPledger))); // Check: is the pledges against dispute for this dispute and pledger set to 0? assertEq(module.pledgesAgainstDispute(_disputeId, _randomPledger), 0); diff --git a/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol b/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol index 1ea5bba7..23c99964 100644 --- a/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/ERC20ResolutionModule.t.sol @@ -199,7 +199,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { emit VoteCast(_voter, _disputeId, _amountOfVotes); vm.prank(_voter); - module.castVote(mockRequest, _dispute, _amountOfVotes); + module.castVote(mockRequest, _dispute, _amountOfVotes, _createAccessControl(_voter)); (, uint256 _totalVotes) = module.escalations(_disputeId); // Check: totalVotes is updated? @@ -216,7 +216,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { // Check: does it revert if the dispute body is invalid? mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - module.castVote(mockRequest, mockDispute, _numberOfVotes); + module.castVote(mockRequest, mockDispute, _numberOfVotes, _createAccessControl(address(this))); } /** @@ -233,7 +233,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { // Check: reverts if called with `_disputeId` of a non-escalated dispute? vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_DisputeNotEscalated.selector); - module.castVote(mockRequest, _dispute, _numberOfVotes); + module.castVote(mockRequest, _dispute, _numberOfVotes, _createAccessControl(address(this))); } /** @@ -265,7 +265,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { // Check: reverts if dispute is already resolved? vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_AlreadyResolved.selector); - module.castVote(mockRequest, _dispute, _amountOfVotes); + module.castVote(mockRequest, _dispute, _amountOfVotes, _createAccessControl(address(this))); } /** @@ -303,7 +303,7 @@ contract ERC20ResolutionModule_Unit_CastVote is BaseTest { // Check: reverts if trying to cast vote after voting phase? vm.expectRevert(IERC20ResolutionModule.ERC20ResolutionModule_VotingPhaseOver.selector); - module.castVote(mockRequest, _dispute, _numberOfVotes); + module.castVote(mockRequest, _dispute, _numberOfVotes, _createAccessControl(address(this))); } } @@ -417,7 +417,7 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { // Check: does it revert if the dispute body is invalid? mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - module.claimVote(mockRequest, mockDispute); + module.claimVote(mockRequest, mockDispute, _createAccessControl(address(this))); } /** @@ -447,7 +447,7 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { // Claim the refund vm.prank(_voter); - module.claimVote(mockRequest, _dispute); + module.claimVote(mockRequest, _dispute, _createAccessControl(address(_voter))); } /** @@ -488,7 +488,7 @@ contract ERC20ResolutionModule_Unit_ClaimVote is BaseTest { // Claim the refund vm.prank(_voter); - module.claimVote(mockRequest, _dispute); + module.claimVote(mockRequest, _dispute, _createAccessControl(address(_voter))); } } diff --git a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol index ad566a2d..49a67024 100644 --- a/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol +++ b/solidity/test/unit/modules/resolution/PrivateERC20ResolutionModule.t.sol @@ -98,7 +98,7 @@ contract BaseTest is Test, Helpers { abi.encodeCall(IOracle.disputeStatus, (_disputeId)), abi.encode(IOracle.DisputeStatus.Escalated) ); - module.commitVote(_request, _dispute, _commitment); + module.commitVote(_request, _dispute, _commitment, _createAccessControl()); vm.warp(END_TIME + 1); @@ -107,7 +107,7 @@ contract BaseTest is Test, Helpers { abi.encodeCall(IERC20.transferFrom, (vm.addr(_i), address(module), _amountOfVotes)), abi.encode() ); - module.revealVote(_request, _dispute, _amountOfVotes, bytes32(_i)); + module.revealVote(_request, _dispute, _amountOfVotes, bytes32(_i), _createAccessControl()); vm.stopPrank(); _totalVotesCast += _amountOfVotes; unchecked { @@ -210,21 +210,21 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if no commitment is given? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_EmptyCommitment.selector); - module.commitVote(mockRequest, mockDispute, bytes32('')); + module.commitVote(mockRequest, mockDispute, bytes32(''), _createAccessControl()); // Compute and store commitment - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, mockDispute, _commitment, _createAccessControl()); // Check: reverts if empty commitment is given? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_EmptyCommitment.selector); - module.commitVote(mockRequest, mockDispute, bytes32('')); + module.commitVote(mockRequest, mockDispute, bytes32(''), _createAccessControl()); // Check: is the commitment stored? IPrivateERC20ResolutionModule.VoterData memory _voterData = module.forTest_getVoterData(_disputeId, _voter); assertEq(_voterData.commitment, _commitment); bytes32 _newCommitment = module.computeCommitment(_disputeId, uint256(_salt), bytes32(_amountOfVotes)); - module.commitVote(mockRequest, mockDispute, _newCommitment); + module.commitVote(mockRequest, mockDispute, _newCommitment, _createAccessControl()); vm.stopPrank(); // Check: is voters data updated with new commitment? @@ -239,7 +239,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if the dispute body is invalid? mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, mockDispute, _commitment, _createAccessControl(address(this))); } /** @@ -256,7 +256,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if no dispute exists? vm.expectRevert(IValidator.Validator_InvalidDispute.selector); - module.commitVote(mockRequest, _dispute, _commitment); + module.commitVote(mockRequest, _dispute, _commitment, _createAccessControl(address(this))); } /** @@ -277,7 +277,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, mockDispute, _commitment, _createAccessControl(address(this))); } /** @@ -300,7 +300,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, mockDispute, _commitment, _createAccessControl(address(this))); } /** @@ -321,7 +321,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, mockDispute, _commitment, _createAccessControl(address(this))); } /** @@ -342,7 +342,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if the dispute is already resolved? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_AlreadyResolved.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, mockDispute, _commitment, _createAccessControl(address(this))); } /** @@ -363,7 +363,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: reverts if dispute is not escalated? == no escalation data vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); - module.commitVote(mockRequest, _dispute, _commitment); + module.commitVote(mockRequest, _dispute, _commitment, _createAccessControl(address(this))); } /** @@ -403,7 +403,7 @@ contract PrivateERC20ResolutionModule_Unit_CommitVote is BaseTest { // Check: does it revert if the committing phase is over? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_CommittingPhaseOver.selector); - module.commitVote(mockRequest, mockDispute, _commitment); + module.commitVote(mockRequest, mockDispute, _commitment, _createAccessControl(address(this))); } } @@ -454,7 +454,7 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { emit VoteRevealed(_voter, _disputeId, _amountOfVotes); vm.prank(_voter); - module.revealVote(mockRequest, _dispute, _amountOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _amountOfVotes, _salt, _createAccessControl(address(_voter))); (, uint256 _totalVotes) = module.escalations(_disputeId); // Check: is totalVotes updated? @@ -472,7 +472,7 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { // Check: does it revert if the dispute body is invalid? mockDispute.requestId = bytes32(0); vm.expectRevert(ValidatorLib.ValidatorLib_InvalidDisputeBody.selector); - module.revealVote(mockRequest, mockDispute, _numberOfVotes, _salt); + module.revealVote(mockRequest, mockDispute, _numberOfVotes, _salt, _createAccessControl(address(this))); } /** @@ -489,7 +489,7 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { // Check: does it revert if the dispute is not escalated? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_DisputeNotEscalated.selector); - module.revealVote(mockRequest, mockDispute, _numberOfVotes, _salt); + module.revealVote(mockRequest, mockDispute, _numberOfVotes, _salt, _createAccessControl(address(this))); } /** @@ -524,11 +524,11 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { if (_timestamp < END_TIME) { // Check: does it revert if trying to reveal during the committing phase? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingCommittingPhase.selector); - module.revealVote(mockRequest, _dispute, _numberOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _numberOfVotes, _salt, _createAccessControl(address(this))); } else { // Check: does it revert if trying to reveal after the revealing phase? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_RevealingPhaseOver.selector); - module.revealVote(mockRequest, _dispute, _numberOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _numberOfVotes, _salt, _createAccessControl(address(this))); } } @@ -579,18 +579,18 @@ contract PrivateERC20ResolutionModule_Unit_RevealVote is BaseTest { // Check: does it revert if the commitment is not valid? (wrong salt) vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); - module.revealVote(mockRequest, _dispute, _amountOfVotes, _wrongSalt); + module.revealVote(mockRequest, _dispute, _amountOfVotes, _wrongSalt, _createAccessControl()); // Check: does it revert if the commitment is not valid? (wrong amount of votes) vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); - module.revealVote(mockRequest, _dispute, _wrongAmountOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _wrongAmountOfVotes, _salt, _createAccessControl()); vm.stopPrank(); // Check: does it revert if the commitment is not valid? (wrong voter) vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_WrongRevealData.selector); vm.prank(_wrongVoter); - module.revealVote(mockRequest, _dispute, _amountOfVotes, _salt); + module.revealVote(mockRequest, _dispute, _amountOfVotes, _salt, _createAccessControl(_wrongVoter)); } } @@ -706,6 +706,7 @@ contract PrivateERC20ResolutionModule_Unit_ResolveDispute is BaseTest { // Jump to timestamp vm.warp(_timestamp); + // fixme : refactor this test if (_timestamp <= 500_000) { // Check: does it revert if trying to resolve during the committing phase? vm.expectRevert(IPrivateERC20ResolutionModule.PrivateERC20ResolutionModule_OnGoingCommittingPhase.selector); diff --git a/solidity/test/unit/modules/response/BondedResponseModule.t.sol b/solidity/test/unit/modules/response/BondedResponseModule.t.sol index 01e2ea33..5e65732a 100644 --- a/solidity/test/unit/modules/response/BondedResponseModule.t.sol +++ b/solidity/test/unit/modules/response/BondedResponseModule.t.sol @@ -646,6 +646,8 @@ contract BondedResponseModule_Unit_ReleaseUnutilizedResponse is BaseTest { vm.expectRevert(IBondedResponseModule.BondedResponseModule_InvalidReleaseParameters.selector); } + address _notTheProposer = makeAddr('not-the-proposer'); + vm.prank(_notTheProposer); bondedResponseModule.releaseUnutilizedResponse(mockRequest, _response); } } diff --git a/solidity/test/utils/Helpers.sol b/solidity/test/utils/Helpers.sol index 44462aba..cd3d2add 100644 --- a/solidity/test/utils/Helpers.sol +++ b/solidity/test/utils/Helpers.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.19; import {TestConstants} from './TestConstants.sol'; +import {IAccessController} from '@defi-wonderland/prophet-core/solidity/interfaces/IAccessController.sol'; import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; import {DSTestPlus} from '@defi-wonderland/solidity-utils/solidity/test/DSTestPlus.sol'; @@ -12,6 +13,7 @@ contract Helpers is DSTestPlus, TestConstants { // Mock objects IOracle.Request public mockRequest = IOracle.Request({ + accessModule: address(0), requestModule: address(0), responseModule: address(0), disputeModule: address(0), @@ -25,6 +27,10 @@ contract Helpers is DSTestPlus, TestConstants { requester: address(this), nonce: 1 }); + + IAccessController.AccessControl public mockAccessControl = + IAccessController.AccessControl({user: address(0), data: bytes('')}); + bytes32 internal _mockRequestId = keccak256(abi.encode(mockRequest)); IOracle.Response public mockResponse = @@ -158,4 +164,17 @@ contract Helpers is DSTestPlus, TestConstants { function _expectEmit(address _contract) internal { vm.expectEmit(true, true, true, true, _contract); } + + function _createAccessControl() internal returns (IAccessController.AccessControl memory _accessControl) { + (, address _msgSender,) = vm.readCallers(); + _accessControl = _createAccessControl(_msgSender); + } + + function _createAccessControl(address _user) + internal + pure + returns (IAccessController.AccessControl memory _accessControl) + { + _accessControl = IAccessController.AccessControl({user: _user, data: bytes('')}); + } } diff --git a/yarn.lock b/yarn.lock index a8aee5fa..931b0815 100644 --- a/yarn.lock +++ b/yarn.lock @@ -193,10 +193,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@defi-wonderland/prophet-core@0.0.0-4d28a0ec": - version "0.0.0-4d28a0ec" - resolved "https://registry.yarnpkg.com/@defi-wonderland/prophet-core/-/prophet-core-0.0.0-4d28a0ec.tgz#228896bb7b9b239c6c25b4deefa8b204d87d7118" - integrity sha512-BF+gSf+nZWNByr9V2/eUvdt7zHlScP0hF47L+grlllMHRadm8T7Eboo6jpIHOgMpLkfNAEVsOyg2vfvgABzACQ== +"@defi-wonderland/prophet-core@0.0.0-0e46031c": + version "0.0.0-0e46031c" + resolved "https://registry.yarnpkg.com/@defi-wonderland/prophet-core/-/prophet-core-0.0.0-0e46031c.tgz#0c31c1a8b45dce4789a1605764672aa9470e89ef" + integrity sha512-0y2Bczrhz3G3lto6UhT8JCfsakKnyi4ERgVIDvjjT8ryBjKBSJqw0jbZ79zU1OMUEE3QiUMKmm7p9V1LsLXiXw== "@defi-wonderland/solidity-utils@0.0.0-3e9c8e8b": version "0.0.0-3e9c8e8b"