Skip to content
This repository has been archived by the owner on Mar 20, 2020. It is now read-only.

Contracts: Add revert reasons #22

Merged
merged 5 commits into from
Apr 16, 2019
Merged
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
48 changes: 31 additions & 17 deletions packages/ppf-contracts/contracts/PPF.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ import "./open-zeppelin/ECRecovery.sol";
contract PPF is IFeed {
using ECRecovery for bytes32;

uint256 constant public ONE = 10 ** 18; // 10^18 is considered 1 in the price feed to allow for decimal calculations
bytes32 constant public PPF_v1_ID = 0x33a8ba7202230fa1cee2aac7bac322939edc7ba0a48b0989335a5f87a5770369; // keccak256("PPF-v1");
sohkai marked this conversation as resolved.
Show resolved Hide resolved

string private constant ERROR_BAD_SIGNATURE = "PPF_BAD_SIGNATURE";
string private constant ERROR_BAD_RATE_TIMESTAMP = "PPF_BAD_RATE_TIMESTAMP";
string private constant ERROR_INVALID_RATE_VALUE = "PPF_INVALID_RATE_VALUE";
string private constant ERROR_EQUAL_BASE_QUOTE_ADDRESSES = "PPF_EQUAL_BASE_QUOTE_ADDRESSES";
string private constant ERROR_BASE_ADDRESSES_LENGTH_ZERO = "PPF_BASE_ADDRESSES_LEN_ZERO";
string private constant ERROR_QUOTE_ADDRESSES_LENGTH_MISMATCH = "PPF_QUOTE_ADDRESSES_LEN_MISMATCH";
string private constant ERROR_RATE_VALUES_LENGTH_MISMATCH = "PPF_RATE_VALUES_LEN_MISMATCH";
string private constant ERROR_RATE_TIMESTAMPS_LENGTH_MISMATCH = "PPF_RATE_TIMESTAMPS_LEN_MISMATCH";
string private constant ERROR_SIGNATURES_LENGTH_MISMATCH = "PPF_SIGNATURES_LEN_MISMATCH";
string private constant ERROR_CAN_NOT_SET_OPERATOR = "PPF_CAN_NOT_SET_OPERATOR";
string private constant ERROR_CAN_NOT_SET_OPERATOR_OWNER = "PPF_CAN_NOT_SET_OPERATOR_OWNER";
string private constant ERROR_OPERATOR_ADDRESS_ZERO = "PPF_OPERATOR_ADDRESS_ZERO";
string private constant ERROR_OPERATOR_OWNER_ADDRESS_ZERO = "PPF_OPERATOR_OWNER_ADDRESS_ZERO";

struct Price {
uint128 xrt;
uint64 when;
Expand All @@ -16,9 +33,6 @@ contract PPF is IFeed {
address public operator;
address public operatorOwner;

uint256 constant public ONE = 10 ** 18; // 10^18 is considered 1 in the price feed to allow for decimal calculations
bytes32 constant public PPF_v1_ID = 0x33a8ba7202230fa1cee2aac7bac322939edc7ba0a48b0989335a5f87a5770369; // keccak256("PPF-v1");

event SetRate(address indexed base, address indexed quote, uint256 xrt, uint64 when);
event SetOperator(address indexed operator);
event SetOperatorOwner(address indexed operatorOwner);
Expand All @@ -45,12 +59,12 @@ contract PPF is IFeed {
bytes32 pair = pairId(base, quote);

// Ensure it is more recent than the current value (implicit check for > 0) and not a future date
require(when > feed[pair].when && when <= block.timestamp);
require(xrt > 0); // Make sure xrt is not 0, as the math would break (Dividing by 0 sucks big time)
require(base != quote); // Assumption that currency units are fungible and xrt should always be 1
require(when > feed[pair].when && when <= block.timestamp, ERROR_BAD_RATE_TIMESTAMP);
require(xrt > 0, ERROR_INVALID_RATE_VALUE); // Make sure xrt is not 0, as the math would break (Dividing by 0 sucks big time)
require(base != quote, ERROR_EQUAL_BASE_QUOTE_ADDRESSES); // Assumption that currency units are fungible and xrt should always be 1

bytes32 h = setHash(base, quote, xrt, when);
require(h.personalRecover(sig) == operator); // Make sure the update was signed by the operator
require(h.personalRecover(sig) == operator, ERROR_BAD_SIGNATURE); // Make sure the update was signed by the operator

feed[pair] = Price(pairXRT(base, quote, xrt), when);

Expand All @@ -67,12 +81,12 @@ contract PPF is IFeed {
* @param sigs Bytes array with the ordered concatenated signatures for the updates
*/
function updateMany(address[] bases, address[] quotes, uint128[] xrts, uint64[] whens, bytes sigs) public {
require(bases.length != 0);
require(bases.length == quotes.length);
require(bases.length == xrts.length);
require(bases.length == whens.length);
require(bases.length == sigs.length / 65);
require(sigs.length % 65 == 0);
require(bases.length != 0, ERROR_BASE_ADDRESSES_LENGTH_ZERO);
require(bases.length == quotes.length, ERROR_QUOTE_ADDRESSES_LENGTH_MISMATCH);
require(bases.length == xrts.length, ERROR_RATE_VALUES_LENGTH_MISMATCH);
require(bases.length == whens.length, ERROR_RATE_TIMESTAMPS_LENGTH_MISMATCH);
require(bases.length == sigs.length / 65, ERROR_SIGNATURES_LENGTH_MISMATCH);
require(sigs.length % 65 == 0, ERROR_SIGNATURES_LENGTH_MISMATCH);

for (uint256 i = 0; i < bases.length; i++) {
// Extract the signature for the update from the concatenated sigs
Expand Down Expand Up @@ -117,7 +131,7 @@ contract PPF is IFeed {
function setOperator(address _operator) external {
// Allow the current operator to change the operator to avoid having to hassle the
// operatorOwner in cases where a node just wants to rotate its public key
require(msg.sender == operator || msg.sender == operatorOwner);
require(msg.sender == operator || msg.sender == operatorOwner, ERROR_CAN_NOT_SET_OPERATOR);
_setOperator(_operator);
}

Expand All @@ -126,18 +140,18 @@ contract PPF is IFeed {
* @param _operatorOwner Address of an account that can change the operator
*/
function setOperatorOwner(address _operatorOwner) external {
require(msg.sender == operatorOwner);
require(msg.sender == operatorOwner, ERROR_CAN_NOT_SET_OPERATOR_OWNER);
_setOperatorOwner(_operatorOwner);
}

function _setOperator(address _operator) internal {
require(_operator != address(0));
require(_operator != address(0), ERROR_OPERATOR_ADDRESS_ZERO);
operator = _operator;
emit SetOperator(_operator);
}

function _setOperatorOwner(address _operatorOwner) internal {
require(_operatorOwner != address(0));
require(_operatorOwner != address(0), ERROR_OPERATOR_OWNER_ADDRESS_ZERO);
operatorOwner = _operatorOwner;
emit SetOperatorOwner(_operatorOwner);
}
Expand Down