// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "../interfaces/periphery/IOracle.sol";
import "../features/UsingStalePeriod.sol";

/**
 * @title Chainlink oracle
 */
contract ChainlinkOracle is IOracle, UsingStalePeriod {
    constructor(uint256 stalePeriod_) UsingStalePeriod(stalePeriod_) {}

    /// @inheritdoc IOracle
    function getPriceInUsd(address token_) public view virtual returns (uint256 _priceInUsd) {
        uint256 _lastUpdatedAt;
        (_priceInUsd, _lastUpdatedAt) = addressProvider.providersAggregator().getPriceInUsd(
            DataTypes.Provider.CHAINLINK,
            token_
        );
        require(_priceInUsd > 0 && !_priceIsStale(_lastUpdatedAt), "price-invalid");
    }

    /// @inheritdoc IOracle
    function quote(
        address tokenIn_,
        address tokenOut_,
        uint256 amountIn_
    ) public view virtual returns (uint256 _amountOut) {
        uint256 _lastUpdatedAt;
        (_amountOut, _lastUpdatedAt) = addressProvider.providersAggregator().quote(
            DataTypes.Provider.CHAINLINK,
            tokenIn_,
            tokenOut_,
            amountIn_
        );
        require(_amountOut > 0 && !_priceIsStale(_lastUpdatedAt), "price-invalid");
    }

    /// @inheritdoc IOracle
    function quoteTokenToUsd(address token_, uint256 amountIn_) public view virtual returns (uint256 _amountOut) {
        uint256 _lastUpdatedAt;
        (_amountOut, _lastUpdatedAt) = addressProvider.providersAggregator().quoteTokenToUsd(
            DataTypes.Provider.CHAINLINK,
            token_,
            amountIn_
        );
        require(_amountOut > 0 && !_priceIsStale(_lastUpdatedAt), "price-invalid");
    }

    /// @inheritdoc IOracle
    function quoteUsdToToken(address token_, uint256 amountIn_) public view virtual returns (uint256 _amountOut) {
        uint256 _lastUpdatedAt;
        (_amountOut, _lastUpdatedAt) = addressProvider.providersAggregator().quoteUsdToToken(
            DataTypes.Provider.CHAINLINK,
            token_,
            amountIn_
        );
        require(_amountOut > 0 && !_priceIsStale(_lastUpdatedAt), "price-invalid");
    }
}
[{"inputs":[{"internalType":"uint256","name":"stalePeriod_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldStalePeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newStalePeriod","type":"uint256"}],"name":"StalePeriodUpdated","type":"event"},{"inputs":[],"name":"addressProvider","outputs":[{"internalType":"contract IAddressProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"name":"getPriceInUsd","outputs":[{"internalType":"uint256","name":"_priceInUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn_","type":"address"},{"internalType":"address","name":"tokenOut_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"quoteTokenToUsd","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"}],"name":"quoteUsdToToken","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stalePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stalePeriod_","type":"uint256"}],"name":"updateStalePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"}]