/** * Source Code first verified at https://etherscan.io on Monday, April 29, 2019 (UTC) */ // File: contracts/interfaces/IERC173.sol pragma solidity ^0.5.7; /// @title ERC-173 Contract Ownership Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-173.md /// Note: the ERC-165 identifier for this interface is 0x7f5828d0 contract IERC173 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed _previousOwner, address indexed _newOwner); /// @notice Get the address of the owner /// @return The address of the owner. //// function owner() external view returns (address); /// @notice Set the address of the new owner of the contract /// @param _newOwner The address of the new owner of the contract function transferOwnership(address _newOwner) external; } // File: contracts/commons/Ownable.sol pragma solidity ^0.5.7; contract Ownable is IERC173 { address internal _owner; modifier onlyOwner() { require(msg.sender == _owner, "The owner should be the sender"); _; } constructor() public { _owner = msg.sender; emit OwnershipTransferred(address(0x0), msg.sender); } function owner() external view returns (address) { return _owner; } /** @dev Transfers the ownership of the contract. @param _newOwner Address of the new owner */ function transferOwnership(address _newOwner) external onlyOwner { require(_newOwner != address(0), "0x0 Is not a valid owner"); emit OwnershipTransferred(_owner, _newOwner); _owner = _newOwner; } } // File: contracts/interfaces/IERC165.sol pragma solidity ^0.5.7; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceID) external view returns (bool); } // File: contracts/core/diaspore/interfaces/RateOracle.sol pragma solidity ^0.5.7; /** @dev Defines the interface of a standard Diaspore RCN Oracle, The contract should also implement it's ERC165 interface: 0xa265d8e0 @notice Each oracle can only support one currency @author Agustin Aguilar */ contract RateOracle is IERC165 { uint256 public constant VERSION = 5; bytes4 internal constant RATE_ORACLE_INTERFACE = 0xa265d8e0; constructor() internal {} /** 3 or 4 letters symbol of the currency, Ej: ETH */ function symbol() external view returns (string memory); /** Descriptive name of the currency, Ej: Ethereum */ function name() external view returns (string memory); /** The number of decimals of the currency represented by this Oracle, it should be the most common number of decimal places */ function decimals() external view returns (uint256); /** The base token on which the sample is returned should be the RCN Token address. */ function token() external view returns (address); /** The currency symbol encoded on a UTF-8 Hex */ function currency() external view returns (bytes32); /** The name of the Individual or Company in charge of this Oracle */ function maintainer() external view returns (string memory); /** Returns the url where the oracle exposes a valid "oracleData" if needed */ function url() external view returns (string memory); /** Returns a sample on how many token() are equals to how many currency() */ function readSample(bytes calldata _data) external returns (uint256 _tokens, uint256 _equivalent); } // File: contracts/commons/ERC165.sol pragma solidity ^0.5.7; /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is IERC165 { bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor() internal { _registerInterface(_InterfaceId_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev internal method for registering an interface */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff, "Can't register 0xffffffff"); _supportedInterfaces[interfaceId] = true; } } // File: contracts/core/basalt/utils/OwnableBasalt.sol pragma solidity ^0.5.7; contract OwnableBasalt { address public owner; modifier onlyOwner() { require(msg.sender == owner, "The owner should be the sender"); _; } constructor() public { owner = msg.sender; } /** @dev Transfers the ownership of the contract. @param _to Address of the new owner */ function transferTo(address _to) public onlyOwner returns (bool) { require(_to != address(0), "0x0 Is not a valid owner"); owner = _to; return true; } } // File: contracts/core/basalt/interfaces/Oracle.sol pragma solidity ^0.5.7; /** @dev Defines the interface of a standard RCN oracle. The oracle is an agent in the RCN network that supplies a convertion rate between RCN and any other currency, it's primarily used by the exchange but could be used by any other agent. */ contract Oracle is OwnableBasalt { uint256 public constant VERSION = 4; event NewSymbol(bytes32 _currency); mapping(bytes32 => bool) public supported; bytes32[] public currencies; /** @dev Returns the url where the oracle exposes a valid "oracleData" if needed */ function url() public view returns (string memory); /** @dev Returns a valid convertion rate from the currency given to RCN @param symbol Symbol of the currency @param data Generic data field, could be used for off-chain signing */ function getRate(bytes32 symbol, bytes memory data) public returns (uint256 rate, uint256 decimals); /** @dev Adds a currency to the oracle, once added it cannot be removed @param ticker Symbol of the currency @return if the creation was done successfully */ function addCurrency(string memory ticker) public onlyOwner returns (bool) { bytes32 currency = encodeCurrency(ticker); emit NewSymbol(currency); supported[currency] = true; currencies.push(currency); return true; } /** @return the currency encoded as a bytes32 */ function encodeCurrency(string memory currency) public pure returns (bytes32 o) { require(bytes(currency).length <= 32); assembly { o := mload(add(currency, 32)) } } /** @return the currency string from a encoded bytes32 */ function decodeCurrency(bytes32 b) public pure returns (string memory o) { uint256 ns = 256; while (true) { if (ns == 0 || (b<