Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xAe6B44ebdd005669B410524eC076424A7308e9e1
Balance 0 ETH
Nonce 1
Code Size 3905 bytes
Indexed Transactions Index loading...
External Etherscan · Sourcify

Contract Bytecode

3905 bytes
0x608060405234801561000f575f80fd5b506004361061012f575f3560e01c8063a0dcdc68116100ad578063d29dba911161007d578063ebbc496511610063578063ebbc49651461030e578063ebdac45814610316578063feaf968c1461033d575f80fd5b8063d29dba91146102db578063e30c3978146102ee575f80fd5b8063a0dcdc6814610279578063acdb31f61461028c578063c42069ec1461029f578063d116c081146102b4575f80fd5b8063620518d8116101025780638a0531a6116100e85780638a0531a6146101cf5780638da5cb5b1461020d578063a06a720714610252575f80fd5b8063620518d8146101b15780637284e416146101ba575f80fd5b80630d73ed7b146101335780631af214a81461015b578063313ce5671461019457806350d25bcd1461019b575b5f80fd5b610146610141366004610aa1565b61037c565b60405190151581526020015b60405180910390f35b6101827f000000000000000000000000000000000000000000000000000000000000000881565b60405160ff9091168152602001610152565b6012610182565b6101a36104ee565b604051908152602001610152565b6101a360035481565b6101c2610503565b6040516101529190610acf565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ab7f623fb2f6fea6601d4350fa0e2290663c28fc161515610146565b60015461022d9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610152565b6101827f000000000000000000000000000000000000000000000000000000000000000881565b6101a3610287366004610b38565b61058e565b61014661029a366004610b60565b6105f5565b6102b26102ad366004610b80565b610642565b005b61022d7f000000000000000000000000f4030086522a5beea4988f8ca5b36dbc97bee88c81565b6102b26102e9366004610ba2565b61070f565b60025461022d9073ffffffffffffffffffffffffffffffffffffffff1681565b6102b2610795565b61022d7f000000000000000000000000ab7f623fb2f6fea6601d4350fa0e2290663c28fc81565b610345610862565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a001610152565b5f808273ffffffffffffffffffffffffffffffffffffffff1663245a7bfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103eb9190610bb9565b90505f8173ffffffffffffffffffffffffffffffffffffffff166370da2f676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610437573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061045b9190610bd4565b90505f8273ffffffffffffffffffffffffffffffffffffffff166322adbc786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104cb9190610bd4565b9050858260170b1315806104e25750858160170b12155b93505050505b92915050565b5f806104f8610862565b509195945050505050565b5f805461050f90610bf4565b80601f016020809104026020016040519081016040528092919081815260200182805461053b90610bf4565b80156105865780601f1061055d57610100808354040283529160200191610586565b820191905f5260205f20905b81548152906001019060200180831161056957829003601f168201915b505050505081565b5f60128260ff1611156105c2576105a6601283610c72565b6105b190600a610da9565b6105bb9084610db7565b90506104e8565b60128260ff1610156105ee576105d9826012610c72565b6105e490600a610da9565b6105bb9084610e43565b5090919050565b5f8042600354846106069190610e8e565b109050808061063a575061063a847f000000000000000000000000f4030086522a5beea4988f8ca5b36dbc97bee88c61037c565b949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4f6e6c79206f776e65720000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610790576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4f6e6c79206f776e65720000000000000000000000000000000000000000000060448201526064016106bf565b600355565b60025473ffffffffffffffffffffffffffffffffffffffff163314610816576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792070656e64696e67206f776e6572000000000000000000000000000060448201526064016106bf565b60028054600180547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b5f805f805f7f000000000000000000000000f4030086522a5beea4988f8ca5b36dbc97bee88c73ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156108d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108f49190610ebf565b93985091965094509250905061090a84836105f5565b15610a495773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ab7f623fb2f6fea6601d4350fa0e2290663c28fc1615610a15577f000000000000000000000000ab7f623fb2f6fea6601d4350fa0e2290663c28fc73ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156109b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d89190610ebf565b939850919650945092509050610a0e847f000000000000000000000000000000000000000000000000000000000000000861058e565b9350610a76565b610a3f847f000000000000000000000000000000000000000000000000000000000000000861058e565b93505f9150610a76565b610a73847f000000000000000000000000000000000000000000000000000000000000000861058e565b93505b9091929394565b73ffffffffffffffffffffffffffffffffffffffff81168114610a9e575f80fd5b50565b5f8060408385031215610ab2575f80fd5b823591506020830135610ac481610a7d565b809150509250929050565b5f6020808352835180828501525f5b81811015610afa57858101830151858201604001528201610ade565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b5f8060408385031215610b49575f80fd5b82359150602083013560ff81168114610ac4575f80fd5b5f8060408385031215610b71575f80fd5b50508035926020909101359150565b5f60208284031215610b90575f80fd5b8135610b9b81610a7d565b9392505050565b5f60208284031215610bb2575f80fd5b5035919050565b5f60208284031215610bc9575f80fd5b8151610b9b81610a7d565b5f60208284031215610be4575f80fd5b81518060170b8114610b9b575f80fd5b600181811c90821680610c0857607f821691505b602082108103610c3f577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60ff82811682821603908111156104e8576104e8610c45565b600181815b80851115610ce457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610cca57610cca610c45565b80851615610cd757918102915b93841c9390800290610c90565b509250929050565b5f82610cfa575060016104e8565b81610d0657505f6104e8565b8160018114610d1c5760028114610d2657610d42565b60019150506104e8565b60ff841115610d3757610d37610c45565b50506001821b6104e8565b5060208310610133831016604e8410600b8410161715610d65575081810a6104e8565b610d6f8383610c8b565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610da157610da1610c45565b029392505050565b5f610b9b60ff841683610cec565b5f82610dea577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615610e3e57610e3e610c45565b500590565b8082025f82127f800000000000000000000000000000000000000000000000000000000000000084141615610e7a57610e7a610c45565b81810583148215176104e8576104e8610c45565b808201808211156104e8576104e8610c45565b805169ffffffffffffffffffff81168114610eba575f80fd5b919050565b5f805f805f60a08688031215610ed3575f80fd5b610edc86610ea1565b9450602086015193506040860151925060608601519150610eff60808701610ea1565b9050929550929590935056fea2646970667358221220b01e1a11dc2eb5f69abd821ffb2693a0947205b1b94a4f71e47a969ea3d15d1064736f6c63430008140033

Verified Source Code Full Match

Compiler: v0.8.20+commit.a1b79de6 EVM: shanghai Optimization: Yes (10000 runs)
ChainlinkBasePriceFeed.sol 162 lines
// 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;
    }
}
IChainlinkFeed.sol 30 lines
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);
}

Read Contract

assetToUsd 0xd116c081 → address
assetToUsdDecimals 0x1af214a8 → uint8
assetToUsdFallback 0xebdac458 → address
assetToUsdFallbackDecimals 0xa06a7207 → uint8
assetToUsdHeartbeat 0x620518d8 → uint256
decimals 0x313ce567 → uint8
description 0x7284e416 → string
hasFallback 0x8a0531a6 → bool
isPriceOutOfBounds 0x0d73ed7b → bool
isPriceStale 0xacdb31f6 → bool
latestAnswer 0x50d25bcd → int256
latestRoundData 0xfeaf968c → uint80, int256, uint256, uint256, uint80
normalizePrice 0xa0dcdc68 → int256
owner 0x8da5cb5b → address
pendingOwner 0xe30c3978 → address

Write Contract 3 functions

These functions modify contract state and require a wallet transaction to execute.

acceptOwner 0xebbc4965
No parameters
setHeartbeat 0xd29dba91
uint256 newHeartbeat
setPendingOwner 0xc42069ec
address newPendingOwner

Recent Transactions

Transaction index is loading. Only unfinalized transactions are shown while the index starts up.