-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: sequential resolution module (#55)
- Loading branch information
Showing
8 changed files
with
677 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import {IOracle} from '../interfaces/IOracle.sol'; | ||
import {IModuleData} from '../interfaces/IModuleData.sol'; | ||
|
||
abstract contract ModuleData is IModuleData { | ||
mapping(bytes32 _requestId => bytes _requestData) public requestData; | ||
|
||
function _setupRequest(bytes32 _requestId, bytes calldata _data) internal virtual { | ||
requestData[_requestId] = _data; | ||
_afterSetupRequest(_requestId, _data); | ||
} | ||
|
||
function _finalizeRequest(bytes32 _requestId) internal virtual; | ||
|
||
function _afterSetupRequest(bytes32 _requestId, bytes calldata _data) internal virtual {} | ||
} |
148 changes: 148 additions & 0 deletions
148
solidity/contracts/modules/SequentialResolutionModule.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; | ||
|
||
import {IAccountingExtension} from '../../interfaces/extensions/IAccountingExtension.sol'; | ||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; | ||
import {Module} from '../Module.sol'; | ||
import {IResolutionModule} from '../../interfaces/modules/IResolutionModule.sol'; | ||
import {ISequentialResolutionModule, IOracle} from '../../interfaces/modules/ISequentialResolutionModule.sol'; | ||
|
||
contract SequentialResolutionModule is Module, ISequentialResolutionModule { | ||
IResolutionModule[] public resolutionModules; | ||
uint256 public currentModuleIndex; | ||
|
||
constructor(IOracle _oracle, IResolutionModule[] memory _resolutionModules) Module(_oracle) { | ||
resolutionModules = _resolutionModules; | ||
} | ||
|
||
modifier onlySubmodule() { | ||
if (msg.sender != address(resolutionModules[currentModuleIndex])) revert SequentialResolutionModule_OnlySubmodule(); | ||
_; | ||
} | ||
|
||
function moduleName() external view returns (string memory _moduleName) { | ||
string memory _submodules = resolutionModules[0].moduleName(); | ||
for (uint256 i = 1; i < resolutionModules.length; ++i) { | ||
_submodules = string.concat(_submodules, ', ', resolutionModules[i].moduleName()); | ||
} | ||
return string.concat('SequentialResolutionModule', '[', _submodules, ']'); | ||
} | ||
|
||
function setupRequest(bytes32 _requestId, bytes calldata _data) public override onlyOracle { | ||
super.setupRequest(_requestId, _data); | ||
bytes[] memory _submoduleData = abi.decode(_data, (bytes[])); | ||
for (uint256 i; i < resolutionModules.length; ++i) { | ||
resolutionModules[i].setupRequest(_requestId, _submoduleData[i]); | ||
} | ||
} | ||
|
||
function startResolution(bytes32 _disputeId) external onlyOracle { | ||
resolutionModules[0].startResolution(_disputeId); | ||
} | ||
|
||
function resolveDispute(bytes32 _disputeId) external onlyOracle { | ||
resolutionModules[currentModuleIndex].resolveDispute(_disputeId); | ||
} | ||
|
||
function updateDisputeStatus(bytes32 _disputeId, DisputeStatus _status) external onlySubmodule { | ||
if (_status == DisputeStatus.NoResolution && currentModuleIndex < resolutionModules.length - 1) { | ||
resolutionModules[++currentModuleIndex].startResolution(_disputeId); | ||
} else { | ||
ORACLE.updateDisputeStatus(_disputeId, _status); | ||
} | ||
} | ||
|
||
// TODO: finalizeRequest function. None of the resolution modules use it. How should we implement it? | ||
function finalizeRequest(bytes32 _requestId) external virtual override onlyOracle { | ||
for (uint256 i; i < resolutionModules.length; ++i) { | ||
resolutionModules[i].finalizeRequest(_requestId); | ||
} | ||
} | ||
|
||
function listSubmodules( | ||
uint256 _startFrom, | ||
uint256 _batchSize | ||
) external view returns (IResolutionModule[] memory _list) { | ||
uint256 _length = resolutionModules.length; | ||
uint256 _count = (_batchSize > _length - _startFrom) ? _length - _startFrom : _batchSize; | ||
_list = new IResolutionModule[](_count); | ||
for (uint256 i; i < _count; ++i) { | ||
_list[i] = resolutionModules[_startFrom + i]; | ||
} | ||
} | ||
|
||
// ============ ORACLE Proxy ============= | ||
|
||
function validModule(bytes32 _requestId, address _module) external view returns (bool _validModule) { | ||
_validModule = ORACLE.validModule(_requestId, _module); | ||
} | ||
|
||
function getDispute(bytes32 _disputeId) external view returns (IOracle.Dispute memory _dispute) { | ||
_dispute = ORACLE.getDispute(_disputeId); | ||
} | ||
|
||
function getResponse(bytes32 _responseId) external view returns (IOracle.Response memory _response) { | ||
_response = ORACLE.getResponse(_responseId); | ||
} | ||
|
||
function getRequest(bytes32 _requestId) external view returns (IOracle.Request memory _request) { | ||
_request = ORACLE.getRequest(_requestId); | ||
} | ||
|
||
function getFullRequest(bytes32 _requestId) external view returns (IOracle.FullRequest memory _request) { | ||
_request = ORACLE.getFullRequest(_requestId); | ||
} | ||
|
||
function disputeOf(bytes32 _requestId) external view returns (bytes32 _disputeId) { | ||
_disputeId = ORACLE.disputeOf(_requestId); | ||
} | ||
|
||
function getFinalizedResponse(bytes32 _requestId) external view returns (IOracle.Response memory _response) { | ||
_response = ORACLE.getFinalizedResponse(_requestId); | ||
} | ||
|
||
function getResponseIds(bytes32 _requestId) external view returns (bytes32[] memory _ids) { | ||
_ids = ORACLE.getResponseIds(_requestId); | ||
} | ||
|
||
function listRequests(uint256 _startFrom, uint256 _amount) external view returns (IOracle.FullRequest[] memory _list) { | ||
_list = ORACLE.listRequests(_startFrom, _amount); | ||
} | ||
|
||
function listRequestIds(uint256 _startFrom, uint256 _batchSize) external view returns (bytes32[] memory _list) { | ||
_list = ORACLE.listRequestIds(_startFrom, _batchSize); | ||
} | ||
|
||
function finalize(bytes32 _requestId, bytes32 _finalizedResponseId) external onlySubmodule { | ||
ORACLE.finalize(_requestId, _finalizedResponseId); | ||
} | ||
|
||
function escalateDispute(bytes32 _disputeId) external onlySubmodule { | ||
ORACLE.escalateDispute(_disputeId); | ||
} | ||
|
||
// ============ ORACLE Proxy not implemented ============= | ||
// This functions use msg.sender in the oracle implementation and cannot be called from a the sequential resolution module | ||
|
||
function createRequest(IOracle.NewRequest memory) external payable onlySubmodule returns (bytes32) { | ||
revert SequentialResolutionModule_NotImplemented(); | ||
} | ||
|
||
function createRequests(IOracle.NewRequest[] calldata) external view onlySubmodule returns (bytes32[] memory) { | ||
revert SequentialResolutionModule_NotImplemented(); | ||
} | ||
|
||
function disputeResponse(bytes32, bytes32) external view onlySubmodule returns (bytes32) { | ||
revert SequentialResolutionModule_NotImplemented(); | ||
} | ||
|
||
function proposeResponse(bytes32, bytes calldata) external view onlySubmodule returns (bytes32) { | ||
revert SequentialResolutionModule_NotImplemented(); | ||
} | ||
|
||
function proposeResponse(address, bytes32, bytes calldata) external view onlySubmodule returns (bytes32) { | ||
revert SequentialResolutionModule_NotImplemented(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
interface IModule { | ||
import {IModuleData} from '../interfaces/IModuleData.sol'; | ||
|
||
interface IModule is IModuleData { | ||
error Module_OnlyOracle(); | ||
error Module_InvalidCaller(); | ||
|
||
function requestData(bytes32 _requestId) external view returns (bytes memory _data); | ||
function setupRequest(bytes32 _requestId, bytes calldata _data) external; | ||
function finalizeRequest(bytes32 _requestId) external; | ||
function moduleName() external pure returns (string memory _moduleName); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
interface IModuleData { | ||
function requestData(bytes32 _requestId) external view returns (bytes memory _data); | ||
function moduleName() external view returns (string memory _moduleName); | ||
} |
22 changes: 22 additions & 0 deletions
22
solidity/interfaces/modules/ISequentialResolutionModule.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
import {IOracle} from '../../interfaces/IOracle.sol'; | ||
import {IResolutionModule} from './IResolutionModule.sol'; | ||
|
||
interface ISequentialResolutionModule is IOracle { | ||
/// @notice Thrown when the caller is not a valid sub-module | ||
error SequentialResolutionModule_OnlySubmodule(); | ||
|
||
/// @notice Thrown when the function called is not implemented | ||
error SequentialResolutionModule_NotImplemented(); | ||
|
||
/// @notice Returns the list of submodules | ||
/// @param _startFrom The index to start from | ||
/// @param _batchSize The number of submodules to return | ||
/// @return _list The list of submodules | ||
function listSubmodules( | ||
uint256 _startFrom, | ||
uint256 _batchSize | ||
) external view returns (IResolutionModule[] memory _list); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.