ETH Price: $3,178.74 (-5.16%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x5cbe8F3D...15C35EB51
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
ChainlinkBasePriceFeed

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 10000 runs

Other Settings:
shanghai EvmVersion
File 1 of 2 : ChainlinkBasePriceFeed.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "src/interfaces/IChainlinkFeed.sol";

interface IAggregator {
    function maxAnswer() external view returns (int192);

    function minAnswer() external view returns (int192);
}

// Standard feed component for FiRM price feeds
/// @dev Always return the feed price in 18 decimals
contract ChainlinkBasePriceFeed {
    IChainlinkFeed public immutable assetToUsd;
    IChainlinkFeed public immutable assetToUsdFallback;
    uint8 public immutable assetToUsdDecimals;
    uint8 public immutable assetToUsdFallbackDecimals;
    string public description;

    address public owner;
    address public pendingOwner;

    uint256 public assetToUsdHeartbeat;

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner");
        _;
    }

    modifier onlyPendingOwner() {
        require(msg.sender == pendingOwner, "Only pending owner");
        _;
    }

    constructor(
        address _owner,
        address _assetToUsd,
        address _assetToUsdFallback,
        uint256 _assetToUsdHeartbeat
    ) {
        owner = _owner;
        assetToUsd = IChainlinkFeed(_assetToUsd);
        assetToUsdFallback = IChainlinkFeed(_assetToUsdFallback);
        assetToUsdHeartbeat = _assetToUsdHeartbeat;
        assetToUsdDecimals = IChainlinkFeed(_assetToUsd).decimals();
        uint8 fallbackDecimals = 0;
        if (address(assetToUsdFallback) != address(0)) {
            fallbackDecimals = assetToUsdFallback.decimals();
        }
        assetToUsdFallbackDecimals = fallbackDecimals;
        description = assetToUsd.description();
    }

    /**
     * @notice Retrieves the latest round data for the asset token price feed
     * @return roundId The round ID of the Chainlink price feed for the feed with the lowest updatedAt feed
     * @return usdPrice The latest asset price in USD with 18 decimals
     * @return startedAt The timestamp when the latest round of Chainlink price feed started of the lowest last updatedAt feed
     * @return updatedAt The lowest timestamp when either of the latest round of Chainlink price feed was updated
     * @return answeredInRound The round ID in which the answer was computed of the lowest updatedAt feed
     */
    function latestRoundData()
        public
        view
        returns (
            uint80 roundId,
            int256 usdPrice,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        )
    {
        (roundId, usdPrice, startedAt, updatedAt, answeredInRound) = assetToUsd
            .latestRoundData();

        if (isPriceStale(usdPrice, updatedAt)) {
            if (hasFallback()) {
                (
                    roundId,
                    usdPrice,
                    startedAt,
                    updatedAt,
                    answeredInRound
                ) = assetToUsdFallback.latestRoundData();
                usdPrice = normalizePrice(usdPrice, assetToUsdFallbackDecimals);
            } else {
                usdPrice = normalizePrice(usdPrice, assetToUsdDecimals);
                updatedAt = 0;
            }
        } else {
            usdPrice = normalizePrice(usdPrice, assetToUsdDecimals);
        }
    }

    /**
     * @notice Returns the latest price only
     * @dev Unlike chainlink oracles, the latestAnswer will always be the same as in the latestRoundData
     * @return int256 Returns the last finalized price of the chainlink oracle
     */
    function latestAnswer() external view returns (int256) {
        (, int256 latestPrice, , , ) = latestRoundData();
        return latestPrice;
    }

    /**
     * @notice Checks if a given price is out of the boundaries defined in the Chainlink aggregator.
     * @param price The price to be checked.
     * @param feed The Chainlink feed to retrieve the boundary information from.
     * @return bool Returns `true` if the price is out of bounds, otherwise `false`.
     */
    function isPriceOutOfBounds(
        int price,
        IChainlinkFeed feed
    ) public view returns (bool) {
        IAggregator aggregator = IAggregator(feed.aggregator());
        int192 max = aggregator.maxAnswer();
        int192 min = aggregator.minAnswer();
        return (max <= price || min >= price);
    }

    function isPriceStale(
        int256 price,
        uint256 updatedAt
    ) public view returns (bool) {
        bool stalePrice = updatedAt + assetToUsdHeartbeat < block.timestamp;
        return stalePrice || isPriceOutOfBounds(price, assetToUsd);
    }

    function hasFallback() public view returns (bool) {
        return address(assetToUsdFallback) != address(0);
    }

    function setHeartbeat(uint256 newHeartbeat) public onlyOwner {
        assetToUsdHeartbeat = newHeartbeat;
    }

    function setPendingOwner(address newPendingOwner) public onlyOwner {
        pendingOwner = newPendingOwner;
    }

    function acceptOwner() public onlyPendingOwner {
        owner = pendingOwner;
        pendingOwner = address(0);
    }

    function decimals() public pure returns (uint8) {
        return 18;
    }

    function normalizePrice(
        int256 price,
        uint8 feedDecimals
    ) public pure returns (int256) {
        if (feedDecimals > 18) {
            return price / int(10 ** (feedDecimals - 18));
        } else if (feedDecimals < 18) {
            return price * int(10 ** (18 - feedDecimals));
        }
        return price;
    }
}

File 2 of 2 : IChainlinkFeed.sol
pragma solidity ^0.8.13;

interface IChainlinkFeed {
    function aggregator() external view returns (address aggregator);

    function decimals() external view returns (uint8 decimals);

    function latestRoundData()
        external
        view
        returns (
            uint80 roundId,
            int256 crvUsdPrice,
            uint256 startedAt,
            uint256 updatedAt,
            uint80 answeredInRound
        );

    function latestAnswer() external view returns (int256 price);

    function description() external view returns (string memory description);
}

interface IChainlinkBasePriceFeed is IChainlinkFeed {
    function assetToUsd() external view returns (IChainlinkFeed);

    function assetToUsdFallback() external view returns (IChainlinkFeed);

    function assetToUsdHeartbeat() external view returns (uint256 heartbeat);
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_assetToUsd","type":"address"},{"internalType":"address","name":"_assetToUsdFallback","type":"address"},{"internalType":"uint256","name":"_assetToUsdHeartbeat","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"acceptOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"assetToUsd","outputs":[{"internalType":"contract IChainlinkFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetToUsdDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetToUsdFallback","outputs":[{"internalType":"contract IChainlinkFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetToUsdFallbackDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetToUsdHeartbeat","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasFallback","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"price","type":"int256"},{"internalType":"contract IChainlinkFeed","name":"feed","type":"address"}],"name":"isPriceOutOfBounds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"price","type":"int256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"name":"isPriceStale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"usdPrice","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"price","type":"int256"},{"internalType":"uint8","name":"feedDecimals","type":"uint8"}],"name":"normalizePrice","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newHeartbeat","type":"uint256"}],"name":"setHeartbeat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingOwner","type":"address"}],"name":"setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x608060405234801561000f575f80fd5b506004361061012f575f3560e01c8063a0dcdc68116100ad578063d29dba911161007d578063ebbc496511610063578063ebbc49651461030e578063ebdac45814610316578063feaf968c1461033d575f80fd5b8063d29dba91146102db578063e30c3978146102ee575f80fd5b8063a0dcdc6814610279578063acdb31f61461028c578063c42069ec1461029f578063d116c081146102b4575f80fd5b8063620518d8116101025780638a0531a6116100e85780638a0531a6146101cf5780638da5cb5b1461020d578063a06a720714610252575f80fd5b8063620518d8146101b15780637284e416146101ba575f80fd5b80630d73ed7b146101335780631af214a81461015b578063313ce5671461019457806350d25bcd1461019b575b5f80fd5b610146610141366004610aa1565b61037c565b60405190151581526020015b60405180910390f35b6101827f000000000000000000000000000000000000000000000000000000000000000881565b60405160ff9091168152602001610152565b6012610182565b6101a36104ee565b604051908152602001610152565b6101a360035481565b6101c2610503565b6040516101529190610acf565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ab56a0ce51028ac286022bc8917bf326ef5f1701161515610146565b60015461022d9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610152565b6101827f000000000000000000000000000000000000000000000000000000000000001281565b6101a3610287366004610b38565b61058e565b61014661029a366004610b60565b6105f5565b6102b26102ad366004610b80565b610642565b005b61022d7f0000000000000000000000008fffffd4afb6115b954bd326cbe7b4ba576818f681565b6102b26102e9366004610ba2565b61070f565b60025461022d9073ffffffffffffffffffffffffffffffffffffffff1681565b6102b2610795565b61022d7f000000000000000000000000ab56a0ce51028ac286022bc8917bf326ef5f170181565b610345610862565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a001610152565b5f808273ffffffffffffffffffffffffffffffffffffffff1663245a7bfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103eb9190610bb9565b90505f8173ffffffffffffffffffffffffffffffffffffffff166370da2f676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610437573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061045b9190610bd4565b90505f8273ffffffffffffffffffffffffffffffffffffffff166322adbc786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104cb9190610bd4565b9050858260170b1315806104e25750858160170b12155b93505050505b92915050565b5f806104f8610862565b509195945050505050565b5f805461050f90610bf4565b80601f016020809104026020016040519081016040528092919081815260200182805461053b90610bf4565b80156105865780601f1061055d57610100808354040283529160200191610586565b820191905f5260205f20905b81548152906001019060200180831161056957829003601f168201915b505050505081565b5f60128260ff1611156105c2576105a6601283610c72565b6105b190600a610da9565b6105bb9084610db7565b90506104e8565b60128260ff1610156105ee576105d9826012610c72565b6105e490600a610da9565b6105bb9084610e43565b5090919050565b5f8042600354846106069190610e8e565b109050808061063a575061063a847f0000000000000000000000008fffffd4afb6115b954bd326cbe7b4ba576818f661037c565b949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4f6e6c79206f776e65720000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610790576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4f6e6c79206f776e65720000000000000000000000000000000000000000000060448201526064016106bf565b600355565b60025473ffffffffffffffffffffffffffffffffffffffff163314610816576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792070656e64696e67206f776e6572000000000000000000000000000060448201526064016106bf565b60028054600180547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b5f805f805f7f0000000000000000000000008fffffd4afb6115b954bd326cbe7b4ba576818f673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156108d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108f49190610ebf565b93985091965094509250905061090a84836105f5565b15610a495773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ab56a0ce51028ac286022bc8917bf326ef5f17011615610a15577f000000000000000000000000ab56a0ce51028ac286022bc8917bf326ef5f170173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156109b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d89190610ebf565b939850919650945092509050610a0e847f000000000000000000000000000000000000000000000000000000000000001261058e565b9350610a76565b610a3f847f000000000000000000000000000000000000000000000000000000000000000861058e565b93505f9150610a76565b610a73847f000000000000000000000000000000000000000000000000000000000000000861058e565b93505b9091929394565b73ffffffffffffffffffffffffffffffffffffffff81168114610a9e575f80fd5b50565b5f8060408385031215610ab2575f80fd5b823591506020830135610ac481610a7d565b809150509250929050565b5f6020808352835180828501525f5b81811015610afa57858101830151858201604001528201610ade565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b5f8060408385031215610b49575f80fd5b82359150602083013560ff81168114610ac4575f80fd5b5f8060408385031215610b71575f80fd5b50508035926020909101359150565b5f60208284031215610b90575f80fd5b8135610b9b81610a7d565b9392505050565b5f60208284031215610bb2575f80fd5b5035919050565b5f60208284031215610bc9575f80fd5b8151610b9b81610a7d565b5f60208284031215610be4575f80fd5b81518060170b8114610b9b575f80fd5b600181811c90821680610c0857607f821691505b602082108103610c3f577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60ff82811682821603908111156104e8576104e8610c45565b600181815b80851115610ce457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610cca57610cca610c45565b80851615610cd757918102915b93841c9390800290610c90565b509250929050565b5f82610cfa575060016104e8565b81610d0657505f6104e8565b8160018114610d1c5760028114610d2657610d42565b60019150506104e8565b60ff841115610d3757610d37610c45565b50506001821b6104e8565b5060208310610133831016604e8410600b8410161715610d65575081810a6104e8565b610d6f8383610c8b565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610da157610da1610c45565b029392505050565b5f610b9b60ff841683610cec565b5f82610dea577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615610e3e57610e3e610c45565b500590565b8082025f82127f800000000000000000000000000000000000000000000000000000000000000084141615610e7a57610e7a610c45565b81810583148215176104e8576104e8610c45565b808201808211156104e8576104e8610c45565b805169ffffffffffffffffffff81168114610eba575f80fd5b919050565b5f805f805f60a08688031215610ed3575f80fd5b610edc86610ea1565b9450602086015193506040860151925060608601519150610eff60808701610ea1565b9050929550929590935056fea264697066735822122077ba93bfb299cfc18788701be13e25db0be236e9d58b3f9adf519ea2677947d764736f6c63430008140033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.