BLOG — Use cases

473 days ago

Build low latency oracles using Web3 Functions


  • Gelato can be used in conjunction with an off-chain pull-based Oracle Network like Redstone to create modular, customizable, low latency oracles that update more frequently than legacy oracle systems (e.g. prices on-chain every minute)
  • This creates new possibilities for building more efficient leveraged products like Float, derivative trading protocols, options, lending markets, and more!


Combining Redstone’s on-demand oracles and Gelato’s Web3 Functions is a game changing innovation that enables novel DeFi applications to process user transactions faster and create unmatched user experiences.

Redstone is an on-demand oracle that can query multiple data sources and sign data as an oracle network - but they don’t push data on-chain when it’s not needed. This results in more data being delivered at lower latency and higher security. To sum it up, users can simply grab the data they need and put it on-chain as needed, saving money on gas fees and enabling a higher refresh rate!

Users can integrate Web3 Functions to query data from an off-chain oracle like Redstone and push it on-chain, combining Redstone’s security with Gelato’s reliable computation & automation.

Why is data latency important?

Latency refers to the time delay for a data transfer. For oracles, latency refers to the time it takes for an oracle to update data on-chain. Having low latency is important as it ensures that a data point is fresh and that data is queried and pushed on-chain both quickly and regularly. Think of it like this: crypto asset prices fluctuate all the time, so users need to be able to access the most recent market data and ensure that it is quickly and consistently being refreshed.

Float Use Case

By integrating these solutions, Float is able to process user transactions 20x faster!

Float creates peer-to-peer markets where you can mint leveraged tokens in a single click. Leveraged tokens allow you to gain exposure to leveraged returns of popular crypto assets without the additional risks of liquidations, margin maintenance, and collateralized debt positions.

Corresponding pools of stablecoin collateral back the leveraged tokens minted through Float. To make sure that tokens can always be redeemed for 100% of their value, Float updates the balances of each of these pools at regular intervals, based on data received from price oracles. In their latest update, Float uses RedStone’s on-demand oracles to collect validated price data, which are called off-chain using Gelato’s Web3 Functions and then pushed on-chain every time certain conditions are met. As a result, Float is able to process updates 20x faster than before, creating a seamless user experience.

If you’re interested in learning more about this use case, check out our Twitter space with Float and Redstone.

Traditionally Chainlink Oracles have been using the request response model. This requires an on-chain transaction to emit an event that can trigger an off-chain Chainlink function, which then goes on to trigger another on-chain transaction. As you can probably guess, this flow creates a lot of latency and runs the risk of having outdated prices.

An alternative to this model is to have all prices pushed on-chain. However, although this helps with the previous problems, it is inefficient (it wastes gas) and doesn’t scale well, as not all prices written on-chain are needed.

Using pull-based Oracle solutions like RedStone paves the way for a hybrid solution, leveraging the best of both worlds, creating an off-chain, on-demand infrastructure that updates the prices with higher frequency than standard Oracles.

And finally, Gelato Web3 Functions offers the ability to customize the way that the protocol receives the prices, having on-chain prices updated on-demand and based on arbitrary on - and off-chain conditions.

Here you can see a Gelato Web3 Function showcasing how to update Redstone oracles on-chain if the price starts deviating by a pre-defined threshold:

Web3Function.onRun(async (context: Web3FunctionContext) => {
  const { userArgs, provider } = context;
  const oracleAddress = userArgs.oracleAddress as string;
  const oracle = new Contract(oracleAddress, ORACLE_ABI, provider);

  // Wrap contract with redstone data service
  const wrappedOracle = WrapperBuilder.wrap(oracle).usingDataService(
      dataServiceId: "redstone-rapid-demo",
      uniqueSignersCount: 1,
      dataFeeds: ["ETH"],
      disablePayloadsDryRun: true,

  // Retrieve stored & live prices
  const decimals = await wrappedOracle.decimals();
  const livePrice: BigNumber = await wrappedOracle.getLivePrice();
  const storedPrice: BigNumber = await wrappedOracle.getStoredPrice();
  console.log(`Live price: ${livePrice.toString()}`);
  console.log(`Stored price: ${storedPrice.toString()}`);

  // Check price deviation
  const deviation: BigNumber = await wrappedOracle.getPriceDeviation();
  const deviationPrct = (deviation.toNumber() / 10 ** decimals) * 100;
  console.log(`Deviation: ${deviationPrct.toFixed(2)}%`);

  // Only update price if deviation is above 0.2%
  const minDeviation = 0.2;
  if (deviationPrct < minDeviation) {
    return {
      canExec: false,
      message: `No update: price deviation too small`,

  // Craft transaction to update the price on-chain
  const { data } = await wrappedOracle.populateTransaction.updatePrice();
  return {
    canExec: true,
    callData: data,

And the RedstoneOracle smart contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@redstone-finance/evm-connector/contracts/data-services/RapidDemoConsumerBase.sol";

contract RedstoneOracle is RapidDemoConsumerBase {
    uint8 private immutable _decimals = 8;
    uint256 private _price = 0;

    function decimals() external pure returns (uint8) {
        return _decimals;

    function getStoredPrice() external view returns (uint256) {
        return _price;

     * Use storage-less approach to query in memory price
     * See:
     * @return uint256 price.
    function getLivePrice() public view returns (uint256) {
        // Extract and verify price using redstone connector
        return getOracleNumericValueFromTxMsg(bytes32("ETH"));

    function _computeDeviation(
        uint256 newPrice,
        uint256 oldPrice
    ) internal pure returns (uint) {
        if (oldPrice == 0) {
            return 1 * 10 ** _decimals;
        } else if (newPrice > oldPrice) {
            return ((newPrice - oldPrice) * 10 ** _decimals) / oldPrice;
        } else {
            return ((oldPrice - newPrice) * 10 ** _decimals) / oldPrice;

    function getPriceDeviation() external view returns (uint) {
        return _computeDeviation(getLivePrice(), _price);

    function updatePrice() public {
        _price = getLivePrice();

About Gelato

Gelato is a Web3 Cloud Platform empowering developers to create automated, gasless, and off-chain-aware Layer 2 chains and smart contracts. Over 400 web3 projects rely on Gelato for years to facilitate millions of transactions in DeFi, NFTs, and gaming.

  • Gelato RaaS: Deploy your own tailor-made ZK or OP L2 chains in a single click with native Account Abstraction and all Gelato middleware baked in.

  • Web3 Functions: Connect your smart contracts to off-chain data & computation by running decentralized cloud functions.

  • Automate: Automate your smart contracts by executing transactions automatically in a reliable, developer-friendly & decentralized manner.

  • Relay: Give your users access to reliable, robust, and scalable gasless transactions via a simple-to-use API.

  • Account Abstraction SDK: Gelato has partnered with Safe, to build a fully-fledged Account Abstraction SDK, combining Gelato's industry's best gasless transaction capabilities, with the industry's most secure smart contract wallet.

Subscribe to our newsletter and turn on your Twitter notifications to get the most recent updates about the Gelato ecosystem! If you are interested in being part of the Gelato team and building the future of the Internet browse the open positions and apply here.