ETH Price: $3,120.01 (+0.75%)

Contract

0x2CDF5812F4ebcF3BD533E8918D47Bd3e65514520
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x6101e060167804792023-03-08 2:08:47619 days ago1678241327IN
 Create: ApeCoinDualOracle
0 ETH0.0561010536.04541758

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
191010472024-01-27 23:01:59293 days ago1706396519
0x2CDF5812...e65514520
0 ETH
191010472024-01-27 23:01:59293 days ago1706396519
0x2CDF5812...e65514520
0 ETH
191010472024-01-27 23:01:59293 days ago1706396519
0x2CDF5812...e65514520
0 ETH
191010472024-01-27 23:01:59293 days ago1706396519
0x2CDF5812...e65514520
0 ETH
186385722023-11-24 2:24:11358 days ago1700792651
0x2CDF5812...e65514520
0 ETH
186385722023-11-24 2:24:11358 days ago1700792651
0x2CDF5812...e65514520
0 ETH
186385722023-11-24 2:24:11358 days ago1700792651
0x2CDF5812...e65514520
0 ETH
186385722023-11-24 2:24:11358 days ago1700792651
0x2CDF5812...e65514520
0 ETH
184062412023-10-22 13:49:35390 days ago1697982575
0x2CDF5812...e65514520
0 ETH
184062412023-10-22 13:49:35390 days ago1697982575
0x2CDF5812...e65514520
0 ETH
184062412023-10-22 13:49:35390 days ago1697982575
0x2CDF5812...e65514520
0 ETH
184062412023-10-22 13:49:35390 days ago1697982575
0x2CDF5812...e65514520
0 ETH
184060862023-10-22 13:17:59390 days ago1697980679
0x2CDF5812...e65514520
0 ETH
184060862023-10-22 13:17:59390 days ago1697980679
0x2CDF5812...e65514520
0 ETH
184060862023-10-22 13:17:59390 days ago1697980679
0x2CDF5812...e65514520
0 ETH
184060862023-10-22 13:17:59390 days ago1697980679
0x2CDF5812...e65514520
0 ETH
179742442023-08-23 1:51:11451 days ago1692755471
0x2CDF5812...e65514520
0 ETH
179742442023-08-23 1:51:11451 days ago1692755471
0x2CDF5812...e65514520
0 ETH
179742442023-08-23 1:51:11451 days ago1692755471
0x2CDF5812...e65514520
0 ETH
179742442023-08-23 1:51:11451 days ago1692755471
0x2CDF5812...e65514520
0 ETH
179047692023-08-13 8:32:59461 days ago1691915579
0x2CDF5812...e65514520
0 ETH
179047692023-08-13 8:32:59461 days ago1691915579
0x2CDF5812...e65514520
0 ETH
179047692023-08-13 8:32:59461 days ago1691915579
0x2CDF5812...e65514520
0 ETH
179047692023-08-13 8:32:59461 days ago1691915579
0x2CDF5812...e65514520
0 ETH
176411652023-07-07 9:54:23497 days ago1688723663
0x2CDF5812...e65514520
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ApeCoinDualOracle

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
default evmVersion
File 1 of 16 : ApeCoinDualOracle.sol
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// ======================== ApeCoinDualOracle =========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance

// Author
// Drake Evans: https://github.com/DrakeEvans

// Reviewers
// Dennis: https://github.com/denett

// ====================================================================

import "frax-std/access-control/Timelock2Step.sol";
import "frax-std/access-control/interfaces/ITimelock2Step.sol";
import {
    UniswapV3SingleTwapOracle,
    ConstructorParams as UniswapV3SingleTwapOracleParams
} from "./abstracts/UniswapV3SingleTwapOracle.sol";
import {
    ChainlinkOracleWithMaxDelay,
    ConstructorParams as ChainlinkOracleWithMaxDelayParams
} from "./abstracts/ChainlinkOracleWithMaxDelay.sol";
import {
    EthUsdChainlinkOracleWithMaxDelay,
    ConstructorParams as EthUsdChainlinkOracleWithMaxDelayParams
} from "./abstracts/EthUsdChainlinkOracleWithMaxDelay.sol";
import "../../interfaces/IDualOracle.sol";

struct ConstructorParams {
    address fraxErc20;
    address apeErc20;
    address wethErc20;
    address apeUsdChainlinkFeed;
    uint256 maximumOracleDelay;
    address ethUsdChainlinkFeed;
    uint256 maxEthUsdOracleDelay;
    address uniV3PairAddress;
    uint32 twapDuration;
    address timelockAddress;
}

/// @title ApeCoinDualOracle
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice  An oracle for ApeCoin in Frax units
contract ApeCoinDualOracle is
    Timelock2Step,
    UniswapV3SingleTwapOracle,
    ChainlinkOracleWithMaxDelay,
    EthUsdChainlinkOracleWithMaxDelay,
    IDualOracle
{
    uint256 public constant ORACLE_PRECISION = 1e18;
    address public immutable FRAX_ERC20;
    address public immutable APE_ERC20;

    /// @notice The oracle type, used for internal monitoring
    /// @dev Deprecated
    uint256 public constant oracleType = 0;

    constructor(
        ConstructorParams memory _params
    )
        Timelock2Step()
        UniswapV3SingleTwapOracle(
            UniswapV3SingleTwapOracleParams({
                uniswapV3PairAddress: _params.uniV3PairAddress,
                twapDuration: _params.twapDuration,
                baseToken: _params.wethErc20,
                quoteToken: _params.apeErc20
            })
        )
        ChainlinkOracleWithMaxDelay(
            ChainlinkOracleWithMaxDelayParams({
                chainlinkFeedAddress: _params.apeUsdChainlinkFeed,
                maximumOracleDelay: _params.maximumOracleDelay
            })
        )
        EthUsdChainlinkOracleWithMaxDelay(
            EthUsdChainlinkOracleWithMaxDelayParams({
                ethUsdChainlinkFeedAddress: _params.ethUsdChainlinkFeed,
                maxEthUsdOracleDelay: _params.maxEthUsdOracleDelay
            })
        )
    {
        _setTimelock({ _newTimelock: _params.timelockAddress });
        _registerInterface({ interfaceId: type(IDualOracle).interfaceId });
        _registerInterface({ interfaceId: type(ITimelock2Step).interfaceId });

        FRAX_ERC20 = _params.fraxErc20;
        APE_ERC20 = _params.apeErc20;
    }

    // ====================================================================
    // View Helpers
    // ====================================================================

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

    function name() external pure returns (string memory) {
        return "Ape Coin Dual Oracle Chainlink with Staleness Check and Uniswap V3 TWAP";
    }

    function quoteToken() external view returns (address) {
        return APE_ERC20;
    }

    function baseToken() external view returns (address) {
        return FRAX_ERC20;
    }

    // ====================================================================
    // Configuration Setters
    // ====================================================================

    /// @notice The ```setMaximumOracleDelay``` function sets the max oracle delay to determine if Chainlink data is stale
    /// @dev Requires msg.sender to be the timelock address
    /// @param _newMaxOracleDelay The new max oracle delay
    function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external override {
        _requireTimelock();
        _setMaximumOracleDelay({ _newMaxOracleDelay: _newMaxOracleDelay });
    }

    function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external override {
        _requireTimelock();
        _setMaximumEthUsdOracleDelay({ _newMaxOracleDelay: _newMaxOracleDelay });
    }

    /// @notice The ```setTwapDuration``` function sets the twap duration for the Uniswap V3 TWAP oracle
    /// @dev Requires msg.sender to be the timelock address
    /// @param _newTwapDuration The new twap duration
    function setTwapDuration(uint32 _newTwapDuration) external override {
        _requireTimelock();
        _setTwapDuration({ _newTwapDuration: _newTwapDuration });
    }

    // ====================================================================
    // Price Functions
    // ====================================================================

    function getApePerUsdTwap() public view returns (bool _isBadData, uint256 _apePerUsd) {
        uint256 _apePerWeth = _getUniswapV3Twap();
        uint256 _usdPerEth;
        (_isBadData, , _usdPerEth) = _getEthUsdChainlinkPrice();
        _apePerUsd = (_apePerWeth * ETH_USD_CHAINLINK_FEED_PRECISION) / _usdPerEth;
    }

    function getApePerUsdChainlink() public view returns (bool _isBadData, uint256 _apePerUsd) {
        (bool _isBadDataChainlink, , uint256 _usdPerApeChainlinkRaw) = _getChainlinkPrice();
        _apePerUsd = (ORACLE_PRECISION * CHAINLINK_FEED_PRECISION) / _usdPerApeChainlinkRaw;
    }

    /// @notice The ```getPrices``` function is intended to return two prices from different oracles
    /// @return _isBadData is true when data is stale or otherwise bad
    /// @return _priceLow is the lower of the two prices
    /// @return _priceHigh is the higher of the two prices
    function getPrices() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh) {
        (bool _isBadDataChainlink, uint256 _apePerUsdChainlink) = getApePerUsdChainlink();

        (bool _isBadDataTwap, uint256 _apePerUsdTwap) = getApePerUsdTwap();
        if (_isBadDataChainlink && _isBadDataTwap) {
            revert("Both Chainlink and TWAP are bad");
        }
        if (_isBadDataChainlink) {
            _priceLow = _apePerUsdTwap;
            _priceHigh = _apePerUsdTwap;
        } else if (_isBadDataTwap) {
            _priceLow = _apePerUsdChainlink;
            _priceHigh = _apePerUsdChainlink;
        } else if (_apePerUsdChainlink < _apePerUsdTwap) {
            _priceLow = _apePerUsdChainlink;
            _priceHigh = _apePerUsdTwap;
        } else {
            _priceLow = _apePerUsdTwap;
            _priceHigh = _apePerUsdChainlink;
        }
    }
}

File 2 of 16 : Timelock2Step.sol
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// ========================== Timelock2Step ===========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance

// Primary Author
// Drake Evans: https://github.com/DrakeEvans

// Reviewers
// Dennis: https://github.com/denett

// ====================================================================

/// @title Timelock2Step
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @dev Inspired by the OpenZeppelin's Ownable2Step contract
/// @notice  An abstract contract which contains 2-step transfer and renounce logic for a timelock address
abstract contract Timelock2Step {
    /// @notice The pending timelock address
    address public pendingTimelockAddress;

    /// @notice The current timelock address
    address public timelockAddress;

    constructor() {
        timelockAddress = msg.sender;
    }

    /// @notice Emitted when timelock is transferred
    error OnlyTimelock();

    /// @notice Emitted when pending timelock is transferred
    error OnlyPendingTimelock();

    /// @notice The ```TimelockTransferStarted``` event is emitted when the timelock transfer is initiated
    /// @param previousTimelock The address of the previous timelock
    /// @param newTimelock The address of the new timelock
    event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);

    /// @notice The ```TimelockTransferred``` event is emitted when the timelock transfer is completed
    /// @param previousTimelock The address of the previous timelock
    /// @param newTimelock The address of the new timelock
    event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);

    /// @notice The ```_isSenderTimelock``` function checks if msg.sender is current timelock address
    /// @return Whether or not msg.sender is current timelock address
    function _isSenderTimelock() internal view returns (bool) {
        return msg.sender == timelockAddress;
    }

    /// @notice The ```_requireTimelock``` function reverts if msg.sender is not current timelock address
    function _requireTimelock() internal view {
        if (msg.sender != timelockAddress) revert OnlyTimelock();
    }

    /// @notice The ```_isSenderPendingTimelock``` function checks if msg.sender is pending timelock address
    /// @return Whether or not msg.sender is pending timelock address
    function _isSenderPendingTimelock() internal view returns (bool) {
        return msg.sender == pendingTimelockAddress;
    }

    /// @notice The ```_requirePendingTimelock``` function reverts if msg.sender is not pending timelock address
    function _requirePendingTimelock() internal view {
        if (msg.sender != pendingTimelockAddress) revert OnlyPendingTimelock();
    }

    /// @notice The ```_transferTimelock``` function initiates the timelock transfer
    /// @dev This function is to be implemented by a public function
    /// @param _newTimelock The address of the nominated (pending) timelock
    function _transferTimelock(address _newTimelock) internal {
        pendingTimelockAddress = _newTimelock;
        emit TimelockTransferStarted(timelockAddress, _newTimelock);
    }

    /// @notice The ```_acceptTransferTimelock``` function completes the timelock transfer
    /// @dev This function is to be implemented by a public function
    function _acceptTransferTimelock() internal {
        pendingTimelockAddress = address(0);
        _setTimelock(msg.sender);
    }

    /// @notice The ```_setTimelock``` function sets the timelock address
    /// @dev This function is to be implemented by a public function
    /// @param _newTimelock The address of the new timelock
    function _setTimelock(address _newTimelock) internal {
        emit TimelockTransferred(timelockAddress, _newTimelock);
        timelockAddress = _newTimelock;
    }

    /// @notice The ```transferTimelock``` function initiates the timelock transfer
    /// @dev Must be called by the current timelock
    /// @param _newTimelock The address of the nominated (pending) timelock
    function transferTimelock(address _newTimelock) external virtual {
        _requireTimelock();
        _transferTimelock(_newTimelock);
    }

    /// @notice The ```acceptTransferTimelock``` function completes the timelock transfer
    /// @dev Must be called by the pending timelock
    function acceptTransferTimelock() external virtual {
        _requirePendingTimelock();
        _acceptTransferTimelock();
    }

    /// @notice The ```renounceTimelock``` function renounces the timelock after setting pending timelock to current timelock
    /// @dev Pending timelock must be set to current timelock before renouncing, creating a 2-step renounce process
    function renounceTimelock() external virtual {
        _requireTimelock();
        _requirePendingTimelock();
        _transferTimelock(address(0));
        _setTimelock(address(0));
    }
}

File 3 of 16 : ITimelock2Step.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

interface ITimelock2Step {
    event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
    event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);

    function acceptTransferTimelock() external;

    function pendingTimelockAddress() external view returns (address);

    function renounceTimelock() external;

    function timelockAddress() external view returns (address);

    function transferTimelock(address _newTimelock) external;
}

File 4 of 16 : AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface AggregatorV3Interface {
  function decimals() external view returns (uint8);

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

  function version() external view returns (uint256);

  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

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

File 5 of 16 : IStaticOracle.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.7.6 <0.9.0;

import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';

/// @title Uniswap V3 Static Oracle
/// @notice Oracle contract for calculating price quoting against Uniswap V3
interface IStaticOracle {
  /// @notice Returns the address of the Uniswap V3 factory
  /// @dev This value is assigned during deployment and cannot be changed
  /// @return The address of the Uniswap V3 factory
  function UNISWAP_V3_FACTORY() external view returns (IUniswapV3Factory);

  /// @notice Returns how many observations are needed per minute in Uniswap V3 oracles, on the deployed chain
  /// @dev This value is assigned during deployment and cannot be changed
  /// @return Number of observation that are needed per minute
  function CARDINALITY_PER_MINUTE() external view returns (uint8);

  /// @notice Returns all supported fee tiers
  /// @return The supported fee tiers
  function supportedFeeTiers() external view returns (uint24[] memory);

  /// @notice Returns whether a specific pair can be supported by the oracle
  /// @dev The pair can be provided in tokenA/tokenB or tokenB/tokenA order
  /// @return Whether the given pair can be supported by the oracle
  function isPairSupported(address tokenA, address tokenB) external view returns (bool);

  /// @notice Returns all existing pools for the given pair
  /// @dev The pair can be provided in tokenA/tokenB or tokenB/tokenA order
  /// @return All existing pools for the given pair
  function getAllPoolsForPair(address tokenA, address tokenB) external view returns (address[] memory);

  /// @notice Returns a quote, based on the given tokens and amount, by querying all of the pair's pools
  /// @dev If some pools are not configured correctly for the given period, then they will be ignored
  /// @dev Will revert if there are no pools available/configured for the pair and period combination
  /// @param baseAmount Amount of token to be converted
  /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination
  /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination
  /// @param period Number of seconds from which to calculate the TWAP
  /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken
  /// @return queriedPools The pools that were queried to calculate the quote
  function quoteAllAvailablePoolsWithTimePeriod(
    uint128 baseAmount,
    address baseToken,
    address quoteToken,
    uint32 period
  ) external view returns (uint256 quoteAmount, address[] memory queriedPools);

  /// @notice Returns a quote, based on the given tokens and amount, by querying only the specified fee tiers
  /// @dev Will revert if the pair does not have a pool for one of the given fee tiers, or if one of the pools
  /// is not prepared/configured correctly for the given period
  /// @param baseAmount Amount of token to be converted
  /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination
  /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination
  /// @param feeTiers The fee tiers to consider when calculating the quote
  /// @param period Number of seconds from which to calculate the TWAP
  /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken
  /// @return queriedPools The pools that were queried to calculate the quote
  function quoteSpecificFeeTiersWithTimePeriod(
    uint128 baseAmount,
    address baseToken,
    address quoteToken,
    uint24[] calldata feeTiers,
    uint32 period
  ) external view returns (uint256 quoteAmount, address[] memory queriedPools);

  /// @notice Returns a quote, based on the given tokens and amount, by querying only the specified pools
  /// @dev Will revert if one of the pools is not prepared/configured correctly for the given period
  /// @param baseAmount Amount of token to be converted
  /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination
  /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination
  /// @param pools The pools to consider when calculating the quote
  /// @param period Number of seconds from which to calculate the TWAP
  /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken
  function quoteSpecificPoolsWithTimePeriod(
    uint128 baseAmount,
    address baseToken,
    address quoteToken,
    address[] calldata pools,
    uint32 period
  ) external view returns (uint256 quoteAmount);

  /// @notice Will initialize all existing pools for the given pair, so that they can be queried with the given period in the future
  /// @dev Will revert if there are no pools available for the pair and period combination
  /// @param tokenA One of the pair's tokens
  /// @param tokenB The other of the pair's tokens
  /// @param period The period that will be guaranteed when quoting
  /// @return preparedPools The pools that were prepared
  function prepareAllAvailablePoolsWithTimePeriod(
    address tokenA,
    address tokenB,
    uint32 period
  ) external returns (address[] memory preparedPools);

  /// @notice Will initialize the pair's pools with the specified fee tiers, so that they can be queried with the given period in the future
  /// @dev Will revert if the pair does not have a pool for a given fee tier
  /// @param tokenA One of the pair's tokens
  /// @param tokenB The other of the pair's tokens
  /// @param feeTiers The fee tiers to consider when searching for the pair's pools
  /// @param period The period that will be guaranteed when quoting
  /// @return preparedPools The pools that were prepared
  function prepareSpecificFeeTiersWithTimePeriod(
    address tokenA,
    address tokenB,
    uint24[] calldata feeTiers,
    uint32 period
  ) external returns (address[] memory preparedPools);

  /// @notice Will initialize all given pools, so that they can be queried with the given period in the future
  /// @param pools The pools to initialize
  /// @param period The period that will be guaranteed when quoting
  function prepareSpecificPoolsWithTimePeriod(address[] calldata pools, uint32 period) external;

  /// @notice Will increase observations for all existing pools for the given pair, so they start accruing information for twap calculations
  /// @dev Will revert if there are no pools available for the pair and period combination
  /// @param tokenA One of the pair's tokens
  /// @param tokenB The other of the pair's tokens
  /// @param cardinality The cardinality that will be guaranteed when quoting
  /// @return preparedPools The pools that were prepared
  function prepareAllAvailablePoolsWithCardinality(
    address tokenA,
    address tokenB,
    uint16 cardinality
  ) external returns (address[] memory preparedPools);

  /// @notice Will increase the pair's pools with the specified fee tiers observations, so they start accruing information for twap calculations
  /// @dev Will revert if the pair does not have a pool for a given fee tier
  /// @param tokenA One of the pair's tokens
  /// @param tokenB The other of the pair's tokens
  /// @param feeTiers The fee tiers to consider when searching for the pair's pools
  /// @param cardinality The cardinality that will be guaranteed when quoting
  /// @return preparedPools The pools that were prepared
  function prepareSpecificFeeTiersWithCardinality(
    address tokenA,
    address tokenB,
    uint24[] calldata feeTiers,
    uint16 cardinality
  ) external returns (address[] memory preparedPools);

  /// @notice Will increase all given pools observations, so they start accruing information for twap calculations
  /// @param pools The pools to initialize
  /// @param cardinality The cardinality that will be guaranteed when quoting
  function prepareSpecificPoolsWithCardinality(address[] calldata pools, uint16 cardinality) external;

  /// @notice Adds support for a new fee tier
  /// @dev Will revert if the given tier is invalid, or already supported
  /// @param feeTier The new fee tier to add
  function addNewFeeTier(uint24 feeTier) external;
}

File 6 of 16 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 7 of 16 : ERC165Storage.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)

pragma solidity ^0.8.0;

import "./ERC165.sol";

/**
 * @dev Storage based implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165Storage is ERC165 {
    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

File 8 of 16 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 9 of 16 : IUniswapV3Factory.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title The interface for the Uniswap V3 Factory
/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees
interface IUniswapV3Factory {
    /// @notice Emitted when the owner of the factory is changed
    /// @param oldOwner The owner before the owner was changed
    /// @param newOwner The owner after the owner was changed
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);

    /// @notice Emitted when a pool is created
    /// @param token0 The first token of the pool by address sort order
    /// @param token1 The second token of the pool by address sort order
    /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
    /// @param tickSpacing The minimum number of ticks between initialized ticks
    /// @param pool The address of the created pool
    event PoolCreated(
        address indexed token0,
        address indexed token1,
        uint24 indexed fee,
        int24 tickSpacing,
        address pool
    );

    /// @notice Emitted when a new fee amount is enabled for pool creation via the factory
    /// @param fee The enabled fee, denominated in hundredths of a bip
    /// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee
    event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);

    /// @notice Returns the current owner of the factory
    /// @dev Can be changed by the current owner via setOwner
    /// @return The address of the factory owner
    function owner() external view returns (address);

    /// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled
    /// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context
    /// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee
    /// @return The tick spacing
    function feeAmountTickSpacing(uint24 fee) external view returns (int24);

    /// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist
    /// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order
    /// @param tokenA The contract address of either token0 or token1
    /// @param tokenB The contract address of the other token
    /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
    /// @return pool The pool address
    function getPool(
        address tokenA,
        address tokenB,
        uint24 fee
    ) external view returns (address pool);

    /// @notice Creates a pool for the given two tokens and fee
    /// @param tokenA One of the two tokens in the desired pool
    /// @param tokenB The other of the two tokens in the desired pool
    /// @param fee The desired fee for the pool
    /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved
    /// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments
    /// are invalid.
    /// @return pool The address of the newly created pool
    function createPool(
        address tokenA,
        address tokenB,
        uint24 fee
    ) external returns (address pool);

    /// @notice Updates the owner of the factory
    /// @dev Must be called by the current owner
    /// @param _owner The new owner of the factory
    function setOwner(address _owner) external;

    /// @notice Enables a fee amount with the given tickSpacing
    /// @dev Fee amounts may never be removed once enabled
    /// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)
    /// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount
    function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
}

File 10 of 16 : IDualOracle.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface IDualOracle is IERC165 {
    function ORACLE_PRECISION() external view returns (uint256);

    function baseToken() external view returns (address);

    function decimals() external pure returns (uint8);

    function getPrices() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh);

    function name() external pure returns (string memory);

    function oracleType() external view returns (uint256);

    function quoteToken() external view returns (address);
}

File 11 of 16 : IChainlinkOracleWithMaxDelay.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface IChainlinkOracleWithMaxDelay is IERC165 {
    event SetMaximumOracleDelay(address oracle, uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);

    function CHAINLINK_FEED_ADDRESS() external view returns (address);

    function CHAINLINK_FEED_DECIMALS() external view returns (uint8);

    function CHAINLINK_FEED_PRECISION() external view returns (uint256);

    function getChainlinkPrice() external view returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth);

    function maximumOracleDelay() external view returns (uint256);
}

File 12 of 16 : IEthUsdChainlinkOracleWithMaxDelay.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface IEthUsdChainlinkOracleWithMaxDelay is IERC165 {
    event SetMaximumEthUsdOracleDelay(uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);

    function ETH_USD_CHAINLINK_FEED_ADDRESS() external view returns (address);

    function ETH_USD_CHAINLINK_FEED_DECIMALS() external view returns (uint8);

    function ETH_USD_CHAINLINK_FEED_PRECISION() external view returns (uint256);

    function maximumEthUsdOracleDelay() external view returns (uint256);

    function getEthUsdChainlinkPrice() external view returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth);
}

File 13 of 16 : IUniswapV3SingleTwapOracle.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface IUniswapV3SingleTwapOracle is IERC165 {
    event SetTwapDuration(uint256 oldTwapDuration, uint256 newTwapDuration);

    function UNISWAP_V3_TWAP_BASE_TOKEN() external view returns (address);

    function UNISWAP_V3_TWAP_QUOTE_TOKEN() external view returns (address);

    function TWAP_PRECISION() external view returns (uint128);

    function UNI_V3_PAIR_ADDRESS() external view returns (address);

    function getUniswapV3Twap() external view returns (uint256 _twap);

    function twapDuration() external view returns (uint32);
}

File 14 of 16 : ChainlinkOracleWithMaxDelay.sol
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// =================== ChainlinkOracleWithMaxDelay ====================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance

// Author
// Drake Evans: https://github.com/DrakeEvans

// Reviewers
// Dennis: https://github.com/denett

// ====================================================================

import "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "../../../interfaces/oracles/abstracts/IChainlinkOracleWithMaxDelay.sol";

struct ConstructorParams {
    address chainlinkFeedAddress;
    uint256 maximumOracleDelay;
}

/// @title ChainlinkOracleWithMaxDelay
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice  An abstract oracle for getting prices from Chainlink
abstract contract ChainlinkOracleWithMaxDelay is ERC165Storage, IChainlinkOracleWithMaxDelay {
    /// @notice Chainlink aggregator
    address public immutable CHAINLINK_FEED_ADDRESS;

    /// @notice Decimals of ETH/USD chainlink feed
    uint8 public immutable CHAINLINK_FEED_DECIMALS;

    /// @notice Precision of ETH/USD chainlink feed
    uint256 public immutable CHAINLINK_FEED_PRECISION;

    /// @notice Maximum delay of Chainlink data, after which it is considered stale
    uint256 public maximumOracleDelay;

    constructor(ConstructorParams memory _params) {
        _registerInterface({ interfaceId: type(IChainlinkOracleWithMaxDelay).interfaceId });

        CHAINLINK_FEED_ADDRESS = _params.chainlinkFeedAddress;
        CHAINLINK_FEED_DECIMALS = AggregatorV3Interface(CHAINLINK_FEED_ADDRESS).decimals();
        CHAINLINK_FEED_PRECISION = 10 ** uint256(CHAINLINK_FEED_DECIMALS);
        maximumOracleDelay = _params.maximumOracleDelay;
    }

    /// @notice The ```SetMaximumOracleDelay``` event is emitted when the max oracle delay is set
    /// @param oldMaxOracleDelay The old max oracle delay
    /// @param newMaxOracleDelay The new max oracle delay
    event SetMaximumOracleDelay(uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);

    /// @notice The ```_setMaximumOracleDelay``` function sets the max oracle delay to determine if Chainlink data is stale
    /// @param _newMaxOracleDelay The new max oracle delay
    function _setMaximumOracleDelay(uint256 _newMaxOracleDelay) internal {
        emit SetMaximumOracleDelay({ oldMaxOracleDelay: maximumOracleDelay, newMaxOracleDelay: _newMaxOracleDelay });
        maximumOracleDelay = _newMaxOracleDelay;
    }

    function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external virtual;

    function _getChainlinkPrice() internal view returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {
        int256 _answer;
        (, _answer, , _updatedAt, ) = AggregatorV3Interface(CHAINLINK_FEED_ADDRESS).latestRoundData();

        // If data is stale or negative, set bad data to true and return
        if (_answer <= 0 || (block.timestamp - _updatedAt > maximumOracleDelay)) {
            _isBadData = true;
        }

        _price = uint256(_answer);
    }

    /// @notice The ```getChainlinkPrice``` function returns the chainlink price and the timestamp of the last update
    /// @dev Uses the same prevision as the chainlink feed, virtual so it can be overridden
    /// @return _isBadData True if the data is stale or negative
    /// @return _updatedAt The timestamp of the last update
    /// @return _price The price
    function getChainlinkPrice() external view virtual returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {
        return _getChainlinkPrice();
    }
}

File 15 of 16 : EthUsdChainlinkOracleWithMaxDelay.sol
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// ================ EthUsdChainlinkOracleWithMaxDelay =================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance

// Author
// Drake Evans: https://github.com/DrakeEvans

// Reviewers
// Dennis: https://github.com/denett

// ====================================================================

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol";
import "../../../interfaces/oracles/abstracts/IEthUsdChainlinkOracleWithMaxDelay.sol";

struct ConstructorParams {
    address ethUsdChainlinkFeedAddress;
    uint256 maxEthUsdOracleDelay;
}

/// @title EthUsdChainlinkOracleWithMaxDelay
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice  An abstract oracle for getting eth/usd prices from Chainlink
abstract contract EthUsdChainlinkOracleWithMaxDelay is ERC165Storage, IEthUsdChainlinkOracleWithMaxDelay {
    /// @notice Chainlink aggregator
    address public immutable ETH_USD_CHAINLINK_FEED_ADDRESS;

    /// @notice Decimals of ETH/USD chainlink feed
    uint8 public immutable ETH_USD_CHAINLINK_FEED_DECIMALS;

    /// @notice Precision of ETH/USD chainlink feed
    uint256 public immutable ETH_USD_CHAINLINK_FEED_PRECISION;

    /// @notice Maximum delay of Chainlink data, after which it is considered stale
    uint256 public maximumEthUsdOracleDelay;

    constructor(ConstructorParams memory _params) {
        _registerInterface({ interfaceId: type(IEthUsdChainlinkOracleWithMaxDelay).interfaceId });

        ETH_USD_CHAINLINK_FEED_ADDRESS = _params.ethUsdChainlinkFeedAddress;
        ETH_USD_CHAINLINK_FEED_DECIMALS = AggregatorV3Interface(ETH_USD_CHAINLINK_FEED_ADDRESS).decimals();
        ETH_USD_CHAINLINK_FEED_PRECISION = 10 ** uint256(ETH_USD_CHAINLINK_FEED_DECIMALS);
        maximumEthUsdOracleDelay = _params.maxEthUsdOracleDelay;
    }

    /// @notice The ```_setMaximumEthUsdOracleDelay``` function sets the max oracle delay to determine if Chainlink data is stale
    /// @param _newMaxOracleDelay The new max oracle delay
    function _setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) internal {
        emit SetMaximumEthUsdOracleDelay({
            oldMaxOracleDelay: maximumEthUsdOracleDelay,
            newMaxOracleDelay: _newMaxOracleDelay
        });
        maximumEthUsdOracleDelay = _newMaxOracleDelay;
    }

    function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external virtual;

    /// @notice The ```_getEthUsdChainlinkPrice``` function is called to get the eth/usd price from Chainlink
    /// @dev If data is stale or negative, set bad data to true and return
    /// @return _isBadData If the data is stale
    /// @return _updatedAt The timestamp of the last update
    /// @return _usdPerEth The eth/usd price
    function _getEthUsdChainlinkPrice()
        internal
        view
        returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth)
    {
        int256 _answer;
        (, _answer, , _updatedAt, ) = AggregatorV3Interface(ETH_USD_CHAINLINK_FEED_ADDRESS).latestRoundData();

        // If data is stale or negative, set bad data to true and return
        if (_answer <= 0 || (block.timestamp - _updatedAt > maximumEthUsdOracleDelay)) {
            _isBadData = true;
        }

        _usdPerEth = uint256(_answer);
    }

    /// @notice The ```getEthUsdChainlinkPrice``` function is called to get the eth/usd price from Chainlink
    /// @return _isBadData If the data is stale
    /// @return _updatedAt The timestamp of the last update
    /// @return _usdPerEth The eth/usd price
    function getEthUsdChainlinkPrice()
        external
        view
        virtual
        returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth)
    {
        return _getEthUsdChainlinkPrice();
    }
}

File 16 of 16 : UniswapV3SingleTwapOracle.sol
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;

// ====================================================================
// |     ______                   _______                             |
// |    / _____________ __  __   / ____(_____  ____ _____  ________   |
// |   / /_  / ___/ __ `| |/_/  / /_  / / __ \/ __ `/ __ \/ ___/ _ \  |
// |  / __/ / /  / /_/ _>  <   / __/ / / / / / /_/ / / / / /__/  __/  |
// | /_/   /_/   \__,_/_/|_|  /_/   /_/_/ /_/\__,_/_/ /_/\___/\___/   |
// |                                                                  |
// ====================================================================
// ==================== UniswapV3SingleTwapOracle =====================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance

// Author
// Drake Evans: https://github.com/DrakeEvans

// Reviewers
// Dennis: https://github.com/denett

// ====================================================================

import "@mean-finance/uniswap-v3-oracle/solidity/interfaces/IStaticOracle.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol";
import "../../../interfaces/oracles/abstracts/IUniswapV3SingleTwapOracle.sol";

struct ConstructorParams {
    address uniswapV3PairAddress;
    uint32 twapDuration;
    address baseToken;
    address quoteToken;
}

/// @title UniswapV3SingleTwapOracle
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice  An oracle for UniV3 Twap prices
abstract contract UniswapV3SingleTwapOracle is ERC165Storage, IUniswapV3SingleTwapOracle {
    /// @notice address of the Uniswap V3 pair
    address public immutable UNI_V3_PAIR_ADDRESS;

    /// @notice The precision of the twap
    uint128 public constant TWAP_PRECISION = 1e18;

    /// @notice The base token of the twap
    address public immutable UNISWAP_V3_TWAP_BASE_TOKEN;

    /// @notice The quote token of the twap
    address public immutable UNISWAP_V3_TWAP_QUOTE_TOKEN;

    /// @notice The duration of the twap
    uint32 public twapDuration;

    constructor(ConstructorParams memory _params) {
        _registerInterface({ interfaceId: type(IUniswapV3SingleTwapOracle).interfaceId });

        UNI_V3_PAIR_ADDRESS = _params.uniswapV3PairAddress;
        twapDuration = _params.twapDuration;
        UNISWAP_V3_TWAP_BASE_TOKEN = _params.baseToken;
        UNISWAP_V3_TWAP_QUOTE_TOKEN = _params.quoteToken;
    }

    /// @notice The ```_setTwapDuration``` function sets duration of the twap
    /// @param _newTwapDuration The new twap duration
    function _setTwapDuration(uint32 _newTwapDuration) internal {
        emit SetTwapDuration({ oldTwapDuration: twapDuration, newTwapDuration: _newTwapDuration });
        twapDuration = _newTwapDuration;
    }

    function setTwapDuration(uint32 _newTwapDuration) external virtual;

    /// @notice The ```_getUniswapV3Twap``` function is called to get the twap
    /// @return _twap The twap price
    function _getUniswapV3Twap() internal view returns (uint256 _twap) {
        address[] memory _pools = new address[](1);
        _pools[0] = UNI_V3_PAIR_ADDRESS;
        _twap = IStaticOracle(0xB210CE856631EeEB767eFa666EC7C1C57738d438).quoteSpecificPoolsWithTimePeriod({
            baseAmount: TWAP_PRECISION,
            baseToken: UNISWAP_V3_TWAP_BASE_TOKEN,
            quoteToken: UNISWAP_V3_TWAP_QUOTE_TOKEN,
            pools: _pools,
            period: twapDuration
        });
    }

    /// @notice The ```getUniswapV3Twap``` function is called to get the twap
    /// @return _twap The twap price
    function getUniswapV3Twap() external view virtual returns (uint256 _twap) {
        return _getUniswapV3Twap();
    }
}

Settings
{
  "remappings": [
    "@chainlink/=node_modules/@chainlink/",
    "@ensdomains/=node_modules/@ensdomains/",
    "@eth-optimism/=node_modules/@eth-optimism/",
    "@mean-finance/=node_modules/@mean-finance/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@rari-capital/=node_modules/@rari-capital/",
    "@uniswap/=node_modules/@uniswap/",
    "base64-sol/=node_modules/base64-sol/",
    "ds-test/=lib/frax-standard-solidity/lib/forge-std/lib/ds-test/src/",
    "eth-gas-reporter/=node_modules/eth-gas-reporter/",
    "forge-std/=lib/frax-standard-solidity/lib/forge-std/src/",
    "frax-standard-solidity/=lib/frax-standard-solidity/src/",
    "frax-std/=lib/frax-standard-solidity/src/",
    "hardhat/=node_modules/hardhat/",
    "solidity-bytes-utils/=node_modules/solidity-bytes-utils/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "bytecodeHash": "none",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"components":[{"internalType":"address","name":"fraxErc20","type":"address"},{"internalType":"address","name":"apeErc20","type":"address"},{"internalType":"address","name":"wethErc20","type":"address"},{"internalType":"address","name":"apeUsdChainlinkFeed","type":"address"},{"internalType":"uint256","name":"maximumOracleDelay","type":"uint256"},{"internalType":"address","name":"ethUsdChainlinkFeed","type":"address"},{"internalType":"uint256","name":"maxEthUsdOracleDelay","type":"uint256"},{"internalType":"address","name":"uniV3PairAddress","type":"address"},{"internalType":"uint32","name":"twapDuration","type":"uint32"},{"internalType":"address","name":"timelockAddress","type":"address"}],"internalType":"struct ConstructorParams","name":"_params","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"OnlyPendingTimelock","type":"error"},{"inputs":[],"name":"OnlyTimelock","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumEthUsdOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldTwapDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTwapDuration","type":"uint256"}],"name":"SetTwapDuration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferred","type":"event"},{"inputs":[],"name":"APE_ERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHAINLINK_FEED_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHAINLINK_FEED_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CHAINLINK_FEED_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRAX_ERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TWAP_PRECISION","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_V3_TWAP_BASE_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAP_V3_TWAP_QUOTE_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNI_V3_PAIR_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"baseToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getApePerUsdChainlink","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_apePerUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getApePerUsdTwap","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_apePerUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainlinkPrice","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_updatedAt","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthUsdChainlinkPrice","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_updatedAt","type":"uint256"},{"internalType":"uint256","name":"_usdPerEth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrices","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_priceLow","type":"uint256"},{"internalType":"uint256","name":"_priceHigh","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUniswapV3Twap","outputs":[{"internalType":"uint256","name":"_twap","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumEthUsdOracleDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumOracleDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"oracleType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxOracleDelay","type":"uint256"}],"name":"setMaximumEthUsdOracleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxOracleDelay","type":"uint256"}],"name":"setMaximumOracleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_newTwapDuration","type":"uint32"}],"name":"setTwapDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"transferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twapDuration","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"}]

6101e060405234620005545761014062001cdf803803809162000025826101e062000575565b6101e03912620005545760405161014081016001600160401b038111828210176200053e576040526200005a6101e062000599565b81526200006961020062000599565b60208201526200007b61022062000599565b60408201526200008d61024062000599565b6060820152610260516080820152620000a861028062000599565b60a082018190526102a05160c08301819052620000c76102c062000599565b60e08401526102e05163ffffffff811681036200055457610100840152620000f161030062000599565b61012084015260405191620001068362000559565b6001600160a01b0390811683526020830191909152606083015160808401516040519492909116620001388562000559565b845260208085019190915260e0820151610100830151604080850151938501519051936001600160a01b03918216939082169263ffffffff169116608085016001600160401b038111868210176200053e576040908152908552602080860192835285820193845260608601948552600180546001600160a01b0319163317815563656af49b60e11b6000908152600283527f9e240b0c7e84609200e93ba9845c3d5e9dd45bae450327302d09f6238d2addf0805460ff19908116841790915597516001600160a01b0390811660805294516003805463ffffffff191663ffffffff929092169190911790559451841660a0529451831660c0526368bcdd6d60e11b9093527f83e240a848583ccfe47465e0c75f5fa80c53130f94b6e26d488260e8ccd2232f8054909516909317909355855190921660e0819052905163313ce56760e01b81529190829060049082905afa9384156200051057620002b460ff6004966020946000916200051c575b50806101005216620005c9565b610120520151835563243cfb2160e21b600052600260209081527f0fa5156299ac68232eb6450d179dc9fb9e39a233deeb76250f3076520c631d50805460ff1916600117905582516001600160a01b031661014081905260405163313ce56760e01b815294859182905afa9283156200051057600093620004d8575b5060206200034760ff6101609580875216620005c9565b6101809081529201516005556101208101516001546001600160a01b0391821691829082167f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6600080a36001600160a01b031916176001908155600260209081527f787818a97fee4eb5ba8ee9b085b81a9e55a36aa9b59d6ee89e0fadc6e0b608e3805460ff199081168417909155632fa3fc3160e21b6000527fe17f8cf6562bc35c286c6773060c91482804c7e08955866957c8b34bf66775af805490911690921790915581516001600160a01b039081166101a09081529290910151166101c09081526040516116f09490939192919085620005ef8639608051858181610bbc015261155e015260a0518581816107ef01526115c8015260c0518581816106d001526115f0015260e051858181610d9f0152611387015261010051856108a401526101205185818161084901526112c6015261014051858181610780015261147501525184610c7701525183818161052001528181610647015261093b015251826110970152518161110b0152f35b6200050091935060203d60201162000508575b620004f7818362000575565b810190620005ae565b913862000330565b503d620004eb565b6040513d6000823e3d90fd5b620005379150853d87116200050857620004f7818362000575565b38620002a7565b634e487b7160e01b600052604160045260246000fd5b600080fd5b604081019081106001600160401b038211176200053e57604052565b601f909101601f19168101906001600160401b038211908210176200053e57604052565b51906001600160a01b03821682036200055457565b9081602091031262000554575160ff81168103620005545790565b604d8111620005d857600a0a90565b634e487b7160e01b600052601160045260246000fdfe608060408181526004918236101561001657600080fd5b600092833560e01c91826301ffc9a714610fa25750816306fdde0314610e4d578163090f3f5014610dfc5781630d623e1014610dc35781631588b0e01461041757816320bf30fc14610d54578163217a4b7014610be057816326d8954514610d11578163313ce56714610cd75781633aeef3d314610c9b5781633b17136a14610c3f5781633cb6f5fa14610be55781633e32ab4214610be0578163417d25a914610b715781634501409514610ac55781634bc66f3214610a725781634f8b4ae7146109a05781636ff484721461095e578163726de1a5146109055781637c99a499146108c85781638b8b2c911461086c5781638e7dc4c014610813578163993e3d54146107a457816399a64f28146107355781639c0d313f146106f4578163a2cc770314610685578163b9f53a6c146105f6578163bd9a548b146104c7578163c433c80a1461041c578163c55dae6314610417578163cede91a4146103db578163d2333be71461036c578163d7360946146102f657508063e2bab3b21461029e578063f6ccaad4146101f45763f97697ff146101b157600080fd5b346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209051670de0b6b3a76400008152f35b5080fd5b823461029b57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029b5761022b61117a565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000808254168255600154903373ffffffffffffffffffffffffffffffffffffffff83167f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc68580a316331760015580f35b80fd5b50346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576102f2906102d96112b0565b9151901515815260208101919091529081906040820190565b0390f35b9050346103685760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610368577f1b427db70b2e813aae1e9f4dc54fcd2ae904b1350f60b84a7bab7d379aa2b02e90359161035361112f565b6005548151908152836020820152a160055580f35b8280fd5b9050346103685760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610368577fd72ef688fa430b6a285b84371ba35e8a8e0762b32c1deb7be9d9c111ca79f5ea8135926103c961112f565b82548151908152846020820152a15580f35b90503461036857827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103685760209250549051908152f35b61104c565b9050346103685760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261036857359063ffffffff8083168093036104c3577fa5868b8f066a74ed982ad7843f1f76a16fc96b95c00596d6249b5fe5dee544137fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000926104a961112f565b6003549281519084168152856020820152a1161760035580f35b8380fd5b839150346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576105006112b0565b61050b94919461150e565b61054a610545610519611444565b92919490507f000000000000000000000000000000000000000000000000000000000000000090611235565b611277565b9386806105ef575b610592575060609515610572575050815b81519384526020840152820152f35b90929015610581575081610563565b918281106000036105635791610563565b60649060208551917f08c379a0000000000000000000000000000000000000000000000000000000008352820152601f60248201527f426f746820436861696e6c696e6b20616e6420545741502061726520626164006044820152fd5b5081610552565b82843461029b57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029b575061062f61150e565b6102f261066c610545610640611444565b92919590507f000000000000000000000000000000000000000000000000000000000000000090611235565b9251911515825260208201929092529081906040820190565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209051670de0b6b3a76400008152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f057602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020906005549051908152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f057602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209061099961150e565b9051908152f35b833461029b57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029b576109d761112f565b6109df61117a565b7fffffffffffffffffffffffff00000000000000000000000000000000000000008082541682556001548273ffffffffffffffffffffffffffffffffffffffff821681817f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a8280a37f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc68280a31660015580f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209073ffffffffffffffffffffffffffffffffffffffff600154169051908152f35b8390346101f05760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0573573ffffffffffffffffffffffffffffffffffffffff80821680920361036857610b1e61112f565b817fffffffffffffffffffffffff0000000000000000000000000000000000000000845416178355600154167f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a8380a380f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b6110c0565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576102f290610c21611444565b92519115158252602082015260408101919091529081906060820190565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576102f290610c21611356565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905160128152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209063ffffffff600354169051908152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05751908152602090f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05773ffffffffffffffffffffffffffffffffffffffff60209254169051908152f35b90503461036857827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261036857815190608082019082821067ffffffffffffffff831117610f7657508252604781526020907f41706520436f696e204475616c204f7261636c6520436861696e6c696e6b2077828201527f697468205374616c656e65737320436865636b20616e6420556e697377617020838201527f5633205457415000000000000000000000000000000000000000000000000000606082015282519382859384528251928382860152825b848110610f6057505050828201840152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168101030190f35b8181018301518882018801528795508201610f24565b8460416024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b929150346104c35760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104c35735907fffffffff0000000000000000000000000000000000000000000000000000000082168092036104c3576020937f01ffc9a7000000000000000000000000000000000000000000000000000000008314928315611037575b50505015158152f35b60ff935081526002855220541638808061102e565b346110bb5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126110bb57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b600080fd5b346110bb5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126110bb57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b73ffffffffffffffffffffffffffffffffffffffff60015416330361115057565b60046040517f1c0be90a000000000000000000000000000000000000000000000000000000008152fd5b73ffffffffffffffffffffffffffffffffffffffff60005416330361119b57565b60046040517ff5c49e64000000000000000000000000000000000000000000000000000000008152fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761120657604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291811591840414171561124857565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8115611281570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000906112bb611356565b670de0b6b3a76400007f00000000000000000000000000000000000000000000000000000000000000008181029450919250830403611248576112fd91611277565b90565b519069ffffffffffffffffffff821682036110bb57565b908160a09103126110bb5761132b81611300565b916020820151916040810151916112fd608060608401519301611300565b9190820391821161124857565b6040517ffeaf968c00000000000000000000000000000000000000000000000000000000815260009160a0826004817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff165afa918215611438576000908193611402575b508260008213908115916113ed575b506113e65790565b6001935090565b6113f8915042611349565b60045410386113de565b905061142691925060a03d8111611431575b61141e81836111c5565b810190611317565b5093925050386113cf565b503d611414565b6040513d6000823e3d90fd5b6040517ffeaf968c00000000000000000000000000000000000000000000000000000000815260009160a0826004817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff165afa9182156114385760009081936114e8575b508260008213908115916114d357506113e65790565b6114de915042611349565b60055410386113de565b905061150391925060a03d81116114315761141e81836111c5565b5093925050386114bd565b6040516040810181811067ffffffffffffffff8211176112065760405260019081815260209081810190823683378051156116b457829073ffffffffffffffffffffffffffffffffffffffff92837f000000000000000000000000000000000000000000000000000000000000000016815263ffffffff600354166040519687937f07f7ca9f00000000000000000000000000000000000000000000000000000000855260a4850190670de0b6b3a76400006004870152877f0000000000000000000000000000000000000000000000000000000000000000166024870152877f000000000000000000000000000000000000000000000000000000000000000016604487015260a060648701525180915260c4850193966000905b8282106116985750505050829394506084830152038173b210ce856631eeeb767efa666ec7c1c57738d4385afa9081156114385760009161166c575b50905090565b82813d8311611691575b61168081836111c5565b8101031261029b5750518038611666565b503d611676565b8851811686529787019789978b9750909501949083019061162a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c6343000813000a000000000000000000000000853d955acef822db058eb8505911ed77f175b99e0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000d10abbc76679a20055e167bb80a24ac851b3705600000000000000000000000000000000000000000000000000000000000152ac0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84190000000000000000000000000000000000000000000000000000000000000f3c000000000000000000000000ac4b3dacb91461209ae9d41ec517c2b9cb1b7daf00000000000000000000000000000000000000000000000000000000000003840000000000000000000000008412ebf45bac1b340bbe8f318b928c466c4e39ca

Deployed Bytecode

0x608060408181526004918236101561001657600080fd5b600092833560e01c91826301ffc9a714610fa25750816306fdde0314610e4d578163090f3f5014610dfc5781630d623e1014610dc35781631588b0e01461041757816320bf30fc14610d54578163217a4b7014610be057816326d8954514610d11578163313ce56714610cd75781633aeef3d314610c9b5781633b17136a14610c3f5781633cb6f5fa14610be55781633e32ab4214610be0578163417d25a914610b715781634501409514610ac55781634bc66f3214610a725781634f8b4ae7146109a05781636ff484721461095e578163726de1a5146109055781637c99a499146108c85781638b8b2c911461086c5781638e7dc4c014610813578163993e3d54146107a457816399a64f28146107355781639c0d313f146106f4578163a2cc770314610685578163b9f53a6c146105f6578163bd9a548b146104c7578163c433c80a1461041c578163c55dae6314610417578163cede91a4146103db578163d2333be71461036c578163d7360946146102f657508063e2bab3b21461029e578063f6ccaad4146101f45763f97697ff146101b157600080fd5b346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209051670de0b6b3a76400008152f35b5080fd5b823461029b57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029b5761022b61117a565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000808254168255600154903373ffffffffffffffffffffffffffffffffffffffff83167f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc68580a316331760015580f35b80fd5b50346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576102f2906102d96112b0565b9151901515815260208101919091529081906040820190565b0390f35b9050346103685760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610368577f1b427db70b2e813aae1e9f4dc54fcd2ae904b1350f60b84a7bab7d379aa2b02e90359161035361112f565b6005548151908152836020820152a160055580f35b8280fd5b9050346103685760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610368577fd72ef688fa430b6a285b84371ba35e8a8e0762b32c1deb7be9d9c111ca79f5ea8135926103c961112f565b82548151908152846020820152a15580f35b90503461036857827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103685760209250549051908152f35b61104c565b9050346103685760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261036857359063ffffffff8083168093036104c3577fa5868b8f066a74ed982ad7843f1f76a16fc96b95c00596d6249b5fe5dee544137fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000926104a961112f565b6003549281519084168152856020820152a1161760035580f35b8380fd5b839150346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576105006112b0565b61050b94919461150e565b61054a610545610519611444565b92919490507f0000000000000000000000000000000000000000000000000000000005f5e10090611235565b611277565b9386806105ef575b610592575060609515610572575050815b81519384526020840152820152f35b90929015610581575081610563565b918281106000036105635791610563565b60649060208551917f08c379a0000000000000000000000000000000000000000000000000000000008352820152601f60248201527f426f746820436861696e6c696e6b20616e6420545741502061726520626164006044820152fd5b5081610552565b82843461029b57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029b575061062f61150e565b6102f261066c610545610640611444565b92919590507f0000000000000000000000000000000000000000000000000000000005f5e10090611235565b9251911515825260208201929092529081906040820190565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209051670de0b6b3a76400008152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f057602090517f0000000000000000000000000000000000000000000000000000000005f5e1008152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905160ff7f0000000000000000000000000000000000000000000000000000000000000008168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020906005549051908152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f057602090517f0000000000000000000000000000000000000000000000000000000005f5e1008152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209061099961150e565b9051908152f35b833461029b57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029b576109d761112f565b6109df61117a565b7fffffffffffffffffffffffff00000000000000000000000000000000000000008082541682556001548273ffffffffffffffffffffffffffffffffffffffff821681817f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a8280a37f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc68280a31660015580f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209073ffffffffffffffffffffffffffffffffffffffff600154169051908152f35b8390346101f05760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0573573ffffffffffffffffffffffffffffffffffffffff80821680920361036857610b1e61112f565b817fffffffffffffffffffffffff0000000000000000000000000000000000000000845416178355600154167f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a8380a380f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ac4b3dacb91461209ae9d41ec517c2b9cb1b7daf168152f35b6110c0565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576102f290610c21611444565b92519115158252602082015260408101919091529081906060820190565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905160ff7f0000000000000000000000000000000000000000000000000000000000000008168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576102f290610c21611356565b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905160128152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05760209063ffffffff600354169051908152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f0576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d10abbc76679a20055e167bb80a24ac851b37056168152f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05751908152602090f35b5050346101f057817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101f05773ffffffffffffffffffffffffffffffffffffffff60209254169051908152f35b90503461036857827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261036857815190608082019082821067ffffffffffffffff831117610f7657508252604781526020907f41706520436f696e204475616c204f7261636c6520436861696e6c696e6b2077828201527f697468205374616c656e65737320436865636b20616e6420556e697377617020838201527f5633205457415000000000000000000000000000000000000000000000000000606082015282519382859384528251928382860152825b848110610f6057505050828201840152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168101030190f35b8181018301518882018801528795508201610f24565b8460416024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b929150346104c35760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104c35735907fffffffff0000000000000000000000000000000000000000000000000000000082168092036104c3576020937f01ffc9a7000000000000000000000000000000000000000000000000000000008314928315611037575b50505015158152f35b60ff935081526002855220541638808061102e565b346110bb5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126110bb57602060405173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000853d955acef822db058eb8505911ed77f175b99e168152f35b600080fd5b346110bb5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126110bb57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381168152f35b73ffffffffffffffffffffffffffffffffffffffff60015416330361115057565b60046040517f1c0be90a000000000000000000000000000000000000000000000000000000008152fd5b73ffffffffffffffffffffffffffffffffffffffff60005416330361119b57565b60046040517ff5c49e64000000000000000000000000000000000000000000000000000000008152fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761120657604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8181029291811591840414171561124857565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8115611281570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000906112bb611356565b670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000005f5e1008181029450919250830403611248576112fd91611277565b90565b519069ffffffffffffffffffff821682036110bb57565b908160a09103126110bb5761132b81611300565b916020820151916040810151916112fd608060608401519301611300565b9190820391821161124857565b6040517ffeaf968c00000000000000000000000000000000000000000000000000000000815260009160a0826004817f000000000000000000000000d10abbc76679a20055e167bb80a24ac851b3705673ffffffffffffffffffffffffffffffffffffffff165afa918215611438576000908193611402575b508260008213908115916113ed575b506113e65790565b6001935090565b6113f8915042611349565b60045410386113de565b905061142691925060a03d8111611431575b61141e81836111c5565b810190611317565b5093925050386113cf565b503d611414565b6040513d6000823e3d90fd5b6040517ffeaf968c00000000000000000000000000000000000000000000000000000000815260009160a0826004817f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b841973ffffffffffffffffffffffffffffffffffffffff165afa9182156114385760009081936114e8575b508260008213908115916114d357506113e65790565b6114de915042611349565b60055410386113de565b905061150391925060a03d81116114315761141e81836111c5565b5093925050386114bd565b6040516040810181811067ffffffffffffffff8211176112065760405260019081815260209081810190823683378051156116b457829073ffffffffffffffffffffffffffffffffffffffff92837f000000000000000000000000ac4b3dacb91461209ae9d41ec517c2b9cb1b7daf16815263ffffffff600354166040519687937f07f7ca9f00000000000000000000000000000000000000000000000000000000855260a4850190670de0b6b3a76400006004870152877f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2166024870152877f0000000000000000000000004d224452801aced8b2f0aebe155379bb5d59438116604487015260a060648701525180915260c4850193966000905b8282106116985750505050829394506084830152038173b210ce856631eeeb767efa666ec7c1c57738d4385afa9081156114385760009161166c575b50905090565b82813d8311611691575b61168081836111c5565b8101031261029b5750518038611666565b503d611676565b8851811686529787019789978b9750909501949083019061162a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea164736f6c6343000813000a

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

000000000000000000000000853d955acef822db058eb8505911ed77f175b99e0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000d10abbc76679a20055e167bb80a24ac851b3705600000000000000000000000000000000000000000000000000000000000152ac0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84190000000000000000000000000000000000000000000000000000000000000f3c000000000000000000000000ac4b3dacb91461209ae9d41ec517c2b9cb1b7daf00000000000000000000000000000000000000000000000000000000000003840000000000000000000000008412ebf45bac1b340bbe8f318b928c466c4e39ca

-----Decoded View---------------
Arg [0] : _params (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000853d955acef822db058eb8505911ed77f175b99e
Arg [1] : 0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 000000000000000000000000d10abbc76679a20055e167bb80a24ac851b37056
Arg [4] : 00000000000000000000000000000000000000000000000000000000000152ac
Arg [5] : 0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000f3c
Arg [7] : 000000000000000000000000ac4b3dacb91461209ae9d41ec517c2b9cb1b7daf
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000384
Arg [9] : 0000000000000000000000008412ebf45bac1b340bbe8f318b928c466c4e39ca


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.