Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: checks createAt #37

Merged
merged 11 commits into from
Aug 6, 2024
7 changes: 6 additions & 1 deletion solidity/contracts/Module.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import {IOracle} from '../interfaces/IOracle.sol';
import {Validator} from './Validator.sol';

abstract contract Module is Validator, IModule {
constructor(IOracle _oracle) payable Validator(_oracle) {}
/// @inheritdoc IModule
IOracle public immutable ORACLE;

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

/**
* @notice Checks that the caller is the oracle
Expand Down
113 changes: 30 additions & 83 deletions solidity/contracts/Oracle.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

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

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

import {IDisputeModule} from '../interfaces/modules/dispute/IDisputeModule.sol';
Expand All @@ -10,7 +12,7 @@ import {IRequestModule} from '../interfaces/modules/request/IRequestModule.sol';
import {IResolutionModule} from '../interfaces/modules/resolution/IResolutionModule.sol';
import {IResponseModule} from '../interfaces/modules/response/IResponseModule.sol';

contract Oracle is IOracle {
contract Oracle is Validator, IOracle {
/// @inheritdoc IOracle
mapping(bytes32 _requestId => uint128 _finalizedAt) public finalizedAt;

Expand Down Expand Up @@ -104,7 +106,7 @@ contract Oracle is IOracle {
Request calldata _request,
Response calldata _response
) external returns (bytes32 _responseId) {
_responseId = _validateProposeResponse(_request, _response);
_responseId = _validateResponse(_request, _response);

// 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,7 +136,11 @@ contract Oracle is IOracle {
Response calldata _response,
Dispute calldata _dispute
) external returns (bytes32 _disputeId) {
_disputeId = _validateDispute(_request, _response, _dispute);
(bytes32 _responseId, bytes32 _disputeId) = _validateResponseAndDispute(_request, _response, _dispute);

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

if (_dispute.proposer != _response.proposer) {
revert Oracle_InvalidDisputeBody();
Expand Down Expand Up @@ -164,7 +170,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) = _validateResponseAndDispute(_request, _response, _dispute);

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

if (disputeOf[_dispute.responseId] != _disputeId) {
revert Oracle_InvalidDisputeId(_disputeId);
Expand All @@ -190,7 +200,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) = _validateResponseAndDispute(_request, _response, _dispute);

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

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

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

if (disputeOf[_dispute.responseId] != _disputeId) {
revert Oracle_InvalidDisputeId(_disputeId);
Expand Down Expand Up @@ -328,7 +346,7 @@ 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 = _getId(_request);

if (requestCreatedAt[_requestId] == 0) {
revert Oracle_InvalidRequestBody();
Expand Down Expand Up @@ -368,6 +386,11 @@ contract Oracle is IOracle {
IOracle.Response calldata _response
) internal returns (bytes32 _requestId, bytes32 _responseId) {
_responseId = _validateResponse(_request, _response);

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

_requestId = _response.requestId;
if (!_matchBytes(_responseId, _responseIds[_requestId], 32)) {
revert Oracle_InvalidFinalizedResponse();
Expand Down Expand Up @@ -416,80 +439,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 view returns (bytes32 _responseId) {
bytes32 _requestId = keccak256(abi.encode(_request));

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

_responseId = keccak256(abi.encode(_response));

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

if (_response.requestId != _requestId) revert Oracle_InvalidResponseBody();
}

function _validateProposeResponse(
Request calldata _request,
Response calldata _response
) internal view returns (bytes32 _responseId) {
bytes32 _requestId = keccak256(abi.encode(_request));

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

_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 view returns (bytes32 _disputeId) {
bytes32 _requestId = keccak256(abi.encode(_request));

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

bytes32 _responseId = keccak256(abi.encode(_response));

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

_disputeId = keccak256(abi.encode(_dispute));

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

if (_dispute.requestId != _requestId || _dispute.responseId != _responseId) revert Oracle_InvalidDisputeBody();
if (_response.requestId != _requestId) revert Oracle_InvalidResponseBody();
}
}
19 changes: 4 additions & 15 deletions solidity/contracts/Validator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@ import {IOracle} from '../interfaces/IOracle.sol';
import {IValidator} from '../interfaces/IValidator.sol';

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

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

/**
* @notice Computes the id a given request
*
Expand Down Expand Up @@ -52,12 +45,11 @@ contract Validator is IValidator {
function _validateResponse(
IOracle.Request calldata _request,
IOracle.Response calldata _response
) internal view returns (bytes32 _responseId) {
) internal pure returns (bytes32 _responseId) {
bytes32 _requestId = _getId(_request);
_responseId = _getId(_response);

if (_response.requestId != _requestId) revert Validator_InvalidResponseBody();
if (ORACLE.responseCreatedAt(_responseId) == 0) revert Validator_InvalidResponse();
0xShaito marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -70,12 +62,11 @@ contract Validator is IValidator {
function _validateDispute(
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute
) internal view returns (bytes32 _disputeId) {
) internal pure returns (bytes32 _disputeId) {
bytes32 _requestId = _getId(_request);
_disputeId = _getId(_dispute);

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

/**
Expand All @@ -88,12 +79,11 @@ contract Validator is IValidator {
function _validateDispute(
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) internal view returns (bytes32 _disputeId) {
) internal pure returns (bytes32 _disputeId) {
bytes32 _responseId = _getId(_response);
_disputeId = _getId(_dispute);

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

/**
Expand All @@ -109,13 +99,12 @@ contract Validator is IValidator {
IOracle.Request calldata _request,
IOracle.Response calldata _response,
IOracle.Dispute calldata _dispute
) internal view returns (bytes32 _responseId, bytes32 _disputeId) {
) internal pure returns (bytes32 _responseId, bytes32 _disputeId) {
bytes32 _requestId = _getId(_request);
_responseId = _getId(_response);
_disputeId = _getId(_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();
}
}
9 changes: 9 additions & 0 deletions solidity/interfaces/IModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ interface IModule {
*/
error Module_OnlyOracle();

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

/**
* @notice The oracle contract
*/
function ORACLE() external view returns (IOracle _oracle);

/*///////////////////////////////////////////////////////////////
LOGIC
//////////////////////////////////////////////////////////////*/
Expand Down
11 changes: 0 additions & 11 deletions solidity/interfaces/IValidator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,4 @@ 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
*/
function ORACLE() external view returns (IOracle _oracle);
}
2 changes: 2 additions & 0 deletions solidity/scripts/Deploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ pragma solidity ^0.8.19;
import {Script, console} from 'forge-std/Script.sol';

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

// solhint-disable no-console
contract Deploy is Script {
Oracle oracle;
Validator validator;
0xJabberwock marked this conversation as resolved.
Show resolved Hide resolved

function run() public {
address deployer = vm.rememberKey(vm.envUint('DEPLOYER_PRIVATE_KEY'));
Expand Down
Loading
Loading