Skip to content

Commit

Permalink
perf: optimize CircuitResolverModule
Browse files Browse the repository at this point in the history
  • Loading branch information
gas1cent committed Nov 6, 2023
1 parent 4144750 commit bf795a1
Show file tree
Hide file tree
Showing 4 changed files with 382 additions and 629 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The Circuit Resolver Module is a pre-dispute module that allows disputers to ver

### Key Methods

- `decodeRequestData(bytes32 _requestId)`: Returns the decoded data for a request.
- `decodeRequestData(bytes calldata _data)`: Returns the decoded data for a request.
- `disputeResponse(bytes32 _requestId, bytes32 _responseId, address _disputer, address _proposer)`: Verifies the ZK circuit and compares it to the proposed one. Updates the dispute status after checking if the disputed response is indeed wrong.
- `onDisputeStatusChange(bytes32 _requestId, IOracle.Dispute memory _dispute)`: Updates the status of the dispute and resolves it by proposing the correct circuit as a response and finalizing the request.
- `disputeEscalated(bytes32 _disputeId)`: This function is present to comply with the module interface but it is not implemented since this is a pre-dispute module.
Expand Down
181 changes: 90 additions & 91 deletions solidity/contracts/modules/dispute/CircuitResolverModule.sol
Original file line number Diff line number Diff line change
@@ -1,91 +1,90 @@
// // 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 {ICircuitResolverModule} from '../../../interfaces/modules/dispute/ICircuitResolverModule.sol';

// contract CircuitResolverModule is Module, ICircuitResolverModule {
// constructor(IOracle _oracle) Module(_oracle) {}

// mapping(bytes32 _requestId => bytes _correctResponse) internal _correctResponses;

// /// @inheritdoc IModule
// function moduleName() external pure returns (string memory _moduleName) {
// return 'CircuitResolverModule';
// }

// /// @inheritdoc ICircuitResolverModule
// function decodeRequestData(bytes32 _requestId) public view returns (RequestParameters memory _params) {
// _params = abi.decode(requestData[_requestId], (RequestParameters));
// }

// /// @inheritdoc ICircuitResolverModule
// function disputeEscalated(bytes32 _disputeId) external onlyOracle {}

// /// @inheritdoc ICircuitResolverModule
// function onDisputeStatusChange(bytes32, /* _disputeId */ IOracle.Dispute memory _dispute) external onlyOracle {
// RequestParameters memory _params = decodeRequestData(_dispute.requestId);

// IOracle.Response memory _response = ORACLE.getResponse(_dispute.responseId);

// bytes memory _correctResponse = _correctResponses[_dispute.requestId];
// bool _won = _response.response.length != _correctResponse.length
// || keccak256(_response.response) != keccak256(_correctResponse);

// 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(_correctResponses[_dispute.requestId]));
// ORACLE.finalize(_dispute.requestId, _correctResponseId);
// } else {
// ORACLE.finalize(_dispute.requestId, _dispute.responseId);
// }

// delete _correctResponses[_dispute.requestId];

// emit DisputeStatusChanged({
// _requestId: _dispute.requestId,
// _responseId: _dispute.responseId,
// _disputer: _dispute.disputer,
// _proposer: _dispute.proposer,
// _status: _dispute.status
// });
// }

// /// @inheritdoc ICircuitResolverModule
// 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);

// (, bytes memory _correctResponse) = _params.verifier.call(_params.callData);
// _correctResponses[_requestId] = _correctResponse;

// bool _won = _response.response.length != _correctResponse.length
// || keccak256(_response.response) != keccak256(_correctResponse);

// _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 {ICircuitResolverModule} from '../../../interfaces/modules/dispute/ICircuitResolverModule.sol';

contract CircuitResolverModule is Module, ICircuitResolverModule {
constructor(IOracle _oracle) Module(_oracle) {}

mapping(bytes32 _requestId => bytes _correctResponse) internal _correctResponses;

/// @inheritdoc IModule
function moduleName() external pure returns (string memory _moduleName) {
return 'CircuitResolverModule';
}

/// @inheritdoc ICircuitResolverModule
function decodeRequestData(bytes calldata _data) public pure returns (RequestParameters memory _params) {
_params = abi.decode(_data, (RequestParameters));
}

/// @inheritdoc ICircuitResolverModule
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);

bytes memory _correctResponse = _correctResponses[_dispute.requestId];
bool _won = _response.response.length != _correctResponse.length
|| keccak256(_response.response) != keccak256(_correctResponse);

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: _correctResponse});

ORACLE.proposeResponse(_dispute.disputer, _request, _newResponse);
ORACLE.finalize(_request, _newResponse);
} else {
ORACLE.finalize(_request, _response);
}

delete _correctResponses[_dispute.requestId];

// TODO: Emit event
// emit DisputeStatusChanged({
// _disputeId: _disputeId,
// _dispute: _dispute,
// _status: IOracle.DisputeStatus.Resolved
// });
}

/// @inheritdoc ICircuitResolverModule
function disputeResponse(
IOracle.Request calldata _request,
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) external onlyOracle {
RequestParameters memory _params = decodeRequestData(_request.disputeModuleData);

(bool _success, bytes memory _correctResponse) = _params.verifier.call(_params.callData);
// TODO: Revert if !_success
_correctResponses[_response.requestId] = _correctResponse;

bool _won = _response.response.length != _correctResponse.length
|| keccak256(_response.response) != keccak256(_correctResponse);

// TODO: call ORACLE.updateDisputeStatus
emit ResponseDisputed({
_responseId: _dispute.responseId,
_disputeId: _getId(_dispute),
_dispute: _dispute,
_blockNumber: block.number
});
}
}
121 changes: 61 additions & 60 deletions solidity/interfaces/modules/dispute/ICircuitResolverModule.sol
Original file line number Diff line number Diff line change
@@ -1,68 +1,69 @@
// // 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 {IAccountingExtension} from '../../extensions/IAccountingExtension.sol';
import {IAccountingExtension} from '../../extensions/IAccountingExtension.sol';

// /**
// * @title CircuitResolverModule
// * @notice Module allowing users to dispute a proposed response
// * by bonding tokens.
// * The module will invoke the circuit verifier supplied to calculate
// * the proposed response and compare it to the correct response.
// * - If the dispute is valid, the disputer wins and their bond is returned along with a reward.
// * - If the dispute is invalid, the bond is forfeited and returned to the proposer.
// *
// * After the dispute is settled, the correct response is automatically proposed to the oracle
// * and the request is finalized.
// */
// interface ICircuitResolverModule is IDisputeModule {
// /*///////////////////////////////////////////////////////////////
// STRUCTS
// //////////////////////////////////////////////////////////////*/
/**
* @title CircuitResolverModule
* @notice Module allowing users to dispute a proposed response
* by bonding tokens.
* The module will invoke the circuit verifier supplied to calculate
* the proposed response and compare it to the correct response.
* - If the dispute is valid, the disputer wins and their bond is returned along with a reward.
* - If the dispute is invalid, the bond is forfeited and returned to the proposer.
*
* After the dispute is settled, the correct response is automatically proposed to the oracle
* and the request is finalized.
*/
interface ICircuitResolverModule is IDisputeModule {
/*///////////////////////////////////////////////////////////////
STRUCTS
//////////////////////////////////////////////////////////////*/

// /**
// * @notice Parameters of the request as stored in the module
// * @return callData The encoded data forwarded to the verifier
// * @return verifier The address of the verifier contract
// * @return accountingExtension The address of the accounting extension
// * @return bondToken The address of the bond token
// * @return bondSize The size of the bond
// */
// struct RequestParameters {
// bytes callData;
// address verifier;
// IAccountingExtension accountingExtension;
// IERC20 bondToken;
// uint256 bondSize;
// }
/**
* @notice Parameters of the request as stored in the module
* @return callData The encoded data forwarded to the verifier
* @return verifier The address of the verifier contract
* @return accountingExtension The address of the accounting extension
* @return bondToken The address of the bond token
* @return bondSize The size of the bond
*/
struct RequestParameters {
bytes callData;
address verifier;
IAccountingExtension accountingExtension;
IERC20 bondToken;
uint256 bondSize;
}

// /*///////////////////////////////////////////////////////////////
// LOGIC
// //////////////////////////////////////////////////////////////*/
/*///////////////////////////////////////////////////////////////
LOGIC
//////////////////////////////////////////////////////////////*/

// /**
// * @notice Returns the decoded data for a request
// * @param _requestId The ID of the request
// * @return _params The decoded parameters of 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);

// /// @inheritdoc IDisputeModule
// function disputeResponse(
// bytes32 _requestId,
// bytes32 _responseId,
// address _disputer,
// address _proposer
// ) external returns (IOracle.Dispute memory _dispute);
/// @inheritdoc IDisputeModule
function disputeResponse(
IOracle.Request calldata _request,
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) external;

// /// @inheritdoc IDisputeModule
// function onDisputeStatusChange(bytes32 _disputeId, IOracle.Dispute memory _dispute) external;

// /// @inheritdoc IDisputeModule
// function disputeEscalated(bytes32 _disputeId) external;
// }
/// @inheritdoc IDisputeModule
function onDisputeStatusChange(
bytes32 _disputeId,
IOracle.Request calldata _request,
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) external;
}
Loading

0 comments on commit bf795a1

Please sign in to comment.