Attention: Follow the examples carefully. It is recommended that you first test and deploy your code on Testnet before using the Pricing Sylo on Mainnet.

The Oracle contract is one half of a pricing system that allows users to request up-to-date token price data. The Pricing Sylo employs a hybrid on-chain/off-chain architecture through the Oracle contract and Pricing Daemon. The Pricing Daemon aggregates token data from multiple sources and relays that information through the Oracle contract. To get accurate price data users will request the Pricing Daemon’s service via the Oracle contract and pay in SYLO token. The price data is then written on-chain to the Oracle contract and becomes widely available for all those who require it. However, as time passes this data will become dated and need updating.

Core Functionality

The Oracle contract has three main functions:

  • Accepts token price requests from users who have deposited SYLO tokens
  • Allows authorised responders (Pricing Daemon) to provide price data for those requests
  • Maintains a record of the latest price for each token

User Flow

  1. User deposits SYLO tokens using the deposit function

Note that this requires the Oracle contract to be approved for the specified amount before the call. When using the monitor both the approve and deposit functions will cost SYLOs, in addition to the actual deposit, so expect that the total SYLOs spent will slightly exceed the specific deposit amount.

  1. User requests price data with createRequest or createRequests (batch)
  2. Pricing Daemon will provide price data via createResponse
  3. Users can query responses with getResponse or get the latest token price via getLatestData

As per the interface below createRequest/createRequests will return the request ID/IDs that correlate to the most recent requests made. Users will find it useful to store this ID value to use as the argument to getResponse which will return the latest token data, as requested by the user.

Another useful aspect to note is that the latest requestId is publicly available. With this information, a user can take advantage of the latest token data without making a request themselves. Simply query for the latest requestId and include this value as the argument to getResponse.

Deployments

Pricing Sylo Monitor deployments can be found at the following URL.

Monitor URLChain
https://pricing.sylo.io/Mainnet

Pricing Sylo Oracle deployments can be found at the following contract addresses.

ChainContract address
Root Mainnet0xA1C10036F5398601f34d11F0be7Da26a8875Fb0d
Root Porcini (Testnet)0xf459E82138096876C25cd5fbc54c487476640619

To start using the Pricing Sylo, you will need to use the following interface.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

interface IOracle {
	struct Response {
		uint256 timestamp;
		uint256 value;
		uint256 requestId;
	}

	function createRequest(uint32 _token) external returns (uint256);

	function createRequests(uint32 _tokens) external returns (uint[] memory);

	function createResponse(uint256 _value, uint256 _requestId) external;

	function deposit(uint256 _amount, address _sender) external;

	function deposits(address) external view returns (uint256);

	function getPendingRequests(bool _breakOnProcessed) external view returns (uint256[] memory);

	function getRemainingRequests(address _address) external view returns (uint256);

	function getResponse(uint256 _requestId) external view returns (Response memory);

	function isProcessed(uint256 _requestId) external view returns (bool);

	function pricePerRequest() external view returns (uint256);

	function requestId() external view returns (uint256);
}

Here is an example of how to use the interface.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

import './IOracle.sol';

contract Example {
    IOracle public oracle;
    uint public lastData;

    constructor(IOracle _oracle) {
        oracle = _oracle;
    }

    function retrieveData(string calldata _token) external {
        oracle.createRequest(_token);
    }

    function useData(uint _requestId) external {
        IOracle.Response memory data = oracle.getResponse(_requestId);
        uint timestamp = data.timestamp;
        if (timestamp + 1 days >= block.timestamp) {
            // Do something with the timestamp
        }
        uint value = data.value;
        lastData = value;
    }
}

Data structures

  • Request: Stores token ID, timestamp of the block when the request was processed, and processed status
struct Request {
        uint32 tokenId;
        uint256 timestamp;
        bool processed;
    }
  • Response: Stores timestamp of the block when the response was processed, token price value, and request ID
struct Response {
        uint256 timestamp;
        uint256 value;
        uint256 requestId;
    }