Skip to content

Commit

Permalink
feat: checks
Browse files Browse the repository at this point in the history
  • Loading branch information
ashitakah committed Jul 26, 2024
1 parent c25103e commit c6f5150
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 5 deletions.
21 changes: 18 additions & 3 deletions solidity/contracts/Oracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ contract Oracle is IOracle {
revert Oracle_InvalidDisputeBody();
}

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

Expand Down Expand Up @@ -329,6 +329,11 @@ contract Oracle is IOracle {
*/
function _finalizeWithoutResponse(IOracle.Request calldata _request) internal view returns (bytes32 _requestId) {
_requestId = keccak256(abi.encode(_request));

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

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

Expand Down Expand Up @@ -422,8 +427,13 @@ contract Oracle is IOracle {
function _validateResponse(
Request calldata _request,
Response calldata _response
) internal pure returns (bytes32 _responseId) {
) 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();
}
Expand All @@ -440,8 +450,13 @@ contract Oracle is IOracle {
Request calldata _request,
Response calldata _response,
Dispute calldata _dispute
) internal pure returns (bytes32 _disputeId) {
) internal view returns (bytes32 _disputeId) {
bytes32 _requestId = keccak256(abi.encode(_request));

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

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

Expand Down
100 changes: 98 additions & 2 deletions solidity/test/unit/Oracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ contract Oracle_Unit_ProposeResponse is BaseTest {
// Compute the response ID
bytes32 _responseId = _getId(mockResponse);

// Set the request creation time
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));

// Mock and expect the responseModule propose call:
_mockAndExpect(
address(responseModule),
Expand Down Expand Up @@ -446,12 +449,25 @@ contract Oracle_Unit_ProposeResponse is BaseTest {
assertEq(_responseIds[1], _secondResponseId);
}

/**
* @notice Revert if the request doesn't exist
*/
function test_proposeResponse_revertsIfInvalidRequest() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

vm.prank(proposer);
oracle.proposeResponse(mockRequest, mockResponse);
}

/**
* @notice Revert if the caller is not the proposer nor the dispute module
*/
function test_proposeResponse_revertsIfInvalidCaller(address _caller) public {
vm.assume(_caller != proposer && _caller != address(disputeModule));

oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Check: revert?
vm.expectRevert(IOracle.Oracle_InvalidResponseBody.selector);

Expand All @@ -464,6 +480,9 @@ contract Oracle_Unit_ProposeResponse is BaseTest {
* @notice Revert if the response has been already proposed
*/
function test_proposeResponse_revertsIfDuplicateResponse() public {
// Set the request creation time
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Test: propose a response
vm.prank(proposer);
oracle.proposeResponse(mockRequest, mockResponse);
Expand All @@ -485,6 +504,7 @@ contract Oracle_Unit_ProposeResponse is BaseTest {
// Set the finalization time
bytes32 _requestId = _getId(mockRequest);
oracle.mock_setFinalizedAt(_requestId, _finalizedAt);
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));

// Check: Reverts if already finalized?
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, (_requestId)));
Expand Down Expand Up @@ -536,6 +556,18 @@ contract Oracle_Unit_DisputeResponse is BaseTest {
}
}

/**
* @notice Revert if the request doesn't exist
*/
function test_disputeResponse_revertsIfInvalidRequest() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

// Test: try to dispute the response
vm.prank(disputer);
oracle.disputeResponse(mockRequest, mockResponse, mockDispute);
}

/**
* @notice Reverts if the dispute proposer and response proposer are not same
*/
Expand All @@ -544,7 +576,7 @@ contract Oracle_Unit_DisputeResponse is BaseTest {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);

// Check: revert?
vm.expectRevert(IOracle.Oracle_InvalidDisputeBody.selector);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

mockDispute.proposer = _otherProposer;

Expand All @@ -560,7 +592,7 @@ contract Oracle_Unit_DisputeResponse is BaseTest {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);

// Check: revert?
vm.expectRevert(IOracle.Oracle_InvalidDisputeBody.selector);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

// Test: try to dispute the response
vm.prank(disputer);
Expand Down Expand Up @@ -636,6 +668,18 @@ contract Oracle_Unit_UpdateDisputeStatus is BaseTest {
}
}

/**
* @notice Revert if the request doesn't exist
*/
function test_updateDisputeStatus_revertsIfInvalidRequest() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

// Test: change the status
vm.prank(address(resolutionModule));
oracle.updateDisputeStatus(mockRequest, mockResponse, mockDispute, IOracle.DisputeStatus(0));
}

/**
* @notice Providing a dispute that does not match the response should revert
*/
Expand All @@ -647,6 +691,7 @@ contract Oracle_Unit_UpdateDisputeStatus is BaseTest {

// Setting a random dispute id, not matching the mockDispute
oracle.mock_setDisputeOf(_getId(mockResponse), _randomId);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Check: revert?
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidDisputeId.selector, _disputeId));
Expand Down Expand Up @@ -683,6 +728,7 @@ contract Oracle_Unit_ResolveDispute is BaseTest {
function test_resolveDispute_callsResolutionModule() public {
// Mock the dispute
bytes32 _disputeId = _getId(mockDispute);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));
oracle.mock_setDisputeOf(_getId(mockResponse), _disputeId);
oracle.mock_setDisputeStatus(_disputeId, IOracle.DisputeStatus.Active);

Expand All @@ -705,13 +751,25 @@ contract Oracle_Unit_ResolveDispute is BaseTest {
* @notice Test the revert when the function is called with an non-existent dispute id
*/
function test_resolveDispute_revertsIfInvalidDispute() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));
// Check: revert?
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidDisputeId.selector, _getId(mockDispute)));

// Test: try to resolve the dispute
oracle.resolveDispute(mockRequest, mockResponse, mockDispute);
}

/**
* @notice Revert if the request doesn't exist
*/
function test_resolveDispute_revertsIfInvalidRequest() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

// Test: try to resolve the dispute
oracle.resolveDispute(mockRequest, mockResponse, mockDispute);
}

/**
* @notice Test the revert when the function is called with a dispute in unresolvable status
*/
Expand All @@ -725,6 +783,7 @@ contract Oracle_Unit_ResolveDispute is BaseTest {

// Mock the dispute
oracle.mock_setDisputeOf(_getId(mockResponse), _disputeId);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));
oracle.mock_setDisputeStatus(_disputeId, IOracle.DisputeStatus(_status));

// Check: revert?
Expand Down Expand Up @@ -753,6 +812,7 @@ contract Oracle_Unit_ResolveDispute is BaseTest {
// Mock the dispute
oracle.mock_setDisputeOf(_getId(mockResponse), _disputeId);
oracle.mock_setDisputeStatus(_disputeId, IOracle.DisputeStatus.Escalated);
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));

// Check: revert?
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_NoResolutionModule.selector, _disputeId));
Expand Down Expand Up @@ -832,7 +892,9 @@ contract Oracle_Unit_Finalize is BaseTest {
bytes32 _requestId = _getId(mockRequest);
mockResponse.requestId = _requestId;
bytes32 _responseId = _getId(mockResponse);

oracle.mock_addResponseId(_requestId, _responseId);
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));

// Mock the finalize call on all modules
bytes memory _calldata = abi.encodeCall(IModule.finalizeRequest, (mockRequest, mockResponse, _caller));
Expand All @@ -857,6 +919,17 @@ contract Oracle_Unit_Finalize is BaseTest {
assertEq(oracle.finalizedAt(_requestId), block.number);
}

/**
* @notice Revert if the request doesn't exist
*/
function test_finalize_revertsIfInvalidRequest() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

vm.prank(requester);
oracle.finalize(mockRequest, mockResponse);
}

/**
* @notice Finalizing an already finalized request
*/
Expand All @@ -866,6 +939,7 @@ contract Oracle_Unit_Finalize is BaseTest {
// Test: finalize a finalized request
oracle.mock_setFinalizedAt(_requestId, uint128(block.number));
oracle.mock_addResponseId(_requestId, _getId(mockResponse));
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));

vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, _requestId));
vm.prank(requester);
Expand All @@ -883,6 +957,7 @@ contract Oracle_Unit_Finalize is BaseTest {

// Store the response
oracle.mock_addResponseId(_requestId, _responseId);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Test: finalize the request
vm.expectRevert(IOracle.Oracle_InvalidResponseBody.selector);
Expand All @@ -894,6 +969,8 @@ contract Oracle_Unit_Finalize is BaseTest {
* @notice Finalizing a request with an unrelated response
*/
function test_finalize_withResponse_revertsIfInvalidResponse() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Test: finalize the request
vm.expectRevert(IOracle.Oracle_InvalidFinalizedResponse.selector);
vm.prank(requester);
Expand All @@ -914,6 +991,7 @@ contract Oracle_Unit_Finalize is BaseTest {

// Submit a response to the request
oracle.mock_addResponseId(_requestId, _responseId);
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));
oracle.mock_setDisputeOf(_responseId, _disputeId);
oracle.mock_setDisputeStatus(_disputeId, IOracle.DisputeStatus.Won);

Expand All @@ -936,6 +1014,7 @@ contract Oracle_Unit_Finalize is BaseTest {
vm.assume(_caller != address(0));

bytes32 _requestId = _getId(mockRequest);
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));
mockResponse.requestId = bytes32(0);

// Create mock request and store it
Expand Down Expand Up @@ -977,6 +1056,7 @@ contract Oracle_Unit_Finalize is BaseTest {
vm.assume(_status <= uint256(type(IOracle.DisputeStatus).max));

bytes32 _requestId = _getId(mockRequest);
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));

IOracle.DisputeStatus _disputeStatus = IOracle.DisputeStatus(_status);

Expand Down Expand Up @@ -1014,6 +1094,7 @@ contract Oracle_Unit_Finalize is BaseTest {

// Override the finalizedAt to make it be finalized
oracle.mock_setFinalizedAt(_requestId, uint128(block.number));
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Test: finalize a finalized request
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_AlreadyFinalized.selector, _requestId));
Expand All @@ -1031,6 +1112,7 @@ contract Oracle_Unit_Finalize is BaseTest {

// Submit a response to the request
oracle.mock_addResponseId(_requestId, _responseId);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Check: reverts?
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_FinalizableResponseExists.selector, _responseId));
Expand All @@ -1050,6 +1132,7 @@ contract Oracle_Unit_EscalateDispute is BaseTest {

oracle.mock_setDisputeOf(_getId(mockResponse), _disputeId);
oracle.mock_setDisputeStatus(_disputeId, IOracle.DisputeStatus.Active);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));

// Mock and expect the dispute module call
_mockAndExpect(
Expand Down Expand Up @@ -1093,6 +1176,7 @@ contract Oracle_Unit_EscalateDispute is BaseTest {

oracle.mock_setDisputeOf(_getId(mockResponse), _disputeId);
oracle.mock_setDisputeStatus(_disputeId, IOracle.DisputeStatus.Active);
oracle.mock_setRequestCreatedAt(_requestId, uint128(block.number));

// Mock and expect the dispute module call
_mockAndExpect(
Expand All @@ -1112,11 +1196,22 @@ contract Oracle_Unit_EscalateDispute is BaseTest {
assertEq(uint256(oracle.disputeStatus(_disputeId)), uint256(IOracle.DisputeStatus.Escalated));
}

/**
* @notice Revert if the request doesn't exist
*/
function test_escalateDispute_revertsIfInvalidRequest() public {
oracle.mock_setRequestCreatedAt(_getId(mockRequest), 0);
vm.expectRevert(IOracle.Oracle_InvalidRequestBody.selector);

oracle.escalateDispute(mockRequest, mockResponse, mockDispute);
}

/**
* @notice Revert if the provided dispute does not match the request or the response
*/
function test_escalateDispute_revertsIfDisputeNotValid() public {
bytes32 _disputeId = _getId(mockDispute);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));
vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_InvalidDisputeId.selector, _disputeId));

// Test: escalate the dispute
Expand All @@ -1125,6 +1220,7 @@ contract Oracle_Unit_EscalateDispute is BaseTest {

function test_escalateDispute_revertsIfDisputeNotActive() public {
bytes32 _disputeId = _getId(mockDispute);
oracle.mock_setRequestCreatedAt(_getId(mockRequest), uint128(block.number));
oracle.mock_setDisputeOf(_getId(mockResponse), _disputeId);

vm.expectRevert(abi.encodeWithSelector(IOracle.Oracle_CannotEscalate.selector, _disputeId));
Expand Down

0 comments on commit c6f5150

Please sign in to comment.