Skip to content

Commit

Permalink
feat: checks createAt (#37)
Browse files Browse the repository at this point in the history
* feat: checks

* feat: checks response and dispute

* feat: implemented validate and tests

* feat: lib and comments

* fix: linter

* fix: linter

* feat: request response

* fix: comments

* fix: linter

* fix: comments
  • Loading branch information
ashitakah authored Aug 6, 2024
1 parent d01bc1a commit 438de1c
Show file tree
Hide file tree
Showing 9 changed files with 529 additions and 139 deletions.
5 changes: 3 additions & 2 deletions solidity/contracts/Module.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ pragma solidity ^0.8.19;

import {IModule} from '../interfaces/IModule.sol';
import {IOracle} from '../interfaces/IOracle.sol';

import {Validator} from './Validator.sol';

abstract contract Module is Validator, IModule {
constructor(IOracle _oracle) payable Validator(_oracle) {}
abstract contract Module is IModule, Validator {
constructor(IOracle _oracle) Validator(_oracle) {}

/**
* @notice Checks that the caller is the oracle
Expand Down
86 changes: 41 additions & 45 deletions solidity/contracts/Oracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {IFinalityModule} from '../interfaces/modules/finality/IFinalityModule.so
import {IRequestModule} from '../interfaces/modules/request/IRequestModule.sol';
import {IResolutionModule} from '../interfaces/modules/resolution/IResolutionModule.sol';
import {IResponseModule} from '../interfaces/modules/response/IResponseModule.sol';
import {ValidatorLib} from '../lib/ValidatorLib.sol';

contract Oracle is IOracle {
/// @inheritdoc IOracle
Expand Down Expand Up @@ -104,7 +105,12 @@ contract Oracle is IOracle {
Request calldata _request,
Response calldata _response
) external returns (bytes32 _responseId) {
_responseId = _validateResponse(_request, _response);
bytes32 _requestId = ValidatorLib._getId(_request);
(_responseId) = ValidatorLib._validateResponse(_request, _response);

if (requestCreatedAt[_requestId] == 0) {
revert Oracle_InvalidRequest();
}

// The caller must be the proposer, unless the response is coming from a dispute module
if (msg.sender != _response.proposer && msg.sender != address(_request.disputeModule)) {
Expand Down Expand Up @@ -134,13 +140,18 @@ contract Oracle is IOracle {
Response calldata _response,
Dispute calldata _dispute
) external returns (bytes32 _disputeId) {
_disputeId = _validateDispute(_request, _response, _dispute);
bytes32 _responseId;
(_responseId, _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

if (responseCreatedAt[_responseId] == 0) {
revert Oracle_InvalidResponse();
}

if (_dispute.proposer != _response.proposer) {
revert Oracle_InvalidDisputeBody();
}

if (_dispute.disputer != msg.sender || requestCreatedAt[_dispute.requestId] == 0) {
if (_dispute.disputer != msg.sender) {
revert Oracle_InvalidDisputeBody();
}

Expand All @@ -164,7 +175,11 @@ contract Oracle is IOracle {

/// @inheritdoc IOracle
function escalateDispute(Request calldata _request, Response calldata _response, Dispute calldata _dispute) external {
bytes32 _disputeId = _validateDispute(_request, _response, _dispute);
(, bytes32 _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

if (disputeCreatedAt[_disputeId] == 0) {
revert Oracle_InvalidDispute();
}

if (disputeOf[_dispute.responseId] != _disputeId) {
revert Oracle_InvalidDisputeId(_disputeId);
Expand All @@ -190,7 +205,11 @@ contract Oracle is IOracle {

/// @inheritdoc IOracle
function resolveDispute(Request calldata _request, Response calldata _response, Dispute calldata _dispute) external {
bytes32 _disputeId = _validateDispute(_request, _response, _dispute);
(, bytes32 _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

if (disputeCreatedAt[_disputeId] == 0) {
revert Oracle_InvalidDispute();
}

if (disputeOf[_dispute.responseId] != _disputeId) {
revert Oracle_InvalidDisputeId(_disputeId);
Expand Down Expand Up @@ -218,7 +237,11 @@ contract Oracle is IOracle {
Dispute calldata _dispute,
DisputeStatus _status
) external {
bytes32 _disputeId = _validateDispute(_request, _response, _dispute);
(, bytes32 _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

if (disputeCreatedAt[_disputeId] == 0) {
revert Oracle_InvalidDispute();
}

if (disputeOf[_dispute.responseId] != _disputeId) {
revert Oracle_InvalidDisputeId(_disputeId);
Expand Down Expand Up @@ -328,7 +351,12 @@ contract Oracle is IOracle {
* @return _requestId The id of the finalized request
*/
function _finalizeWithoutResponse(IOracle.Request calldata _request) internal view returns (bytes32 _requestId) {
_requestId = keccak256(abi.encode(_request));
_requestId = ValidatorLib._getId(_request);

if (requestCreatedAt[_requestId] == 0) {
revert Oracle_InvalidRequest();
}

bytes32[] memory _responses = getResponseIds(_requestId);
uint256 _responsesAmount = _responses.length;

Expand Down Expand Up @@ -362,7 +390,12 @@ contract Oracle is IOracle {
IOracle.Request calldata _request,
IOracle.Response calldata _response
) internal returns (bytes32 _requestId, bytes32 _responseId) {
_responseId = _validateResponse(_request, _response);
_responseId = ValidatorLib._validateResponse(_request, _response);

if (responseCreatedAt[_responseId] == 0) {
revert Oracle_InvalidResponse();
}

_requestId = _response.requestId;
if (!_matchBytes(_responseId, _responseIds[_requestId], 32)) {
revert Oracle_InvalidFinalizedResponse();
Expand Down Expand Up @@ -411,41 +444,4 @@ contract Oracle is IOracle {

emit RequestCreated(_requestId, _request, _ipfsHash, block.number);
}

/**
* @notice Validates the correctness of a request-response pair
*
* @param _request The request to compute the id for
* @param _response The response to compute the id for
* @return _responseId The id the response
*/
function _validateResponse(
Request calldata _request,
Response calldata _response
) internal pure returns (bytes32 _responseId) {
bytes32 _requestId = keccak256(abi.encode(_request));
_responseId = keccak256(abi.encode(_response));
if (_response.requestId != _requestId) revert Oracle_InvalidResponseBody();
}

/**
* @notice Validates the correctness of a request-response-dispute triplet
*
* @param _request The request to compute the id for
* @param _response The response to compute the id for
* @param _dispute The dispute to compute the id for
* @return _disputeId The id the dispute
*/
function _validateDispute(
Request calldata _request,
Response calldata _response,
Dispute calldata _dispute
) internal pure returns (bytes32 _disputeId) {
bytes32 _requestId = keccak256(abi.encode(_request));
bytes32 _responseId = keccak256(abi.encode(_response));
_disputeId = keccak256(abi.encode(_dispute));

if (_dispute.requestId != _requestId || _dispute.responseId != _responseId) revert Oracle_InvalidDisputeBody();
if (_response.requestId != _requestId) revert Oracle_InvalidResponseBody();
}
}
35 changes: 13 additions & 22 deletions solidity/contracts/Validator.sol
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IOracle} from '../interfaces/IOracle.sol';
import {IValidator} from '../interfaces/IValidator.sol';
import {IOracle, IValidator} from '../interfaces/IValidator.sol';

contract Validator is IValidator {
import {ValidatorLib} from '../lib/ValidatorLib.sol';

abstract contract Validator is IValidator {
/// @inheritdoc IValidator
IOracle public immutable ORACLE;

constructor(IOracle _oracle) payable {
constructor(IOracle _oracle) {
ORACLE = _oracle;
}

/**
* @notice Computes the id a given request
*
* @param _request The request to compute the id for
* @return _id The id the request
*/

function _getId(IOracle.Request calldata _request) internal pure returns (bytes32 _id) {
_id = keccak256(abi.encode(_request));
_id = ValidatorLib._getId(_request);
}

/**
Expand All @@ -29,7 +30,7 @@ contract Validator is IValidator {
* @return _id The id the response
*/
function _getId(IOracle.Response calldata _response) internal pure returns (bytes32 _id) {
_id = keccak256(abi.encode(_response));
_id = ValidatorLib._getId(_response);
}

/**
Expand All @@ -39,7 +40,7 @@ contract Validator is IValidator {
* @return _id The id the dispute
*/
function _getId(IOracle.Dispute calldata _dispute) internal pure returns (bytes32 _id) {
_id = keccak256(abi.encode(_dispute));
_id = ValidatorLib._getId(_dispute);
}

/**
Expand All @@ -53,10 +54,8 @@ contract Validator is IValidator {
IOracle.Request calldata _request,
IOracle.Response calldata _response
) internal view returns (bytes32 _responseId) {
bytes32 _requestId = _getId(_request);
_responseId = _getId(_response);
_responseId = ValidatorLib._validateResponse(_request, _response);

if (_response.requestId != _requestId) revert Validator_InvalidResponseBody();
if (ORACLE.responseCreatedAt(_responseId) == 0) revert Validator_InvalidResponse();
}

Expand All @@ -71,10 +70,8 @@ contract Validator is IValidator {
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute
) internal view returns (bytes32 _disputeId) {
bytes32 _requestId = _getId(_request);
_disputeId = _getId(_dispute);
_disputeId = ValidatorLib._validateDispute(_request, _dispute);

if (_dispute.requestId != _requestId) revert Validator_InvalidDisputeBody();
if (ORACLE.disputeCreatedAt(_disputeId) == 0) revert Validator_InvalidDispute();
}

Expand All @@ -89,10 +86,8 @@ contract Validator is IValidator {
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) internal view returns (bytes32 _disputeId) {
bytes32 _responseId = _getId(_response);
_disputeId = _getId(_dispute);
_disputeId = ValidatorLib._validateDispute(_response, _dispute);

if (_dispute.responseId != _responseId) revert Validator_InvalidDisputeBody();
if (ORACLE.disputeCreatedAt(_disputeId) == 0) revert Validator_InvalidDispute();
}

Expand All @@ -110,12 +105,8 @@ contract Validator is IValidator {
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) internal view returns (bytes32 _responseId, bytes32 _disputeId) {
bytes32 _requestId = _getId(_request);
_responseId = _getId(_response);
_disputeId = _getId(_dispute);
(_responseId, _disputeId) = ValidatorLib._validateResponseAndDispute(_request, _response, _dispute);

if (_response.requestId != _requestId) revert Validator_InvalidResponseBody();
if (_dispute.requestId != _requestId || _dispute.responseId != _responseId) revert Validator_InvalidDisputeBody();
if (ORACLE.disputeCreatedAt(_disputeId) == 0) revert Validator_InvalidDispute();
}
}
15 changes: 15 additions & 0 deletions solidity/interfaces/IOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,21 @@ interface IOracle {
*/
error Oracle_InvalidDisputeBody();

/**
* @notice Thrown when the request provided does not exist
*/
error Oracle_InvalidRequest();

/**
* @notice Thrown when the response provided does not exist
*/
error Oracle_InvalidResponse();

/**
* @notice Thrown when the dispute provided does not exist
*/
error Oracle_InvalidDispute();

/*///////////////////////////////////////////////////////////////
ENUMS
//////////////////////////////////////////////////////////////*/
Expand Down
15 changes: 1 addition & 14 deletions solidity/interfaces/IValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,6 @@ interface IValidator {
ERRORS
//////////////////////////////////////////////////////////////*/

/**
* @notice Thrown when the response provided does not match the request
*/
error Validator_InvalidResponseBody();

/**
* @notice Thrown when the dispute provided does not match the request or response
*/
error Validator_InvalidDisputeBody();

/**
* @notice Thrown when the response provided does not exist
*/
Expand All @@ -31,15 +21,12 @@ interface IValidator {
* @notice Thrown when the dispute provided does not exist
*/
error Validator_InvalidDispute();

/*///////////////////////////////////////////////////////////////
VARIABLES
//////////////////////////////////////////////////////////////*/

/**
* @notice Returns the address of the oracle
*
* @return _oracle The address of the oracle
* @notice The oracle contract
*/
function ORACLE() external view returns (IOracle _oracle);
}
Loading

0 comments on commit 438de1c

Please sign in to comment.