-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf: optimize
RootVerificationModule
(#7)
- Loading branch information
Showing
5 changed files
with
485 additions
and
544 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
189 changes: 95 additions & 94 deletions
189
solidity/contracts/modules/dispute/RootVerificationModule.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 |
---|---|---|
@@ -1,94 +1,95 @@ | ||
// // SPDX-License-Identifier: MIT | ||
// pragma solidity ^0.8.19; | ||
|
||
// // solhint-disable-next-line no-unused-import | ||
// import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; | ||
// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; | ||
|
||
// import {IRootVerificationModule} from '../../../interfaces/modules/dispute/IRootVerificationModule.sol'; | ||
// import {MerkleLib} from '../../libraries/MerkleLib.sol'; | ||
|
||
// contract RootVerificationModule is Module, IRootVerificationModule { | ||
// using MerkleLib for MerkleLib.Tree; | ||
|
||
// /** | ||
// * @notice The calculated correct root for a given request | ||
// */ | ||
// mapping(bytes32 _requestId => bytes32 _correctRoot) internal _correctRoots; | ||
|
||
// constructor(IOracle _oracle) Module(_oracle) {} | ||
|
||
// /// @inheritdoc IModule | ||
// function moduleName() external pure returns (string memory _moduleName) { | ||
// return 'RootVerificationModule'; | ||
// } | ||
|
||
// /// @inheritdoc IRootVerificationModule | ||
// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) { | ||
// _params = abi.decode(requestData[_requestId], (RequestParameters)); | ||
// } | ||
|
||
// /// @inheritdoc IRootVerificationModule | ||
// function disputeEscalated(bytes32 _disputeId) external onlyOracle {} | ||
|
||
// /// @inheritdoc IRootVerificationModule | ||
// function onDisputeStatusChange(bytes32, IOracle.Dispute memory _dispute) external onlyOracle { | ||
// RequestParameters memory _params = decodeRequestData(_dispute.requestId); | ||
|
||
// IOracle.Response memory _response = ORACLE.getResponse(_dispute.responseId); | ||
|
||
// bool _won = abi.decode(_response.response, (bytes32)) != _correctRoots[_dispute.requestId]; | ||
|
||
// if (_won) { | ||
// _params.accountingExtension.pay({ | ||
// _requestId: _dispute.requestId, | ||
// _payer: _dispute.proposer, | ||
// _receiver: _dispute.disputer, | ||
// _token: _params.bondToken, | ||
// _amount: _params.bondSize | ||
// }); | ||
// bytes32 _correctResponseId = | ||
// ORACLE.proposeResponse(_dispute.disputer, _dispute.requestId, abi.encode(_correctRoots[_dispute.requestId])); | ||
// ORACLE.finalize(_dispute.requestId, _correctResponseId); | ||
// } else { | ||
// ORACLE.finalize(_dispute.requestId, _dispute.responseId); | ||
// } | ||
|
||
// delete _correctRoots[_dispute.requestId]; | ||
|
||
// emit DisputeStatusChanged({ | ||
// _requestId: _dispute.requestId, | ||
// _responseId: _dispute.responseId, | ||
// _disputer: _dispute.disputer, | ||
// _proposer: _dispute.proposer, | ||
// _status: _dispute.status | ||
// }); | ||
// } | ||
|
||
// /// @inheritdoc IRootVerificationModule | ||
// function disputeResponse( | ||
// bytes32 _requestId, | ||
// bytes32 _responseId, | ||
// address _disputer, | ||
// address _proposer | ||
// ) external onlyOracle returns (IOracle.Dispute memory _dispute) { | ||
// IOracle.Response memory _response = ORACLE.getResponse(_responseId); | ||
// RequestParameters memory _params = decodeRequestData(_requestId); | ||
|
||
// bytes32 _correctRoot = _params.treeVerifier.calculateRoot(_params.treeData, _params.leavesToInsert); | ||
// _correctRoots[_requestId] = _correctRoot; | ||
|
||
// bool _won = abi.decode(_response.response, (bytes32)) != _correctRoot; | ||
|
||
// _dispute = IOracle.Dispute({ | ||
// disputer: _disputer, | ||
// responseId: _responseId, | ||
// proposer: _proposer, | ||
// requestId: _requestId, | ||
// status: _won ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost, | ||
// createdAt: block.timestamp | ||
// }); | ||
|
||
// emit ResponseDisputed(_requestId, _responseId, _disputer, _proposer); | ||
// } | ||
// } | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
// solhint-disable-next-line no-unused-import | ||
import {Module, IModule} from '@defi-wonderland/prophet-core-contracts/solidity/contracts/Module.sol'; | ||
import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; | ||
|
||
import {IRootVerificationModule} from '../../../interfaces/modules/dispute/IRootVerificationModule.sol'; | ||
import {MerkleLib} from '../../libraries/MerkleLib.sol'; | ||
|
||
contract RootVerificationModule is Module, IRootVerificationModule { | ||
using MerkleLib for MerkleLib.Tree; | ||
|
||
/** | ||
* @notice The calculated correct root for a given request | ||
*/ | ||
mapping(bytes32 _requestId => bytes32 _correctRoot) internal _correctRoots; | ||
|
||
constructor(IOracle _oracle) Module(_oracle) {} | ||
|
||
/// @inheritdoc IModule | ||
function moduleName() external pure returns (string memory _moduleName) { | ||
return 'RootVerificationModule'; | ||
} | ||
|
||
/// @inheritdoc IRootVerificationModule | ||
function decodeRequestData(bytes calldata _data) public pure returns (RequestParameters memory _params) { | ||
_params = abi.decode(_data, (RequestParameters)); | ||
} | ||
|
||
/// @inheritdoc IRootVerificationModule | ||
function onDisputeStatusChange( | ||
bytes32 _disputeId, | ||
IOracle.Request calldata _request, | ||
IOracle.Response calldata _response, | ||
IOracle.Dispute calldata _dispute | ||
) external onlyOracle { | ||
// TODO: Call `disputeStatus` to check the current status | ||
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData); | ||
|
||
bytes32 _correctRoot = _correctRoots[_dispute.requestId]; | ||
bool _won = abi.decode(_response.response, (bytes32)) != _correctRoot; | ||
|
||
if (_won) { | ||
_params.accountingExtension.pay({ | ||
_requestId: _dispute.requestId, | ||
_payer: _dispute.proposer, | ||
_receiver: _dispute.disputer, | ||
_token: _params.bondToken, | ||
_amount: _params.bondSize | ||
}); | ||
|
||
IOracle.Response memory _newResponse = IOracle.Response({ | ||
requestId: _dispute.requestId, | ||
proposer: _dispute.disputer, | ||
response: abi.encode(_correctRoot) | ||
}); | ||
|
||
emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Won}); | ||
|
||
ORACLE.proposeResponse(_request, _newResponse); | ||
ORACLE.finalize(_request, _newResponse); | ||
} else { | ||
emit DisputeStatusChanged({_disputeId: _disputeId, _dispute: _dispute, _status: IOracle.DisputeStatus.Lost}); | ||
ORACLE.finalize(_request, _response); | ||
} | ||
|
||
delete _correctRoots[_dispute.requestId]; | ||
} | ||
|
||
/// @inheritdoc IRootVerificationModule | ||
function disputeResponse( | ||
IOracle.Request calldata _request, | ||
IOracle.Response calldata _response, | ||
IOracle.Dispute calldata _dispute | ||
) external onlyOracle { | ||
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData); | ||
|
||
bytes32 _correctRoot = _params.treeVerifier.calculateRoot(_params.treeData, _params.leavesToInsert); | ||
_correctRoots[_response.requestId] = _correctRoot; | ||
|
||
IOracle.DisputeStatus _status = | ||
abi.decode(_response.response, (bytes32)) != _correctRoot ? IOracle.DisputeStatus.Won : IOracle.DisputeStatus.Lost; | ||
|
||
emit ResponseDisputed({ | ||
_requestId: _response.requestId, | ||
_responseId: _dispute.responseId, | ||
_disputeId: _getId(_dispute), | ||
_dispute: _dispute, | ||
_blockNumber: block.number | ||
}); | ||
|
||
ORACLE.updateDisputeStatus(_request, _response, _dispute, _status); | ||
} | ||
} |
151 changes: 74 additions & 77 deletions
151
solidity/interfaces/modules/dispute/IRootVerificationModule.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 |
---|---|---|
@@ -1,84 +1,81 @@ | ||
// // SPDX-License-Identifier: MIT | ||
// pragma solidity ^0.8.19; | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
// import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; | ||
// import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; | ||
// import {IDisputeModule} from | ||
// '@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; | ||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; | ||
import {IOracle} from '@defi-wonderland/prophet-core-contracts/solidity/interfaces/IOracle.sol'; | ||
import {IDisputeModule} from | ||
'@defi-wonderland/prophet-core-contracts/solidity/interfaces/modules/dispute/IDisputeModule.sol'; | ||
|
||
// import {ITreeVerifier} from '../../ITreeVerifier.sol'; | ||
// import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; | ||
import {ITreeVerifier} from '../../ITreeVerifier.sol'; | ||
import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol'; | ||
|
||
// /* | ||
// * @title RootVerificationModule | ||
// * @notice Dispute module allowing disputers to calculate the correct root | ||
// * for a given request and propose it as a response. If the disputer wins the | ||
// * dispute, he is rewarded with the bond of the proposer. | ||
// * @dev This module is a pre-dispute module. It allows disputing | ||
// * and resolving a response in a single call. | ||
// */ | ||
// interface IRootVerificationModule is IDisputeModule { | ||
// /*/////////////////////////////////////////////////////////////// | ||
// STRUCTS | ||
// //////////////////////////////////////////////////////////////*/ | ||
/* | ||
* @title RootVerificationModule | ||
* @notice Dispute module allowing disputers to calculate the correct root for a given request and propose it as a response. | ||
* If the disputer wins the dispute, he is rewarded with the bond of the proposer. | ||
* | ||
* @dev This module is a pre-dispute module. It allows disputing and resolving a response in a single call. | ||
*/ | ||
interface IRootVerificationModule is IDisputeModule { | ||
/*/////////////////////////////////////////////////////////////// | ||
STRUCTS | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
// /** | ||
// * @notice Parameters of the request as stored in the module | ||
// * @param treeData The data of the tree | ||
// * @param leavesToInsert The leaves to insert in the tree | ||
// * @param treeVerifier The tree verifier to use to calculate the correct root | ||
// * @param accountingExtension The accounting extension to use for bonds and payments | ||
// * @param bondToken The token to use for bonds and payments | ||
// * @param bondSize The size of the bond to participate in the request | ||
// */ | ||
// struct RequestParameters { | ||
// bytes treeData; | ||
// bytes32[] leavesToInsert; | ||
// ITreeVerifier treeVerifier; | ||
// IAccountingExtension accountingExtension; | ||
// IERC20 bondToken; | ||
// uint256 bondSize; | ||
// } | ||
// /*/////////////////////////////////////////////////////////////// | ||
// LOGIC | ||
// //////////////////////////////////////////////////////////////*/ | ||
/** | ||
* @notice Parameters of the request as stored in the module | ||
* @param treeData The data of the tree | ||
* @param leavesToInsert The leaves to insert in the tree | ||
* @param treeVerifier The tree verifier to use to calculate the correct root | ||
* @param accountingExtension The accounting extension to use for bonds and payments | ||
* @param bondToken The token to use for bonds and payments | ||
* @param bondSize The size of the bond to participate in the request | ||
*/ | ||
struct RequestParameters { | ||
bytes treeData; | ||
bytes32[] leavesToInsert; | ||
ITreeVerifier treeVerifier; | ||
IAccountingExtension accountingExtension; | ||
IERC20 bondToken; | ||
uint256 bondSize; | ||
} | ||
/*/////////////////////////////////////////////////////////////// | ||
LOGIC | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
// /** | ||
// * @notice Returns the decoded data for a request | ||
// * @param _requestId The ID of the request | ||
// * @return _params The struct containing the parameters for the request | ||
// */ | ||
// function decodeRequestData(bytes32 _requestId) external view returns (RequestParameters memory _params); | ||
/** | ||
* @notice Returns the decoded data for a request | ||
* @param _data The encoded request parameters | ||
* @return _params The decoded parameters of the request | ||
*/ | ||
function decodeRequestData(bytes calldata _data) external view returns (RequestParameters memory _params); | ||
|
||
// /** | ||
// * @notice Calculates the correct root and compares it to the proposed one. | ||
// * @dev Since this is a pre-dispute module, the dispute status is updated after checking | ||
// * if the disputed response is indeed wrong, since it is calculated on dispute. | ||
// * @param _requestId The id of the request from which the response is being disputed | ||
// * @param _responseId The id of the response being disputed | ||
// * @param _disputer The user who is disputing the response | ||
// * @param _proposer The proposer of the response being disputed | ||
// * @return _dispute The dispute of the current response with the updated status | ||
// */ | ||
// function disputeResponse( | ||
// bytes32 _requestId, | ||
// bytes32 _responseId, | ||
// address _disputer, | ||
// address _proposer | ||
// ) external returns (IOracle.Dispute memory _dispute); | ||
/** | ||
* @notice Initiates and resolves the dispute by comparing the proposed response with the one returned by the verifier | ||
* | ||
* @dev This function will notify the oracle about the outcome of the dispute | ||
* @param _request The request that the response was proposed to | ||
* @param _response The response that is being disputed | ||
* @param _dispute The dispute created by the oracle | ||
*/ | ||
function disputeResponse( | ||
IOracle.Request calldata _request, | ||
IOracle.Response calldata _response, | ||
IOracle.Dispute calldata _dispute | ||
) external; | ||
|
||
// /** | ||
// * @notice Updates the status of the dispute and resolves it by proposing the correct root | ||
// * as a response and finalizing the request. | ||
// * @dev The correct root is retrieved from storage and compared to the proposed root. | ||
// * If the dispute is won, the disputer is paid. In both cases, the request is finalized. | ||
// * @param _dispute The dispute of the current response | ||
// */ | ||
// function onDisputeStatusChange(bytes32, IOracle.Dispute memory _dispute) external; | ||
|
||
// /** | ||
// * @dev This function is present to comply with the module interface but it | ||
// * is not implemented since this is a pre-dispute module. | ||
// */ | ||
// function disputeEscalated(bytes32 _disputeId) external; | ||
// } | ||
/** | ||
* @notice Depending on the status of the dispute, either pays the disputer and submits the correct response, | ||
* or pays the proposer. Finalizes the request in any case. | ||
* | ||
* @param _disputeId The id of the dispute | ||
* @param _request The request that the response was proposed to | ||
* @param _response The response that was disputed | ||
* @param _dispute The dispute | ||
*/ | ||
function onDisputeStatusChange( | ||
bytes32 _disputeId, | ||
IOracle.Request calldata _request, | ||
IOracle.Response calldata _response, | ||
IOracle.Dispute calldata _dispute | ||
) external; | ||
} |
Oops, something went wrong.