Why DeFi Protocols Should Migrate from Push Oracles to Pull Oracles: A Case for the Pyth Network
Tags: oracle, defi, blockchain, web3
Published: 2024-06-28 15:14:43

##Introduction

In the dynamic world of decentralized finance (DeFi), oracles play a crucial role in bridging the gap between blockchain systems and real-world data. With the rapid evolution of DeFi, the need for accurate, timely, and reliable data has never been more critical. Traditionally, push oracles have been the go-to solution, but the emergence of pull oracles, exemplified by the Pyth Network, presents a compelling case for a paradigm shift. This article explores why DeFi protocols should consider migrating from push oracles to pull oracles, supported by quantitative evidence and real-world examples.

##Understanding Oracles in DeFi

Oracles are essential components in the DeFi ecosystem, enabling smart contracts to interact with and process external data. They ensure that blockchain applications can access off-chain information such as asset prices, weather conditions, and sports scores, thereby expanding the functionality and applicability of decentralized applications (dApps). Accurate data is paramount, as inaccuracies can lead to financial losses, security vulnerabilities, and diminished user trust.

##Push Oracles: An Overiew

Push oracles operate by periodically updating on-chain prices based on predefined conditions. These updates are executed by a set of permissioned operators who commit to a specific update frequency or price movement threshold. Examples of push oracle providers include Chainlink and Band Protocol. While push oracles offer advantages such as automated updates and established market presence, they also have notable limitations. These include potential inefficiencies due to unnecessary updates, higher costs, and the risk of data manipulation by malicious operators.

##Pull Oracles: A New Paradigm

Pull oracles, in contrast, update on-chain prices only when requested. This model introduces greater flexibility and efficiency, as updates are triggered by user demand rather than a fixed schedule. The Pyth Network exemplifies this approach, allowing anyone to permissionlessly update the on-chain price by requesting the latest data from an off-chain service. This method reduces unnecessary updates, lowers costs, and enhances data accuracy.

##Case Study: _Pyth Network_

The Pyth Network stands out as a leading pull oracle provider, delivering real-time asset price data with high fidelity. Launched in April 2021, Pyth has rapidly grown to offer over 500 low-latency price feeds across various asset classes, including digital assets, FX, ETFs, equities, and commodities. The network comprises major exchanges, market makers, and financial services providers, ensuring a robust and reliable data stream. Quantitative analysis reveals that Pyth's pull oracle design significantly reduces costs and improves data accuracy compared to traditional push oracles.


##Why DeFi Protocols should migrate to Pull Oracles

1. **Improved Data Accuracy and Reliability:** Pull oracles provide data on demand, ensuring that information is up-to-ate and relevant when needed. This reduces the likelihood of using outdated or incorrect data in smart contracts.

2. **Enhanced Security and Fraud Prevention:** By decentralizing the data update process and allowing anyone to request updates, pull oracles mitigate the risk of data manipulation and centralization vulnerabilities.

3. **Cost Efficiency and Resource Optimization:** Pull oracles eliminate unnecessary updates, reducing transaction fees and resource consumption. This makes them a more economical choice for DeFi protocols.

4. **Flexibility and Scalability:** The on-demand nature of pull oracles allows them to scale more efficiently with the growth of DeFi applications, adapting to varying data requirements without overburdening the network.


##Quantitative Evidence and Analysis

Data from the Pyth Network demonstrates a marked improvement in cost efficiency and data accuracy. For instance, Pyth's model shows a reduction in unnecessary updates by up to 50%, leading to significant savings in transaction fees. Additionally, the real-time data provided by Pyth ensures more accurate pricing, which is crucial for high-frequency trading and other time-sensitive applications.

##Challenges and Considerations


Despite the advantages, migrating from push to pull oracles presents certain challenges. These include technical complexities in integrating pull oracles into existing systems, potential delays in data retrieval, and the need for robust verification mechanisms to ensure data authenticity. DeFi protocols must carefully evaluate these factors and implement strategies to address them, such as hybrid models combining the strengths of both oracle types.


#An example to understand this much better - 

This will involve fetching the latest price from Pyth's off-chain service and then submitting this price to an on-chain smart contract.


```
import requests
from web3 import Web3

PYTH_API_URL = "https://pyth.network/api/latest_price"
INFURA_URL = "https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID"

# Smart contract address and ABI
CONTRACT_ADDRESS = "0xYourContractAddress"
CONTRACT_ABI = [
    # Add your contract's ABI here
]

# Ethereum account details
ACCOUNT_ADDRESS = "0xYourAccountAddress"
PRIVATE_KEY = "your_private_key"

# List of assets to fetch
assets = ["BTC/USD", "ETH/USD", "SOL/USD"]

def fetch_price(asset):
    try:
        response = requests.get(f"{PYTH_API_URL}?symbol={asset}")
        if response.status_code == 200:
            data = response.json()
            return data['price']
        else:
            print(f"Failed to fetch price for {asset}. Status code: {response.status_code}")
            return None
    except Exception as e:
        print(f"An error occurred while fetching price for {asset}: {e}")
        return None

def fetch_prices(assets):
    prices = {}
    for asset in assets:
        price = fetch_price(asset)
        if price is not None:
            prices[asset] = price
    return prices

def submit_price_to_contract(web3, contract, asset, price):
    try:
        nonce = web3.eth.get_transaction_count(ACCOUNT_ADDRESS)
        transaction = contract.functions.updatePrice(asset, price).build_transaction({
            'from': ACCOUNT_ADDRESS,
            'nonce': nonce,
            'gas': 2000000,
            'gasPrice': web3.toWei('50', 'gwei')
        })
        signed_txn = web3.eth.account.sign_transaction(transaction, private_key=PRIVATE_KEY)
        tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
        tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
        print(f"Submitted price for {asset}: {price}. Transaction hash: {tx_hash.hex()}")
        return tx_receipt
    except Exception as e:
        print(f"An error occurred while submitting price for {asset}: {e}")
        return None

def main():
    # Connect to Ethereum node
    web3 = Web3(Web3.HTTPProvider(INFURA_URL))
    if not web3.isConnected():
        print("Failed to connect to Ethereum node. Exiting.")
        return

    # Instantiate smart contract
    contract = web3.eth.contract(address=CONTRACT_ADDRESS, abi=CONTRACT_ABI)

    # Fetch prices for all assets
    prices = fetch_prices(assets)
    if not prices:
        print("No prices fetched. Exiting.")
        return

    # Submit prices to the smart contract
    for asset, price in prices.items():
        submit_price_to_contract(web3, contract, asset, price)

if __name__ == "__main__":
    main()
```


1. `fetch_price(asset)`: Fetches the latest price of a single asset from Pyth Network's API.

2. `submit_price_to_contract(web3, contract, asset,price)`: Submits the fetched price to the smart contract on Ethereum.