🎓 A1Learner
🔍
0 of 48 lessons completed

Solidity Price Oracles

A price oracle is a contract that reports a price other contracts can read. Other contracts use that reported price instead of working out a price on their own.

A mock feed stores a price its owner sets

The owner sets the price and anyone can read it back. A reader who is not the owner cannot change it.

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

contract MockFeed {
    address public owner;
    uint256 public price;

    constructor() {
        owner = msg.sender;
    }

    function setPrice(uint256 newPrice) public {
        require(msg.sender == owner, "only owner sets price");
        price = newPrice;
    }
}

A consumer reads the price from the feed

The consumer holds the feed behind an interface and reads through it. The consumer never stores the price itself.

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

interface IFeed {
    function price() external view returns (uint256);
}

contract MockFeed {
    address public owner;
    uint256 public price;

    constructor() {
        owner = msg.sender;
    }

    function setPrice(uint256 newPrice) public {
        require(msg.sender == owner, "only owner sets price");
        price = newPrice;
    }
}

contract PriceReader {
    IFeed public feed;

    constructor(IFeed feedAddress) {
        feed = feedAddress;
    }

    function readPrice() public view returns (uint256) {
        return feed.price();
    }
}

An owner update changes what consumers read

The owner sets a new price and the same consumer reads the new value. No change to the consumer is needed.

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

interface IFeed {
    function price() external view returns (uint256);
}

contract MockFeed {
    address public owner;
    uint256 public price;

    constructor() {
        owner = msg.sender;
    }

    function setPrice(uint256 newPrice) public {
        require(msg.sender == owner, "only owner sets price");
        price = newPrice;
    }
}

contract PriceReader {
    IFeed public feed;

    constructor(IFeed feedAddress) {
        feed = feedAddress;
    }

    function readPrice() public view returns (uint256) {
        return feed.price();
    }
}

Example

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

interface IFeed {
    function price() external view returns (uint256);
}

contract MockFeed {
    address public owner;
    uint256 public price;

    constructor() {
        owner = msg.sender;
    }

    function setPrice(uint256 newPrice) public {
        require(msg.sender == owner, "only owner sets price");
        price = newPrice;
    }
}

contract PriceConverter {
    IFeed public feed;

    constructor(IFeed feedAddress) {
        feed = feedAddress;
    }

    function convert(uint256 amount) public view returns (uint256) {
        return amount * feed.price();
    }
}

Key points

  • Oracle: a contract that reports a price for other contracts to read.
  • Mock feed: a toy feed whose price its owner sets, used for teaching and testing.
  • Consumer: a contract that reads the price from an oracle.
  • Shared price: many consumers reading one oracle all see the same price.
  • Price update: the owner changes the stored price and later reads show the new price.

In this example, a mock feed holds a price and a converter reads that price through an interface. Converting an amount multiplies it by the current price, so an owner update changes every later conversion.

Note

a mock feed price is set by its owner, so it is trusted input and not a market price.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Remix IDE

Exercise

Who sets the price in a mock feed?