contract PriceFeedProvider is IPriceFeedProvider {
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    address admin;

    mapping(uint8 => address) private priceFeeds;

    constructor() {
        admin = msg.sender;
    }

    /**
     * Returns the latest price for a price feed.
     * It reverts if the feed id is invalid: there was no price feed address provided for the given id yet
     */
    function getLatestPrice(uint8 _priceFeedId)
        external
        view
        override
        returns (int256)
    {
        require(
            priceFeeds[_priceFeedId] != address(0),
            "invalid price feed id"
        );
        AggregatorV3Interface priceFeed;
        priceFeed = AggregatorV3Interface(priceFeeds[_priceFeedId]);
        (, int256 price, , , ) = priceFeed.latestRoundData();
        return price;
    }

    /**
     * Inserts or updates the price feed address for the given price feed id
     */
    function upsertFeed(uint8 _id, address _dataFeedAddress) external {
        require(msg.sender == admin, "admin only");
        priceFeeds[_id] = _dataFeedAddress;
    }

    function transferOwnership(address newAdmin) external {
        require(msg.sender == admin, "admin only");
        emit OwnershipTransferred(admin, newAdmin);
        admin = newAdmin;
    }
}
function getLatestPrice(uint8 _priceFeedId)
    external
    view
    override
    returns (int256)
{
    require(
        priceFeeds[_priceFeedId] != address(0),
        "invalid price feed id"
    );
    AggregatorV3Interface priceFeed;
    priceFeed = AggregatorV3Interface(priceFeeds[_priceFeedId]);
    (, int256 price, , , ) = priceFeed.latestRoundData();
    return price;
}

/**
 * Returns the latest price for a price feed.
 * It reverts if the feed id is invalid: there was no price feed address provided for the given id yet
 */