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: WitnetTraps #398

Open
wants to merge 7 commits into
base: 2.0.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions contracts/WitnetTraps.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

import "./WitnetBytecodes.sol";
import "./interfaces/V2/IWitnetTraps.sol";
import "./interfaces/V2/IWitnetTrapsEvents.sol";

/// @title WitnetTraps: Witnet Push Oracle base contract
/// @author The Witnet Foundation.
abstract contract WitnetTraps
is
IWitnetTraps,
IWitnetTrapsEvents
{
function class() virtual external view returns (string memory) {
return type(WitnetTraps).name;
}
function registry() virtual external view returns (WitnetBytecodes);
function specs() virtual external view returns (bytes4);
}
42 changes: 14 additions & 28 deletions contracts/core/defaults/WitnetRequestBoardTrustableBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import "../WitnetUpgradableBase.sol";
import "../../WitnetRequestBoard.sol";
import "../../WitnetRequestFactory.sol";

import "../../data/WitnetRequestBoardDataACLs.sol";
import "../../data/WitnetRequestBoardData.sol";
import "../../interfaces/IWitnetRequest.sol";
import "../../interfaces/IWitnetRequestBoardAdminACLs.sol";
import "../../interfaces/V2/IWitnetRequestBoardReporter.sol";
Expand All @@ -24,7 +24,7 @@ abstract contract WitnetRequestBoardTrustableBase
is
WitnetUpgradableBase,
WitnetRequestBoard,
WitnetRequestBoardDataACLs,
WitnetRequestBoardData,
IWitnetRequestBoardReporter,
IWitnetRequestBoardAdminACLs,
Payable
Expand Down Expand Up @@ -122,6 +122,12 @@ abstract contract WitnetRequestBoardTrustableBase
/// @param _callbackGasLimit Maximum gas to be spent when reporting the data request result.
function estimateBaseFeeWithCallback(uint256 _gasPrice, uint96 _callbackGasLimit) virtual public view returns (uint256);

/// @notice Estimates the actual earnings (or loss), in WEI, that a reporter would get by reporting result to given query,
/// @notice based on the gas price of the calling transaction. Data requesters should consider upgrading the reward on
/// @notice queries providing no actual earnings.
/// @dev Fails if the query does not exist, or if deleted.
function estimateQueryEarnings(uint256[] calldata _witnetQueryIds, uint256 _gasPrice) virtual external view returns (int256);


// ================================================================================================================
// --- Overrides 'Upgradeable' ------------------------------------------------------------------------------------
Expand Down Expand Up @@ -206,7 +212,7 @@ abstract contract WitnetRequestBoardTrustableBase
uint16 _resultMaxSize = registry.lookupRadonRequestResultMaxSize(radHash);
require(
_resultMaxSize > 0,
"WitnetRequestBoardTrustableDefault: invalid RAD"
"WitnetRequestBoardTrustableBase: invalid RAD"
);
return estimateBaseFee(
gasPrice,
Expand Down Expand Up @@ -528,26 +534,6 @@ abstract contract WitnetRequestBoardTrustableBase
// ================================================================================================================
// --- Full implementation of IWitnetRequestBoardReporter ---------------------------------------------------------

/// @notice Estimates the actual earnings (or loss), in WEI, that a reporter would get by reporting result to given query,
/// @notice based on the gas price of the calling transaction. Data requesters should consider upgrading the reward on
/// @notice queries providing no actual earnings.
/// @dev Fails if the query does not exist, or if deleted.
function estimateQueryEarnings(uint256[] calldata _witnetQueryIds, uint256 _gasPrice)
virtual override
external view
returns (int256 _earnings)
{
uint256 _expenses; uint256 _revenues;
for (uint _ix = 0; _ix < _witnetQueryIds.length; _ix ++) {
if (_statusOf(_witnetQueryIds[_ix]) == WitnetV2.QueryStatus.Posted) {
WitnetV2.Request storage __request = __seekQueryRequest(_witnetQueryIds[_ix]);
_revenues += __request.evmReward;
_expenses += _gasPrice * __request.unpackCallbackGasLimit();
}
}
return int256(_revenues) - int256(_expenses);
}

/// Reports the Witnet-provable result to a previously posted request.
/// @dev Will assume `block.timestamp` as the timestamp at which the request was solved.
/// @dev Fails if:
Expand All @@ -570,13 +556,13 @@ abstract contract WitnetRequestBoardTrustableBase
{
require(
_witnetResultTallyHash != 0,
"WitnetRequestBoardTrustableDefault: tally has cannot be zero"
"WitnetRequestBoardTrustableBase: tally hash cannot be zero"
);
// Ensures the result bytes do not have zero length
// This would not be a valid encoding with CBOR and could trigger a reentrancy attack
require(
_witnetResultCborBytes.length != 0,
"WitnetRequestBoardTrustableDefault: result cannot be empty"
"WitnetRequestBoardTrustableBase: result cannot be empty"
);
// Do actual report:
// solhint-disable not-rely-on-time
Expand Down Expand Up @@ -612,17 +598,17 @@ abstract contract WitnetRequestBoardTrustableBase
{
require(
_witnetResultTimestamp <= block.timestamp,
"WitnetRequestBoardTrustableDefault: bad timestamp"
"WitnetRequestBoardTrustableBase: bad timestamp"
);
require(
_witnetResultTallyHash != 0,
"WitnetRequestBoardTrustableDefault: Witnet tallyHash cannot be zero"
"WitnetRequestBoardTrustableBase: Witnet tallyHash cannot be zero"
);
// Ensures the result bytes do not have zero length (this would not be a valid CBOR encoding
// and could trigger a reentrancy attack)
require(
_witnetResultCborBytes.length != 0,
"WitnetRequestBoardTrustableDefault: result cannot be empty"
"WitnetRequestBoardTrustableBase: result cannot be empty"
);
// Do actual report and return reward transfered to the reproter:
return __reportResultAndReward(
Expand Down
31 changes: 31 additions & 0 deletions contracts/core/defaults/WitnetRequestBoardTrustableDefault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ contract WitnetRequestBoardTrustableDefault
is
WitnetRequestBoardTrustableBase
{
using WitnetV2 for WitnetV2.Request;

uint256 internal immutable __reportResultGasBase;
uint256 internal immutable __reportResultWithCallbackGasBase;
uint256 internal immutable __reportResultWithCallbackRevertGasBase;
Expand Down Expand Up @@ -97,6 +99,35 @@ contract WitnetRequestBoardTrustableDefault
}
}

/// @notice Estimates the actual earnings (or loss), in WEI, that a reporter would get by reporting result to given query,
/// @notice based on the gas price of the calling transaction. Data requesters should consider upgrading the reward on
/// @notice queries providing no actual earnings.
/// @dev Fails if the query does not exist, or if deleted.
function estimateQueryEarnings(uint256[] calldata _witnetQueryIds, uint256 _gasPrice)
virtual override
external view
returns (int256 _earnings)
{
uint256 _expenses; uint256 _revenues;
for (uint _ix = 0; _ix < _witnetQueryIds.length; _ix ++) {
if (_statusOf(_witnetQueryIds[_ix]) == WitnetV2.QueryStatus.Posted) {
WitnetV2.Request storage __request = __seekQueryRequest(_witnetQueryIds[_ix]);
_revenues += __request.evmReward;
uint96 _callbackGasLimit = __request.unpackCallbackGasLimit();
if (_callbackGasLimit > 0) {
_expenses += estimateBaseFeeWithCallback(_gasPrice, _callbackGasLimit);
} else {
_expenses += estimateBaseFee(
_gasPrice,
registry.lookupRadonRequestResultMaxSize(__request.RAD)
);
}
}
}
return int256(_revenues) - int256(_expenses);
}



// ================================================================================================================
// --- Overrides 'Payable' ----------------------------------------------------------------------------------------
Expand Down
Loading
Loading