ETH Price: $2,305.49 (-0.51%)

Contract

0xBc0131AA1FF58F628ceAcE15751F703E17E24C69
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x61012060198738422024-05-15 7:19:35126 days ago1715757575IN
 Create: PendlePTEzETH26DEC2024PriceProviderEth
0 ETH0.004171615.02398154

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PendlePTEzETH26DEC2024PriceProviderEth

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : PendlePTEzETH26DEC2024PriceProviderEth.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.13;

import "./PendleEzETHPriceProvider.sol";

contract PendlePTEzETH26DEC2024PriceProviderEth is PendleEzETHPriceProvider {
    address public constant EZETH = 0xbf5495Efe5DB9ce00f80364C8B423567e58d2110;

    constructor(IPriceProvidersRepository _priceProvidersRepository) PendlePriceProvider(
        0x66a1096C6366b2529274dF4f5D8247827fe4CEA8, // PT Oracle
        1800, // twap duration
        0xD8F12bCDE578c653014F27379a6114F67F0e445f, // PT Market
        _priceProvidersRepository,
        0xf7906F274c174A52d444175729E3fa98f9bde285, // PT Token
        "PT-ezETH-26DEC2024" // PT token symbol
    ) {}

    function ezETH() public pure override returns (address asset) {
        asset = EZETH;
    }
}

File 2 of 13 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 3 of 13 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 4 of 13 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 5 of 13 : IPriceProvider.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.7.6 <0.9.0;

/// @title Common interface for Silo Price Providers
interface IPriceProvider {
    /// @notice Returns "Time-Weighted Average Price" for an asset. Calculates TWAP price for quote/asset.
    /// It unifies all tokens decimal to 18, examples:
    /// - if asses == quote it returns 1e18
    /// - if asset is USDC and quote is ETH and ETH costs ~$3300 then it returns ~0.0003e18 WETH per 1 USDC
    /// @param _asset address of an asset for which to read price
    /// @return price of asses with 18 decimals, throws when pool is not ready yet to provide price
    function getPrice(address _asset) external view returns (uint256 price);

    /// @dev Informs if PriceProvider is setup for asset. It does not means PriceProvider can provide price right away.
    /// Some providers implementations need time to "build" buffer for TWAP price,
    /// so price may not be available yet but this method will return true.
    /// @param _asset asset in question
    /// @return TRUE if asset has been setup, otherwise false
    function assetSupported(address _asset) external view returns (bool);

    /// @notice Gets token address in which prices are quoted
    /// @return quoteToken address
    function quoteToken() external view returns (address);

    /// @notice Helper method that allows easily detects, if contract is PriceProvider
    /// @dev this can save us from simple human errors, in case we use invalid address
    /// but this should NOT be treated as security check
    /// @return always true
    function priceProviderPing() external pure returns (bytes4);
}

File 6 of 13 : IPriceProvidersRepository.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.7.6 <0.9.0;

import "./IPriceProvider.sol";

interface IPriceProvidersRepository {
    /// @notice Emitted when price provider is added
    /// @param newPriceProvider new price provider address
    event NewPriceProvider(IPriceProvider indexed newPriceProvider);

    /// @notice Emitted when price provider is removed
    /// @param priceProvider removed price provider address
    event PriceProviderRemoved(IPriceProvider indexed priceProvider);

    /// @notice Emitted when asset is assigned to price provider
    /// @param asset assigned asset   address
    /// @param priceProvider price provider address
    event PriceProviderForAsset(address indexed asset, IPriceProvider indexed priceProvider);

    /// @notice Register new price provider
    /// @param _priceProvider address of price provider
    function addPriceProvider(IPriceProvider _priceProvider) external;

    /// @notice Unregister price provider
    /// @param _priceProvider address of price provider to be removed
    function removePriceProvider(IPriceProvider _priceProvider) external;

    /// @notice Sets price provider for asset
    /// @dev Request for asset price is forwarded to the price provider assigned to that asset
    /// @param _asset address of an asset for which price provider will be used
    /// @param _priceProvider address of price provider
    function setPriceProviderForAsset(address _asset, IPriceProvider _priceProvider) external;

    /// @notice Returns "Time-Weighted Average Price" for an asset
    /// @param _asset address of an asset for which to read price
    /// @return price TWAP price of a token with 18 decimals
    function getPrice(address _asset) external view returns (uint256 price);

    /// @notice Gets price provider assigned to an asset
    /// @param _asset address of an asset for which to get price provider
    /// @return priceProvider address of price provider
    function priceProviders(address _asset) external view returns (IPriceProvider priceProvider);

    /// @notice Gets token address in which prices are quoted
    /// @return quoteToken address
    function quoteToken() external view returns (address);

    /// @notice Gets manager role address
    /// @return manager role address
    function manager() external view returns (address);

    /// @notice Checks if providers are available for an asset
    /// @param _asset asset address to check
    /// @return returns TRUE if price feed is ready, otherwise false
    function providersReadyForAsset(address _asset) external view returns (bool);

    /// @notice Returns true if address is a registered price provider
    /// @param _provider address of price provider to be removed
    /// @return true if address is a registered price provider, otherwise false
    function isPriceProvider(IPriceProvider _provider) external view returns (bool);

    /// @notice Gets number of price providers registered
    /// @return number of price providers registered
    function providersCount() external view returns (uint256);

    /// @notice Gets an array of price providers
    /// @return array of price providers
    function providerList() external view returns (address[] memory);

    /// @notice Sanity check function
    /// @return returns always TRUE
    function priceProvidersRepositoryPing() external pure returns (bytes4);
}

File 7 of 13 : Ping.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.7.6 <0.9.0;


library Ping {
    function pong(function() external pure returns(bytes4) pingFunction) internal pure returns (bool) {
        return pingFunction.address != address(0) && pingFunction.selector == pingFunction();
    }
}

File 8 of 13 : TokenHelper.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.13;

import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";


library TokenHelper {
    uint256 private constant _BYTES32_SIZE = 32;

    error TokenIsNotAContract();

    function assertAndGetDecimals(address _token) internal view returns (uint256) {
        (bool hasMetadata, bytes memory data) = _tokenMetadataCall(_token, abi.encodeCall(IERC20Metadata.decimals,()));

        // decimals() is optional in the ERC20 standard, so if metadata is not accessible
        // we assume there are no decimals and use 0.
        if (!hasMetadata) {
            return 0;
        }

        return abi.decode(data, (uint8));
    }

    /// @dev Returns the symbol for the provided ERC20 token.
    /// An empty string is returned if the call to the token didn't succeed.
    /// @param _token address of the token to get the symbol for
    /// @return assetSymbol the token symbol
    function symbol(address _token) internal view returns (string memory assetSymbol) {
        (bool hasMetadata, bytes memory data) = _tokenMetadataCall(_token, abi.encodeCall(IERC20Metadata.symbol,()));

        if (!hasMetadata || data.length == 0) {
            return "?";
        } else if (data.length == _BYTES32_SIZE) {
            return string(removeZeros(data));
        } else {
            return abi.decode(data, (string));
        }
    }

    /// @dev Removes bytes with value equal to 0 from the provided byte array.
    /// @param _data byte array from which to remove zeroes
    /// @return result byte array with zeroes removed 
    function removeZeros(bytes memory _data) internal pure returns (bytes memory result) {
        uint256 n = _data.length;

        unchecked {
            for (uint256 i; i < n; i++) {
                if (_data[i] == 0) continue;

                result = abi.encodePacked(result, _data[i]);
            }
        }
    }

    /// @dev Performs a staticcall to the token to get its metadata (symbol, decimals, name)
    function _tokenMetadataCall(address _token, bytes memory _data) private view returns(bool, bytes memory) {
        // We need to do this before the call, otherwise the call will succeed even for EOAs
        if (!Address.isContract(_token)) revert TokenIsNotAContract();

        (bool success, bytes memory result) = _token.staticcall(_data);

        // If the call reverted we assume the token doesn't follow the metadata extension
        if (!success) {
            return (false, "");
        }

        return (true, result);
    }
}

File 9 of 13 : IndividualPriceProvider.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.13;

import "./PriceProvider.sol";
import "./../lib/TokenHelper.sol";

/// @title IndividualPriceProvider
/// @notice IndividualPriceProvider
/// @custom:security-contact [email protected]
abstract contract IndividualPriceProvider is PriceProvider {
    // solhint-disable-next-line var-name-mixedcase
    address public immutable ASSET;

    error InvalidAssetAddress();

    constructor(
        IPriceProvidersRepository _priceProvidersRepository,
        address _asset,
        string memory _symbol
    ) PriceProvider(_priceProvidersRepository) {
        if (keccak256(abi.encode(TokenHelper.symbol(_asset))) != keccak256(abi.encode(_symbol))) {
            revert InvalidAssetAddress();
        }

        ASSET = _asset;
    }

    /// @notice Only ASSET token is supported, false otherwise.
    /// @param _asset address of an asset
    function assetSupported(address _asset) public view virtual override returns (bool) {
        return _asset == ASSET;
    }
}

File 10 of 13 : IPPtOracle.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.13;

interface IPPtOracle {
    event SetBlockCycleNumerator(uint16 newBlockCycleNumerator);

    function getPtToAssetRate(
        address market,
        uint32 duration
    ) external view returns (uint256 ptToAssetRate);

    function getPtToSyRate(
        address market,
        uint32 duration
    ) external view returns (uint256 ptToAssetRate);

    function getOracleState(
        address market,
        uint32 duration
    )
        external
        view
        returns (
            bool increaseCardinalityRequired,
            uint16 cardinalityRequired,
            bool oldestObservationSatisfied
        );
}

File 11 of 13 : PendleEzETHPriceProvider.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.13;

import "./PendlePriceProvider.sol";

abstract contract PendleEzETHPriceProvider is PendlePriceProvider {
    function getPrice(address _asset) public view virtual returns (uint256 price) {
        if (!assetSupported(_asset)) revert AssetNotSupported();

        // Pendle PT-ezETH-..../ezETH conversion rate
        uint256 ratePRtoEZETH = getPtToSyRate(twapDuration);

        // RedStone ezETH/ETH conversion rate
        uint256 rateEZETHtoETH = priceProvidersRepository.getPrice(ezETH());

        price = ratePRtoEZETH * rateEZETHtoETH;
        unchecked { price = price / 1e18; }

        // Zero price is unacceptable
        if (price == 0) revert ZeroPrice();
    }

    function ezETH() public pure virtual returns (address asset) {}
}

File 12 of 13 : PendlePriceProvider.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.13;

import "../IndividualPriceProvider.sol";
import "./interfaces/IPPtOracle.sol";

/// @title Pendle token price provider
/// @dev https://docs.pendle.finance/Developers/Integration/PTOracle
abstract contract PendlePriceProvider is IndividualPriceProvider {
    // solhint-disable
    address public immutable PT_ORACLE;
    address public immutable MARKET;
    // solhint-enable

    uint32 public twapDuration;

    event TwapDurationUpdated(uint256 twapDuration);

    error OracleNotReady(bool increaseCardinalityRequired, bool oldestObservationSatisfied);
    error AssetNotSupported();
    error ZeroPrice();

    constructor(
        address _ptOracle,
        uint32 _twapDuration,
        address _market,
        IPriceProvidersRepository _priceProvidersRepository,
        address _asset,
        string memory _symbol
    ) IndividualPriceProvider(
        _priceProvidersRepository,
        _asset,
        _symbol
    )
    {
        PT_ORACLE = _ptOracle;
        MARKET = _market;

        _updateTwapDuration(_twapDuration);
    }

    /// @notice Allow's to update a TWAP duration
    /// @param _newTwapDuration The new TWAP duration that should be used in the price provider
    function setTwapDuration(uint32 _newTwapDuration) external virtual onlyManager() {
        _updateTwapDuration(_newTwapDuration);
    }

    /// @notice Resolve oracle state
    function getOracleState(uint32 _newTwapDuration)
        public
        view
        virtual
        returns (bool increaseCardinalityRequired, bool oldestObservationSatisfied)
    {
        (increaseCardinalityRequired, ,oldestObservationSatisfied) = IPPtOracle(PT_ORACLE)
            .getOracleState(MARKET, _newTwapDuration);
    }

    /// @notice Get PT to asset rate
    function getPtToSyRate(uint32 _twapDuration) public view virtual returns (uint256 ratePRtoEETH) {
        ratePRtoEETH = IPPtOracle(PT_ORACLE).getPtToSyRate(MARKET, _twapDuration);
    }

    /// @notice Update a TWAP duration
    /// @param _newTwapDuration The new TWAP duration that should be used in the price provider
    function _updateTwapDuration(uint32 _newTwapDuration) internal {
        (bool increaseCardinalityRequired, bool oldestObservationSatisfied) = getOracleState(_newTwapDuration);

        if (increaseCardinalityRequired || !oldestObservationSatisfied) {
            revert OracleNotReady(increaseCardinalityRequired, oldestObservationSatisfied);
        }

        twapDuration = _newTwapDuration;

        emit TwapDurationUpdated(_newTwapDuration);
    }
}

File 13 of 13 : PriceProvider.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.7.6 <0.9.0;

import "../lib/Ping.sol";
import "../interfaces/IPriceProvider.sol";
import "../interfaces/IPriceProvidersRepository.sol";

/// @title PriceProvider
/// @notice Abstract PriceProvider contract, parent of all PriceProviders
/// @dev Price provider is a contract that directly integrates with a price source, ie. a DEX or alternative system
/// like Chainlink to calculate TWAP prices for assets. Each price provider should support a single price source
/// and multiple assets.
abstract contract PriceProvider is IPriceProvider {
    /// @notice PriceProvidersRepository address
    IPriceProvidersRepository public immutable priceProvidersRepository;

    /// @notice Token address which prices are quoted in. Must be the same as PriceProvidersRepository.quoteToken
    address public immutable override quoteToken;

    modifier onlyManager() {
        if (priceProvidersRepository.manager() != msg.sender) revert("OnlyManager");
        _;
    }

    /// @param _priceProvidersRepository address of PriceProvidersRepository
    constructor(IPriceProvidersRepository _priceProvidersRepository) {
        if (
            !Ping.pong(_priceProvidersRepository.priceProvidersRepositoryPing)            
        ) {
            revert("InvalidPriceProviderRepository");
        }

        priceProvidersRepository = _priceProvidersRepository;
        quoteToken = _priceProvidersRepository.quoteToken();
    }

    /// @inheritdoc IPriceProvider
    function priceProviderPing() external pure override returns (bytes4) {
        return this.priceProviderPing.selector;
    }

    function _revertBytes(bytes memory _errMsg, string memory _customErr) internal pure {
        if (_errMsg.length > 0) {
            assembly { // solhint-disable-line no-inline-assembly
                revert(add(32, _errMsg), mload(_errMsg))
            }
        }

        revert(_customErr);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IPriceProvidersRepository","name":"_priceProvidersRepository","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AssetNotSupported","type":"error"},{"inputs":[],"name":"InvalidAssetAddress","type":"error"},{"inputs":[{"internalType":"bool","name":"increaseCardinalityRequired","type":"bool"},{"internalType":"bool","name":"oldestObservationSatisfied","type":"bool"}],"name":"OracleNotReady","type":"error"},{"inputs":[],"name":"TokenIsNotAContract","type":"error"},{"inputs":[],"name":"ZeroPrice","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"twapDuration","type":"uint256"}],"name":"TwapDurationUpdated","type":"event"},{"inputs":[],"name":"ASSET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EZETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MARKET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PT_ORACLE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"assetSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ezETH","outputs":[{"internalType":"address","name":"asset","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_newTwapDuration","type":"uint32"}],"name":"getOracleState","outputs":[{"internalType":"bool","name":"increaseCardinalityRequired","type":"bool"},{"internalType":"bool","name":"oldestObservationSatisfied","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_twapDuration","type":"uint32"}],"name":"getPtToSyRate","outputs":[{"internalType":"uint256","name":"ratePRtoEETH","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceProviderPing","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"priceProvidersRepository","outputs":[{"internalType":"contract IPriceProvidersRepository","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_newTwapDuration","type":"uint32"}],"name":"setTwapDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twapDuration","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"}]

6101206040523480156200001257600080fd5b506040516200157a3803806200157a833981016040819052620000359162000633565b7366a1096c6366b2529274df4f5d8247827fe4cea861070873d8f12bcde578c653014f27379a6114f67f0e445f8373f7906f274c174a52d444175729e3fa98f9bde2856040518060400160405280601281526020017114150b595e9155120b4c8d911150cc8c0c8d60721b81525082828282620000cb816001600160a01b031663eec3e6a76200025560201b620006b91760201c565b6200011d5760405162461bcd60e51b815260206004820152601e60248201527f496e76616c6964507269636550726f76696465725265706f7369746f7279000060448201526064015b60405180910390fd5b6001600160a01b038116608081905260408051630217a4b760e41b8152905163217a4b70916004808201926020929091908290030181865afa15801562000168573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018e919062000633565b6001600160a01b031660a05250604051620001ae90829060200162000686565b60405160208183030381529060405280519060200120620001da83620002df60201b6200073f1760201c565b604051602001620001ec919062000686565b60405160208183030381529060405280519060200120146200022157604051630ccd248560e21b815260040160405180910390fd5b506001600160a01b0390811660c05287811660e05285166101005250620002488562000393565b5050505050505062000882565b60006001600160a01b03831615801590620002d8575082826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200029d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002c39190620006bb565b60e083901b6001600160e01b03199081169116145b9392505050565b6040805160048152602481019091526020810180516001600160e01b039081166395d89b4160e01b17909152606091600091829162000322918691906200042c16565b915091508115806200033357508051155b15620003595750506040805180820190915260018152603f60f81b602082015292915050565b602081510362000376576200036e81620004fb565b949350505050565b808060200190518101906200036e9190620006fd565b5050919050565b600080620003a18362000585565b915091508180620003b0575080155b15620003dc5760405163685ddbe760e11b81528215156004820152811515602482015260440162000114565b6000805463ffffffff191663ffffffff85169081179091556040519081527fd82b20bed317f4f38777ecc650568940cbd210b15af84857f885373342a3d6fa9060200160405180910390a1505050565b6000606062000446846200061460201b620007de1760201c565b62000464576040516373d39f9d60e01b815260040160405180910390fd5b600080856001600160a01b031685604051620004819190620007b5565b600060405180830381855afa9150503d8060008114620004be576040519150601f19603f3d011682016040523d82523d6000602084013e620004c3565b606091505b509150915081620004ec57600060405180602001604052806000815250935093505050620004f4565b600193509150505b9250929050565b805160609060005b818110156200038c57838181518110620005215762000521620007d3565b01602001516001600160f81b031916156200057c57828482815181106200054c576200054c620007d3565b602001015160f81c60f81b6040516020016200056a929190620007e9565b60405160208183030381529060405292505b60010162000503565b60e0516101005160405162439f4b60e91b81526001600160a01b03918216600482015263ffffffff841660248201526000928392169063873e960090604401606060405180830381865afa158015620005e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000608919062000830565b91959194509092505050565b3b151590565b6001600160a01b03811681146200063057600080fd5b50565b6000602082840312156200064657600080fd5b8151620002d8816200061a565b60005b838110156200067057818101518382015260200162000656565b8381111562000680576000848401525b50505050565b6020815260008251806020840152620006a781604085016020870162000653565b601f01601f19169190910160400192915050565b600060208284031215620006ce57600080fd5b81516001600160e01b031981168114620002d857600080fd5b634e487b7160e01b600052604160045260246000fd5b6000602082840312156200071057600080fd5b81516001600160401b03808211156200072857600080fd5b818401915084601f8301126200073d57600080fd5b815181811115620007525762000752620006e7565b604051601f8201601f19908116603f011681019083821181831017156200077d576200077d620006e7565b816040528281528760208487010111156200079757600080fd5b620007aa83602083016020880162000653565b979650505050505050565b60008251620007c981846020870162000653565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b60008351620007fd81846020880162000653565b6001600160f81b0319939093169190920190815260010192915050565b805180151581146200082b57600080fd5b919050565b6000806000606084860312156200084657600080fd5b62000851846200081a565b9250602084015161ffff811681146200086957600080fd5b915062000879604085016200081a565b90509250925092565b60805160a05160c05160e05161010051610c7b620008ff600039600081816102db01528181610313015261052e01526000818161024f0152818161034c01526105650152600081816101be0152818161028101526103c7015260006101270152600081816102150152818161043301526105e40152610c7b6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806358fe922d1161008c578063809d7b3111610066578063809d7b311461024a578063b31fb25614610271578063c433c80a146102c1578063f46f16c2146102d657600080fd5b806358fe922d146101f55780635ddf2be3146102105780637b1d10891461023757600080fd5b8063284ada3e116100c8578063284ada3e1461016e57806341976e09146101985780634800d97f146101b957806357e0c50f146101e057600080fd5b806313a73c78146100ef578063217a4b701461012257806326d8954514610149575b600080fd5b73bf5495efe5db9ce00f80364c8b423567e58d21105b6040516001600160a01b0390911681526020015b60405180910390f35b6101057f000000000000000000000000000000000000000000000000000000000000000081565b6000546101599063ffffffff1681565b60405163ffffffff9091168152602001610119565b61018161017c3660046109ab565b6102fd565b604080519215158352901515602083015201610119565b6101ab6101a63660046109e6565b6103c3565b604051908152602001610119565b6101057f000000000000000000000000000000000000000000000000000000000000000081565b6040516357e0c50f60e01b8152602001610119565b61010573bf5495efe5db9ce00f80364c8b423567e58d211081565b6101057f000000000000000000000000000000000000000000000000000000000000000081565b6101ab6102453660046109ab565b610517565b6101057f000000000000000000000000000000000000000000000000000000000000000081565b6102b161027f3660046109e6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811691161490565b6040519015158152602001610119565b6102d46102cf3660046109ab565b6105d8565b005b6101057f000000000000000000000000000000000000000000000000000000000000000081565b60405162439f4b60e91b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015263ffffffff8316602483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063873e960090604401606060405180830381865afa158015610393573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b79190610a18565b91959194509092505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03908116908316146104125760405163981a2a2b60e01b815260040160405180910390fd5b600080546104259063ffffffff16610517565b905060006001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166341976e0973bf5495efe5db9ce00f80364c8b423567e58d21106040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156104b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d59190610a64565b90506104e18183610a7d565b670de0b6b3a764000090049250600083900361051057604051634dfba02360e01b815260040160405180910390fd5b5050919050565b60405163a31426d160e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015263ffffffff831660248301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a31426d190604401602060405180830381865afa1580156105ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d29190610a64565b92915050565b336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015610640573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106649190610aaa565b6001600160a01b0316146106ad5760405162461bcd60e51b815260206004820152600b60248201526a27b7363ca6b0b730b3b2b960a91b60448201526064015b60405180910390fd5b6106b6816107e4565b50565b60006001600160a01b03831615801590610738575082826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107239190610ac7565b60e083901b6001600160e01b03199081169116145b9392505050565b6040805160048152602481019091526020810180516001600160e01b03166395d89b4160e01b179052606090600090819061077b908590610878565b9150915081158061078b57508051155b156107b05750506040805180820190915260018152603f60f81b602082015292915050565b60208151036107ca576107c28161092c565b949350505050565b808060200190518101906107c29190610b37565b3b151590565b6000806107f0836102fd565b9150915081806107fe575080155b156108285760405163685ddbe760e11b8152821515600482015281151560248201526044016106a4565b6000805463ffffffff191663ffffffff85169081179091556040519081527fd82b20bed317f4f38777ecc650568940cbd210b15af84857f885373342a3d6fa9060200160405180910390a1505050565b60006060833b61089b576040516373d39f9d60e01b815260040160405180910390fd5b600080856001600160a01b0316856040516108b69190610be4565b600060405180830381855afa9150503d80600081146108f1576040519150601f19603f3d011682016040523d82523d6000602084013e6108f6565b606091505b50915091508161091d57600060405180602001604052806000815250935093505050610925565b600193509150505b9250929050565b805160609060005b818110156105105783818151811061094e5761094e610c00565b01602001516001600160f81b031916156109a3578284828151811061097557610975610c00565b602001015160f81c60f81b604051602001610991929190610c16565b60405160208183030381529060405292505b600101610934565b6000602082840312156109bd57600080fd5b813563ffffffff8116811461073857600080fd5b6001600160a01b03811681146106b657600080fd5b6000602082840312156109f857600080fd5b8135610738816109d1565b80518015158114610a1357600080fd5b919050565b600080600060608486031215610a2d57600080fd5b610a3684610a03565b9250602084015161ffff81168114610a4d57600080fd5b9150610a5b60408501610a03565b90509250925092565b600060208284031215610a7657600080fd5b5051919050565b6000816000190483118215151615610aa557634e487b7160e01b600052601160045260246000fd5b500290565b600060208284031215610abc57600080fd5b8151610738816109d1565b600060208284031215610ad957600080fd5b81516001600160e01b03198116811461073857600080fd5b634e487b7160e01b600052604160045260246000fd5b60005b83811015610b22578181015183820152602001610b0a565b83811115610b31576000848401525b50505050565b600060208284031215610b4957600080fd5b815167ffffffffffffffff80821115610b6157600080fd5b818401915084601f830112610b7557600080fd5b815181811115610b8757610b87610af1565b604051601f8201601f19908116603f01168101908382118183101715610baf57610baf610af1565b81604052828152876020848701011115610bc857600080fd5b610bd9836020830160208801610b07565b979650505050505050565b60008251610bf6818460208701610b07565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b60008351610c28818460208801610b07565b6001600160f81b031993909316919092019081526001019291505056fea264697066735822122013ea28deaec8b9d8906b8bd8387fa7f1c48ef04a677ae3e03d2e027b6832eaf164736f6c634300080d00330000000000000000000000007c2ca9d502f2409beceafa68e97a176ff805029f

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806358fe922d1161008c578063809d7b3111610066578063809d7b311461024a578063b31fb25614610271578063c433c80a146102c1578063f46f16c2146102d657600080fd5b806358fe922d146101f55780635ddf2be3146102105780637b1d10891461023757600080fd5b8063284ada3e116100c8578063284ada3e1461016e57806341976e09146101985780634800d97f146101b957806357e0c50f146101e057600080fd5b806313a73c78146100ef578063217a4b701461012257806326d8954514610149575b600080fd5b73bf5495efe5db9ce00f80364c8b423567e58d21105b6040516001600160a01b0390911681526020015b60405180910390f35b6101057f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000546101599063ffffffff1681565b60405163ffffffff9091168152602001610119565b61018161017c3660046109ab565b6102fd565b604080519215158352901515602083015201610119565b6101ab6101a63660046109e6565b6103c3565b604051908152602001610119565b6101057f000000000000000000000000f7906f274c174a52d444175729e3fa98f9bde28581565b6040516357e0c50f60e01b8152602001610119565b61010573bf5495efe5db9ce00f80364c8b423567e58d211081565b6101057f0000000000000000000000007c2ca9d502f2409beceafa68e97a176ff805029f81565b6101ab6102453660046109ab565b610517565b6101057f00000000000000000000000066a1096c6366b2529274df4f5d8247827fe4cea881565b6102b161027f3660046109e6565b7f000000000000000000000000f7906f274c174a52d444175729e3fa98f9bde2856001600160a01b0390811691161490565b6040519015158152602001610119565b6102d46102cf3660046109ab565b6105d8565b005b6101057f000000000000000000000000d8f12bcde578c653014f27379a6114f67f0e445f81565b60405162439f4b60e91b81526001600160a01b037f000000000000000000000000d8f12bcde578c653014f27379a6114f67f0e445f8116600483015263ffffffff8316602483015260009182917f00000000000000000000000066a1096c6366b2529274df4f5d8247827fe4cea8169063873e960090604401606060405180830381865afa158015610393573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b79190610a18565b91959194509092505050565b60007f000000000000000000000000f7906f274c174a52d444175729e3fa98f9bde2856001600160a01b03908116908316146104125760405163981a2a2b60e01b815260040160405180910390fd5b600080546104259063ffffffff16610517565b905060006001600160a01b037f0000000000000000000000007c2ca9d502f2409beceafa68e97a176ff805029f166341976e0973bf5495efe5db9ce00f80364c8b423567e58d21106040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156104b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d59190610a64565b90506104e18183610a7d565b670de0b6b3a764000090049250600083900361051057604051634dfba02360e01b815260040160405180910390fd5b5050919050565b60405163a31426d160e01b81526001600160a01b037f000000000000000000000000d8f12bcde578c653014f27379a6114f67f0e445f8116600483015263ffffffff831660248301526000917f00000000000000000000000066a1096c6366b2529274df4f5d8247827fe4cea89091169063a31426d190604401602060405180830381865afa1580156105ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d29190610a64565b92915050565b336001600160a01b03167f0000000000000000000000007c2ca9d502f2409beceafa68e97a176ff805029f6001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa158015610640573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106649190610aaa565b6001600160a01b0316146106ad5760405162461bcd60e51b815260206004820152600b60248201526a27b7363ca6b0b730b3b2b960a91b60448201526064015b60405180910390fd5b6106b6816107e4565b50565b60006001600160a01b03831615801590610738575082826040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107239190610ac7565b60e083901b6001600160e01b03199081169116145b9392505050565b6040805160048152602481019091526020810180516001600160e01b03166395d89b4160e01b179052606090600090819061077b908590610878565b9150915081158061078b57508051155b156107b05750506040805180820190915260018152603f60f81b602082015292915050565b60208151036107ca576107c28161092c565b949350505050565b808060200190518101906107c29190610b37565b3b151590565b6000806107f0836102fd565b9150915081806107fe575080155b156108285760405163685ddbe760e11b8152821515600482015281151560248201526044016106a4565b6000805463ffffffff191663ffffffff85169081179091556040519081527fd82b20bed317f4f38777ecc650568940cbd210b15af84857f885373342a3d6fa9060200160405180910390a1505050565b60006060833b61089b576040516373d39f9d60e01b815260040160405180910390fd5b600080856001600160a01b0316856040516108b69190610be4565b600060405180830381855afa9150503d80600081146108f1576040519150601f19603f3d011682016040523d82523d6000602084013e6108f6565b606091505b50915091508161091d57600060405180602001604052806000815250935093505050610925565b600193509150505b9250929050565b805160609060005b818110156105105783818151811061094e5761094e610c00565b01602001516001600160f81b031916156109a3578284828151811061097557610975610c00565b602001015160f81c60f81b604051602001610991929190610c16565b60405160208183030381529060405292505b600101610934565b6000602082840312156109bd57600080fd5b813563ffffffff8116811461073857600080fd5b6001600160a01b03811681146106b657600080fd5b6000602082840312156109f857600080fd5b8135610738816109d1565b80518015158114610a1357600080fd5b919050565b600080600060608486031215610a2d57600080fd5b610a3684610a03565b9250602084015161ffff81168114610a4d57600080fd5b9150610a5b60408501610a03565b90509250925092565b600060208284031215610a7657600080fd5b5051919050565b6000816000190483118215151615610aa557634e487b7160e01b600052601160045260246000fd5b500290565b600060208284031215610abc57600080fd5b8151610738816109d1565b600060208284031215610ad957600080fd5b81516001600160e01b03198116811461073857600080fd5b634e487b7160e01b600052604160045260246000fd5b60005b83811015610b22578181015183820152602001610b0a565b83811115610b31576000848401525b50505050565b600060208284031215610b4957600080fd5b815167ffffffffffffffff80821115610b6157600080fd5b818401915084601f830112610b7557600080fd5b815181811115610b8757610b87610af1565b604051601f8201601f19908116603f01168101908382118183101715610baf57610baf610af1565b81604052828152876020848701011115610bc857600080fd5b610bd9836020830160208801610b07565b979650505050505050565b60008251610bf6818460208701610b07565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b60008351610c28818460208801610b07565b6001600160f81b031993909316919092019081526001019291505056fea264697066735822122013ea28deaec8b9d8906b8bd8387fa7f1c48ef04a677ae3e03d2e027b6832eaf164736f6c634300080d0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000007c2ca9d502f2409beceafa68e97a176ff805029f

-----Decoded View---------------
Arg [0] : _priceProvidersRepository (address): 0x7C2ca9D502f2409BeceAfa68E97a176Ff805029F

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000007c2ca9d502f2409beceafa68e97a176ff805029f


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
[ Download: CSV Export  ]

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.