Contract 0x86E8cB7Cd38F7dE6Ef7fb62A5D7cCEe350C40310 3

 
Txn Hash Method
Block
From
To
Value
0xd29b2265b16337148b3168fe38480d8af6eedf4194da0bc1b306fdd40540e183Set Pending Gove...87972292022-05-22 19:18:18675 days 22 hrs ago0x1a00e1e311009e56e3b0b9ed6f86f5ce128a1c01 IN  0x86e8cb7cd38f7de6ef7fb62a5d7ccee350c403100 ETH0.0000708963730.001
0xa7a5d2a6e872069cbc9e0e4acd9ccbe3911abc57421ea6c8ae114fc2cfc84be3Add Mappings83711712022-05-16 3:32:13682 days 14 hrs ago0x1a00e1e311009e56e3b0b9ed6f86f5ce128a1c01 IN  0x86e8cb7cd38f7de6ef7fb62a5d7ccee350c403100 ETH0.0000852104730.001
0xf9adf659240f434083e6e6ef10c377ac4dd21bdb80414c397ff4737fa8c69fbdAdd USD Stableco...83711452022-05-16 3:31:42682 days 14 hrs ago0x1a00e1e311009e56e3b0b9ed6f86f5ce128a1c01 IN  0x86e8cb7cd38f7de6ef7fb62a5d7ccee350c403100 ETH0.0000922367380.001
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x93931391b70328892e890dd066cb7891792201dc08dd91f0ebd80fced537184183707942022-05-16 3:25:30682 days 14 hrs ago 0x123c098069dea70e8f2c5f37819fb33c41392c47  Contract Creation0 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChainlinkOracle

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 9999 runs

Other Settings:
default evmVersion
File 1 of 12 : ChainlinkOracle.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.8.7 <0.9.0;

import '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
import '@chainlink/contracts/src/v0.8/Denominations.sol';
import '../interfaces/oracles/IChainlinkOracle.sol';
import '../libraries/TokenSorting.sol';
import '../utils/Governable.sol';

contract ChainlinkOracle is Governable, IChainlinkOracle {
  /// @inheritdoc IChainlinkOracle
  mapping(address => mapping(address => PricingPlan)) public planForPair;
  /// @inheritdoc IChainlinkOracle
  FeedRegistryInterface public immutable registry;
  /// @inheritdoc IChainlinkOracle
  // solhint-disable-next-line var-name-mixedcase
  address public immutable WETH;
  /// @inheritdoc IChainlinkOracle
  uint32 public maxDelay;

  // solhint-disable private-vars-leading-underscore
  // Addresses in Ethereum Mainnet
  address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
  address private constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
  address private constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
  address private constant RENBTC = 0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D;
  address private constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;
  int8 private constant USD_DECIMALS = 8;
  int8 private constant ETH_DECIMALS = 18;
  // solhint-enable private-vars-leading-underscore

  mapping(address => bool) internal _shouldBeConsideredUSD;
  mapping(address => address) internal _tokenMappings;

  constructor(
    // solhint-disable-next-line var-name-mixedcase
    address _WETH,
    FeedRegistryInterface _registry,
    uint32 _maxDelay,
    address _governor
  ) Governable(_governor) {
    if (_WETH == address(0) || address(_registry) == address(0)) revert ZeroAddress();
    if (_maxDelay == 0) revert ZeroMaxDelay();
    registry = _registry;
    maxDelay = _maxDelay;
    WETH = _WETH;
  }

  /// @inheritdoc IPriceOracle
  function canSupportPair(address _tokenA, address _tokenB) external view returns (bool) {
    (address __tokenA, address __tokenB) = TokenSorting.sortTokens(_tokenA, _tokenB);
    PricingPlan _plan = _determinePricingPlan(__tokenA, __tokenB);
    return _plan != PricingPlan.NONE;
  }

  /// @inheritdoc IPriceOracle
  function quote(
    address _tokenIn,
    uint128 _amountIn,
    address _tokenOut
  ) external view returns (uint256 _amountOut) {
    (address _tokenA, address _tokenB) = TokenSorting.sortTokens(_tokenIn, _tokenOut);
    PricingPlan _plan = planForPair[_tokenA][_tokenB];
    if (_plan == PricingPlan.NONE) revert PairNotSupported();

    int8 _inDecimals = _getDecimals(_tokenIn);
    int8 _outDecimals = _getDecimals(_tokenOut);

    if (_plan <= PricingPlan.TOKEN_ETH_PAIR) {
      return _getDirectPrice(_tokenIn, _tokenOut, _inDecimals, _outDecimals, _amountIn, _plan);
    } else if (_plan <= PricingPlan.TOKEN_TO_ETH_TO_TOKEN_PAIR) {
      return _getPriceSameBase(_tokenIn, _tokenOut, _inDecimals, _outDecimals, _amountIn, _plan);
    } else {
      return _getPriceDifferentBases(_tokenIn, _tokenOut, _inDecimals, _outDecimals, _amountIn, _plan);
    }
  }

  /// @inheritdoc IPriceOracle
  function reconfigureSupportForPair(address _tokenA, address _tokenB) external {
    _addSupportForPair(_tokenA, _tokenB);
  }

  /// @inheritdoc IPriceOracle
  function addSupportForPairIfNeeded(address _tokenA, address _tokenB) external {
    (address __tokenA, address __tokenB) = TokenSorting.sortTokens(_tokenA, _tokenB);
    if (planForPair[__tokenA][__tokenB] == PricingPlan.NONE) {
      _addSupportForPair(_tokenA, _tokenB);
    }
  }

  function _addSupportForPair(address _tokenA, address _tokenB) internal virtual {
    (address __tokenA, address __tokenB) = TokenSorting.sortTokens(_tokenA, _tokenB);
    PricingPlan _plan = _determinePricingPlan(__tokenA, __tokenB);
    if (_plan == PricingPlan.NONE) revert PairNotSupported();
    planForPair[__tokenA][__tokenB] = _plan;
    emit AddedSupportForPairInChainlinkOracle(__tokenA, __tokenB);
  }

  /// @inheritdoc IChainlinkOracle
  function addUSDStablecoins(address[] calldata _addresses) external onlyGovernor {
    for (uint256 i; i < _addresses.length; i++) {
      _shouldBeConsideredUSD[_addresses[i]] = true;
    }
    emit TokensConsideredUSD(_addresses);
  }

  /// @inheritdoc IChainlinkOracle
  function addMappings(address[] calldata _addresses, address[] calldata _mappings) external onlyGovernor {
    if (_addresses.length != _mappings.length) revert InvalidMappingsInput();
    for (uint256 i; i < _addresses.length; i++) {
      _tokenMappings[_addresses[i]] = _mappings[i];
    }
    emit MappingsAdded(_addresses, _mappings);
  }

  /// @inheritdoc IChainlinkOracle
  function setMaxDelay(uint32 _maxDelay) external onlyGovernor {
    maxDelay = _maxDelay;
    emit MaxDelaySet(_maxDelay);
  }

  /// @inheritdoc IChainlinkOracle
  function mappedToken(address _token) public view returns (address) {
    if (block.chainid == 1 && (_token == RENBTC || _token == WBTC)) {
      return Denominations.BTC;
    } else {
      address _mapping = _tokenMappings[_token];
      return _mapping != address(0) ? _mapping : _token;
    }
  }

  /** Handles prices when the pair is either ETH/USD, token/ETH or token/USD */
  function _getDirectPrice(
    address _tokenIn,
    address _tokenOut,
    int8 _inDecimals,
    int8 _outDecimals,
    uint256 _amountIn,
    PricingPlan _plan
  ) internal view returns (uint256) {
    uint256 _price;
    int8 _resultDecimals = _plan == PricingPlan.TOKEN_ETH_PAIR ? ETH_DECIMALS : USD_DECIMALS;
    bool _needsInverting = _isUSD(_tokenIn) || (_plan == PricingPlan.TOKEN_ETH_PAIR && _tokenIn == WETH);

    if (_plan == PricingPlan.ETH_USD_PAIR) {
      _price = _getETHUSD();
    } else if (_plan == PricingPlan.TOKEN_USD_PAIR) {
      _price = _getPriceAgainstUSD(_isUSD(_tokenOut) ? _tokenIn : _tokenOut);
    } else if (_plan == PricingPlan.TOKEN_ETH_PAIR) {
      _price = _getPriceAgainstETH(_tokenOut == WETH ? _tokenIn : _tokenOut);
    }
    if (!_needsInverting) {
      return _adjustDecimals(_price * _amountIn, _outDecimals - _resultDecimals - _inDecimals);
    } else {
      return _adjustDecimals(_adjustDecimals(_amountIn, _resultDecimals + _outDecimals) / _price, -_inDecimals);
    }
  }

  /** Handles prices when both tokens share the same base (either ETH or USD) */
  function _getPriceSameBase(
    address _tokenIn,
    address _tokenOut,
    int8 _inDecimals,
    int8 _outDecimals,
    uint256 _amountIn,
    PricingPlan _plan
  ) internal view returns (uint256) {
    address _base = _plan == PricingPlan.TOKEN_TO_USD_TO_TOKEN_PAIR ? Denominations.USD : Denominations.ETH;
    uint256 _tokenInToBase = _callRegistry(mappedToken(_tokenIn), _base);
    uint256 _tokenOutToBase = _callRegistry(mappedToken(_tokenOut), _base);
    return _adjustDecimals((_amountIn * _tokenInToBase) / _tokenOutToBase, _outDecimals - _inDecimals);
  }

  /** Handles prices when one of the tokens uses ETH as the base, and the other USD */
  function _getPriceDifferentBases(
    address _tokenIn,
    address _tokenOut,
    int8 _inDecimals,
    int8 _outDecimals,
    uint256 _amountIn,
    PricingPlan _plan
  ) internal view returns (uint256) {
    bool _isTokenInUSD = (_plan == PricingPlan.TOKEN_A_TO_USD_TO_ETH_TO_TOKEN_B && _tokenIn < _tokenOut) ||
      (_plan == PricingPlan.TOKEN_A_TO_ETH_TO_USD_TO_TOKEN_B && _tokenIn > _tokenOut);
    uint256 _ethToUSDPrice = _getETHUSD();
    if (_isTokenInUSD) {
      uint256 _tokenInToUSD = _getPriceAgainstUSD(_tokenIn);
      uint256 _tokenOutToETH = _getPriceAgainstETH(_tokenOut);
      uint256 _adjustedInUSDValue = _adjustDecimals(_amountIn * _tokenInToUSD, _outDecimals - _inDecimals + ETH_DECIMALS);
      return _adjustedInUSDValue / _ethToUSDPrice / _tokenOutToETH;
    } else {
      uint256 _tokenInToETH = _getPriceAgainstETH(_tokenIn);
      uint256 _tokenOutToUSD = _getPriceAgainstUSD(_tokenOut);
      return _adjustDecimals((_amountIn * _tokenInToETH * _ethToUSDPrice) / _tokenOutToUSD, _outDecimals - _inDecimals - ETH_DECIMALS);
    }
  }

  function _getPriceAgainstUSD(address _token) internal view returns (uint256) {
    return _isUSD(_token) ? 1e8 : _callRegistry(mappedToken(_token), Denominations.USD);
  }

  function _getPriceAgainstETH(address _token) internal view returns (uint256) {
    return _token == WETH ? 1e18 : _callRegistry(mappedToken(_token), Denominations.ETH);
  }

  function _determinePricingPlan(address _tokenA, address _tokenB) internal view virtual returns (PricingPlan) {
    bool _isTokenAUSD = _isUSD(_tokenA);
    bool _isTokenBUSD = _isUSD(_tokenB);
    bool _isTokenAETH = _tokenA == WETH;
    bool _isTokenBETH = _tokenB == WETH;
    if ((_isTokenAETH && _isTokenBUSD) || (_isTokenAUSD && _isTokenBETH)) {
      // Note: there are stablecoins/ETH pairs on Chainlink, but they are updated less often than the USD/ETH pair.
      // That's why we prefer to use the USD/ETH pair instead
      return PricingPlan.ETH_USD_PAIR;
    } else if (_isTokenBUSD && !_isTokenAUSD) {
      return _tryWithBases(_tokenA, PricingPlan.TOKEN_USD_PAIR, PricingPlan.TOKEN_A_TO_ETH_TO_USD_TO_TOKEN_B);
    } else if (_isTokenAUSD && !_isTokenBUSD) {
      return _tryWithBases(_tokenB, PricingPlan.TOKEN_USD_PAIR, PricingPlan.TOKEN_A_TO_USD_TO_ETH_TO_TOKEN_B);
    } else if (_isTokenBETH) {
      return _tryWithBases(_tokenA, PricingPlan.TOKEN_A_TO_USD_TO_ETH_TO_TOKEN_B, PricingPlan.TOKEN_ETH_PAIR);
    } else if (_isTokenAETH) {
      return _tryWithBases(_tokenB, PricingPlan.TOKEN_A_TO_ETH_TO_USD_TO_TOKEN_B, PricingPlan.TOKEN_ETH_PAIR);
    } else if (_exists(_tokenA, Denominations.USD)) {
      return _tryWithBases(_tokenB, PricingPlan.TOKEN_TO_USD_TO_TOKEN_PAIR, PricingPlan.TOKEN_A_TO_USD_TO_ETH_TO_TOKEN_B);
    } else if (_exists(_tokenA, Denominations.ETH)) {
      return _tryWithBases(_tokenB, PricingPlan.TOKEN_A_TO_ETH_TO_USD_TO_TOKEN_B, PricingPlan.TOKEN_TO_ETH_TO_TOKEN_PAIR);
    }
    return PricingPlan.NONE;
  }

  function _tryWithBases(
    address _token,
    PricingPlan _ifUSD,
    PricingPlan _ifETH
  ) internal view returns (PricingPlan) {
    // Note: we are prioritizing plans that have fewer external calls
    (address _firstBase, PricingPlan _firstResult, address _secondBaseBase, PricingPlan _secondResult) = _ifUSD < _ifETH
      ? (Denominations.USD, _ifUSD, Denominations.ETH, _ifETH)
      : (Denominations.ETH, _ifETH, Denominations.USD, _ifUSD);
    if (_exists(_token, _firstBase)) {
      return _firstResult;
    } else if (_exists(_token, _secondBaseBase)) {
      return _secondResult;
    } else {
      return PricingPlan.NONE;
    }
  }

  function _exists(address _base, address _quote) internal view returns (bool) {
    try registry.latestRoundData(mappedToken(_base), _quote) returns (uint80, int256 _price, uint256, uint256, uint80) {
      return _price > 0;
    } catch {
      return false;
    }
  }

  function _adjustDecimals(uint256 _amount, int256 _factor) internal pure returns (uint256) {
    if (_factor < 0) {
      return _amount / (10**uint256(-_factor));
    } else {
      return _amount * (10**uint256(_factor));
    }
  }

  function _getDecimals(address _token) internal view returns (int8) {
    return int8(IERC20Metadata(_token).decimals());
  }

  function _callRegistry(address _base, address _quote) internal view returns (uint256) {
    (, int256 _price, , uint256 _updatedAt, ) = registry.latestRoundData(_base, _quote);
    if (_price <= 0) revert InvalidPrice();
    if (maxDelay < block.timestamp && _updatedAt < block.timestamp - maxDelay) revert LastUpdateIsTooOld();
    return uint256(_price);
  }

  function _getETHUSD() internal view returns (uint256) {
    return _callRegistry(Denominations.ETH, Denominations.USD);
  }

  function _isUSD(address _token) internal view returns (bool) {
    // We are doing this, to avoid expensive storage read
    bool _isHardcodedUSDInMainnet = block.chainid == 1 && (_token == DAI || _token == USDC || _token == USDT);
    return _isHardcodedUSDInMainnet || _shouldBeConsideredUSD[_token];
  }
}

File 2 of 12 : 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 12 : Denominations.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library Denominations {
  address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
  address public constant BTC = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;

  // Fiat currencies follow https://en.wikipedia.org/wiki/ISO_4217
  address public constant USD = address(840);
  address public constant GBP = address(826);
  address public constant EUR = address(978);
  address public constant JPY = address(392);
  address public constant KRW = address(410);
  address public constant CNY = address(156);
  address public constant AUD = address(36);
  address public constant CAD = address(124);
  address public constant CHF = address(756);
  address public constant ARS = address(32);
  address public constant PHP = address(608);
  address public constant NZD = address(554);
  address public constant SGD = address(702);
  address public constant NGN = address(566);
  address public constant ZAR = address(710);
  address public constant RUB = address(643);
  address public constant INR = address(356);
  address public constant BRL = address(986);
}

File 4 of 12 : IChainlinkOracle.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

import '@chainlink/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol';
import './IPriceOracle.sol';

/// @title An implementation of IPriceOracle that uses Chainlink feeds
/// @notice This oracle will attempt to use all available feeds to determine prices between pairs
interface IChainlinkOracle is IPriceOracle {
  /// @notice The plan that will be used to calculate quotes for a given pair
  enum PricingPlan {
    // There is no plan calculated
    NONE,
    // Will use the ETH/USD feed
    ETH_USD_PAIR,
    // Will use a token/USD feed
    TOKEN_USD_PAIR,
    // Will use a token/ETH feed
    TOKEN_ETH_PAIR,
    // Will use tokenIn/USD and tokenOut/USD feeds
    TOKEN_TO_USD_TO_TOKEN_PAIR,
    // Will use tokenIn/ETH and tokenOut/ETH feeds
    TOKEN_TO_ETH_TO_TOKEN_PAIR,
    // Will use tokenA/USD, tokenB/ETH and ETH/USD feeds
    TOKEN_A_TO_USD_TO_ETH_TO_TOKEN_B,
    // Will use tokenA/ETH, tokenB/USD and ETH/USD feeds
    TOKEN_A_TO_ETH_TO_USD_TO_TOKEN_B
  }

  /// @notice Emitted when the oracle add supports for a new pair
  /// @param tokenA One of the pair's tokens
  /// @param tokenB The other of the pair's tokens
  event AddedSupportForPairInChainlinkOracle(address tokenA, address tokenB);

  /// @notice Emitted when new tokens are considered USD
  /// @param tokens The new tokens
  event TokensConsideredUSD(address[] tokens);

  /// @notice Emitted when new mappings are added
  /// @param tokens The tokens
  /// @param mappings Their new mappings
  event MappingsAdded(address[] tokens, address[] mappings);

  /// @notice Emitted when a new max delay is set
  /// @param newMaxDelay The new max delay
  event MaxDelaySet(uint32 newMaxDelay);

  /// @notice Thrown when the price is non-positive
  error InvalidPrice();

  /// @notice Thrown when the last price update was too long ago
  error LastUpdateIsTooOld();

  /// @notice Thrown when one of the parameters is a zero address
  error ZeroAddress();

  /// @notice Thrown when the given max delay is zero
  error ZeroMaxDelay();

  /// @notice Thrown when trying to configure a pair that is not supported
  error PairNotSupported();

  /// @notice Thrown when the input for adding mappings in invalid
  error InvalidMappingsInput();

  /// @notice Returns the Chainlink feed registry
  /// @return The Chainlink registry
  function registry() external view returns (FeedRegistryInterface);

  /// @notice Returns how old the last price update can be before the oracle reverts by considering it too old
  /// @return How old the last price update can be in seconds
  function maxDelay() external view returns (uint32);

  /// @notice Returns the address of the WETH ERC-20 token
  /// @return The address of the token
  // solhint-disable-next-line func-name-mixedcase
  function WETH() external view returns (address);

  /// @notice Returns the pricing plan that will be used when quoting the given pair
  /// @dev It is expected that _tokenA < _tokenB
  /// @return The pricing plan that will be used
  function planForPair(address _tokenA, address _tokenB) external view returns (PricingPlan);

  /// @notice Returns the mapping of the given token, if it exists. If it doesn't, then the original token is returned
  /// @return If it exists, the mapping is returned. Otherwise, the original token is returned
  function mappedToken(address _token) external view returns (address);

  /// @notice Adds new tokens that should be considered USD stablecoins
  /// @param _addresses The addresses of the tokens
  function addUSDStablecoins(address[] calldata _addresses) external;

  /// @notice Adds new token mappings
  /// @param _addresses The addresses of the tokens
  /// @param _mappings The addresses of their mappings
  function addMappings(address[] calldata _addresses, address[] calldata _mappings) external;

  /// @notice Sets a new max delay
  /// @param _maxDelay The new max delay
  function setMaxDelay(uint32 _maxDelay) external;
}

File 5 of 12 : TokenSorting.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >0.6;

/// @title TokenSorting library
/// @notice Provides functions to sort tokens easily
library TokenSorting {
  /// @notice Takes two tokens, and returns them sorted
  /// @param _tokenA One of the tokens
  /// @param _tokenB The other token
  /// @return __tokenA The first of the tokens
  /// @return __tokenB The second of the tokens
  function sortTokens(address _tokenA, address _tokenB) internal pure returns (address __tokenA, address __tokenB) {
    (__tokenA, __tokenB) = _tokenA < _tokenB ? (_tokenA, _tokenB) : (_tokenB, _tokenA);
  }
}

File 6 of 12 : Governable.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity >=0.7.0;

interface IGovernable {
  event PendingGovernorSet(address pendingGovernor);
  event PendingGovernorAccepted();

  function setPendingGovernor(address _pendingGovernor) external;

  function acceptPendingGovernor() external;

  function governor() external view returns (address);

  function pendingGovernor() external view returns (address);

  function isGovernor(address _account) external view returns (bool _isGovernor);

  function isPendingGovernor(address _account) external view returns (bool _isPendingGovernor);
}

abstract contract Governable is IGovernable {
  address private _governor;
  address private _pendingGovernor;

  constructor(address __governor) {
    require(__governor != address(0), 'Governable: zero address');
    _governor = __governor;
  }

  function governor() external view override returns (address) {
    return _governor;
  }

  function pendingGovernor() external view override returns (address) {
    return _pendingGovernor;
  }

  function setPendingGovernor(address __pendingGovernor) external virtual override onlyGovernor {
    _setPendingGovernor(__pendingGovernor);
  }

  function _setPendingGovernor(address __pendingGovernor) internal {
    require(__pendingGovernor != address(0), 'Governable: zero address');
    _pendingGovernor = __pendingGovernor;
    emit PendingGovernorSet(__pendingGovernor);
  }

  function acceptPendingGovernor() external virtual override onlyPendingGovernor {
    _acceptPendingGovernor();
  }

  function _acceptPendingGovernor() internal {
    require(_pendingGovernor != address(0), 'Governable: no pending governor');
    _governor = _pendingGovernor;
    _pendingGovernor = address(0);
    emit PendingGovernorAccepted();
  }

  function isGovernor(address _account) public view override returns (bool _isGovernor) {
    return _account == _governor;
  }

  function isPendingGovernor(address _account) public view override returns (bool _isPendingGovernor) {
    return _account == _pendingGovernor;
  }

  modifier onlyGovernor() {
    require(isGovernor(msg.sender), 'Governable: only governor');
    _;
  }

  modifier onlyPendingGovernor() {
    require(isPendingGovernor(msg.sender), 'Governable: only pending governor');
    _;
  }
}

File 7 of 12 : 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 8 of 12 : FeedRegistryInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma abicoder v2;

import "./AggregatorV2V3Interface.sol";

interface FeedRegistryInterface {
  struct Phase {
    uint16 phaseId;
    uint80 startingAggregatorRoundId;
    uint80 endingAggregatorRoundId;
  }

  event FeedProposed(
    address indexed asset,
    address indexed denomination,
    address indexed proposedAggregator,
    address currentAggregator,
    address sender
  );
  event FeedConfirmed(
    address indexed asset,
    address indexed denomination,
    address indexed latestAggregator,
    address previousAggregator,
    uint16 nextPhaseId,
    address sender
  );

  // V3 AggregatorV3Interface

  function decimals(
    address base,
    address quote
  )
    external
    view
    returns (
      uint8
    );

  function description(
    address base,
    address quote
  )
    external
    view
    returns (
      string memory
    );

  function version(
    address base,
    address quote
  )
    external
    view
    returns (
      uint256
    );

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

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

  // V2 AggregatorInterface

  function latestAnswer(
    address base,
    address quote
  )
    external
    view
    returns (
      int256 answer
    );

  function latestTimestamp(
    address base,
    address quote
  )
    external
    view
    returns (
      uint256 timestamp
    );

  function latestRound(
    address base,
    address quote
  )
    external
    view
    returns (
      uint256 roundId
    );

  function getAnswer(
    address base,
    address quote,
    uint256 roundId
  )
    external
    view
    returns (
      int256 answer
    );

  function getTimestamp(
    address base,
    address quote,
    uint256 roundId
  )
    external
    view
    returns (
      uint256 timestamp
    );

  // Registry getters

  function getFeed(
    address base,
    address quote
  )
    external
    view
    returns (
      AggregatorV2V3Interface aggregator
    );

  function getPhaseFeed(
    address base,
    address quote,
    uint16 phaseId
  )
    external
    view
    returns (
      AggregatorV2V3Interface aggregator
    );

  function isFeedEnabled(
    address aggregator
  )
    external
    view
    returns (
      bool
    );

  function getPhase(
    address base,
    address quote,
    uint16 phaseId
  )
    external
    view
    returns (
      Phase memory phase
    );

  // Round helpers

  function getRoundFeed(
    address base,
    address quote,
    uint80 roundId
  )
    external
    view
    returns (
      AggregatorV2V3Interface aggregator
    );

  function getPhaseRange(
    address base,
    address quote,
    uint16 phaseId
  )
    external
    view
    returns (
      uint80 startingRoundId,
      uint80 endingRoundId
    );

  function getPreviousRoundId(
    address base,
    address quote,
    uint80 roundId
  ) external
    view
    returns (
      uint80 previousRoundId
    );

  function getNextRoundId(
    address base,
    address quote,
    uint80 roundId
  ) external
    view
    returns (
      uint80 nextRoundId
    );

  // Feed management

  function proposeFeed(
    address base,
    address quote,
    address aggregator
  ) external;

  function confirmFeed(
    address base,
    address quote,
    address aggregator
  ) external;

  // Proposed aggregator

  function getProposedFeed(
    address base,
    address quote
  )
    external
    view
    returns (
      AggregatorV2V3Interface proposedAggregator
    );

  function proposedGetRoundData(
    address base,
    address quote,
    uint80 roundId
  )
    external
    view
    returns (
      uint80 id,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function proposedLatestRoundData(
    address base,
    address quote
  )
    external
    view
    returns (
      uint80 id,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  // Phases
  function getCurrentPhaseId(
    address base,
    address quote
  )
    external
    view
    returns (
      uint16 currentPhaseId
    );
}

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

/// @title The interface for an oracle that provides price quotes
/// @notice These methods allow users to add support for pairs, and then ask for quotes
interface IPriceOracle {
  /// @notice Returns whether this oracle can support this pair of tokens
  /// @dev _tokenA and _tokenB may be passed in either tokenA/tokenB or tokenB/tokenA order
  /// @param _tokenA One of the pair's tokens
  /// @param _tokenB The other of the pair's tokens
  /// @return Whether the given pair of tokens can be supported by the oracle
  function canSupportPair(address _tokenA, address _tokenB) external view returns (bool);

  /// @notice Returns a quote, based on the given tokens and amount
  /// @param _tokenIn The token that will be provided
  /// @param _amountIn The amount that will be provided
  /// @param _tokenOut The token we would like to quote
  /// @return _amountOut How much _tokenOut will be returned in exchange for _amountIn amount of _tokenIn
  function quote(
    address _tokenIn,
    uint128 _amountIn,
    address _tokenOut
  ) external view returns (uint256 _amountOut);

  /// @notice Reconfigures support for a given pair. This function will let the oracle take some actions to configure the pair, in
  /// preparation for future quotes. Can be called many times in order to let the oracle re-configure for a new context.
  /// @dev Will revert if pair cannot be supported. _tokenA and _tokenB may be passed in either tokenA/tokenB or tokenB/tokenA order
  /// @param _tokenA One of the pair's tokens
  /// @param _tokenB The other of the pair's tokens
  function reconfigureSupportForPair(address _tokenA, address _tokenB) external;

  /// @notice Adds support for a given pair if the oracle didn't support it already. If called for a pair that is already supported,
  /// then nothing will happen. This function will let the oracle take some actions to configure the pair, in preparation for future quotes.
  /// @dev Will revert if pair cannot be supported. _tokenA and _tokenB may be passed in either tokenA/tokenB or tokenB/tokenA order
  /// @param _tokenA One of the pair's tokens
  /// @param _tokenB The other of the pair's tokens
  function addSupportForPairIfNeeded(address _tokenA, address _tokenB) external;
}

File 10 of 12 : AggregatorV2V3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./AggregatorInterface.sol";
import "./AggregatorV3Interface.sol";

interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface
{
}

File 11 of 12 : AggregatorInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface AggregatorInterface {
  function latestAnswer()
    external
    view
    returns (
      int256
    );
  
  function latestTimestamp()
    external
    view
    returns (
      uint256
    );

  function latestRound()
    external
    view
    returns (
      uint256
    );

  function getAnswer(
    uint256 roundId
  )
    external
    view
    returns (
      int256
    );

  function getTimestamp(
    uint256 roundId
  )
    external
    view
    returns (
      uint256
    );

  event AnswerUpdated(
    int256 indexed current,
    uint256 indexed roundId,
    uint256 updatedAt
  );

  event NewRound(
    uint256 indexed roundId,
    address indexed startedBy,
    uint256 startedAt
  );
}

File 12 of 12 : 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
    );

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  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
    );

}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"contract FeedRegistryInterface","name":"_registry","type":"address"},{"internalType":"uint32","name":"_maxDelay","type":"uint32"},{"internalType":"address","name":"_governor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidMappingsInput","type":"error"},{"inputs":[],"name":"InvalidPrice","type":"error"},{"inputs":[],"name":"LastUpdateIsTooOld","type":"error"},{"inputs":[],"name":"PairNotSupported","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroMaxDelay","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenA","type":"address"},{"indexed":false,"internalType":"address","name":"tokenB","type":"address"}],"name":"AddedSupportForPairInChainlinkOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"mappings","type":"address[]"}],"name":"MappingsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newMaxDelay","type":"uint32"}],"name":"MaxDelaySet","type":"event"},{"anonymous":false,"inputs":[],"name":"PendingGovernorAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingGovernor","type":"address"}],"name":"PendingGovernorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"TokensConsideredUSD","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptPendingGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"},{"internalType":"address[]","name":"_mappings","type":"address[]"}],"name":"addMappings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenA","type":"address"},{"internalType":"address","name":"_tokenB","type":"address"}],"name":"addSupportForPairIfNeeded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addUSDStablecoins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenA","type":"address"},{"internalType":"address","name":"_tokenB","type":"address"}],"name":"canSupportPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isGovernor","outputs":[{"internalType":"bool","name":"_isGovernor","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isPendingGovernor","outputs":[{"internalType":"bool","name":"_isPendingGovernor","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"mappedToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDelay","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"planForPair","outputs":[{"internalType":"enum IChainlinkOracle.PricingPlan","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"uint128","name":"_amountIn","type":"uint128"},{"internalType":"address","name":"_tokenOut","type":"address"}],"name":"quote","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenA","type":"address"},{"internalType":"address","name":"_tokenB","type":"address"}],"name":"reconfigureSupportForPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract FeedRegistryInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_maxDelay","type":"uint32"}],"name":"setMaxDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"__pendingGovernor","type":"address"}],"name":"setPendingGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b506040516200234838038062002348833981016040819052620000349162000155565b806001600160a01b038116620000905760405162461bcd60e51b815260206004820152601860248201527f476f7665726e61626c653a207a65726f20616464726573730000000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b0392831617905584161580620000c257506001600160a01b038316155b15620000e15760405163d92e233d60e01b815260040160405180910390fd5b8163ffffffff166000036200010957604051632c4f52fb60e21b815260040160405180910390fd5b506001600160a01b039182166080526003805463ffffffff191663ffffffff929092169190911790551660a052620001c5565b6001600160a01b03811681146200015257600080fd5b50565b600080600080608085870312156200016c57600080fd5b845162000179816200013c565b60208601519094506200018c816200013c565b604086015190935063ffffffff81168114620001a757600080fd5b6060860151909250620001ba816200013c565b939692955090935050565b60805160a051612133620002156000396000818161026b01528181610e5101528181611034015281816110ff01526117b40152600081816102100152818161164c01526118d201526121336000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80637f55db3a116100b2578063e3056a3411610081578063e82138cd11610066578063e82138cd14610309578063ed49d2f814610344578063f235757f1461036957600080fd5b8063e3056a34146102bc578063e43581b8146102da57600080fd5b80637f55db3a14610232578063a513355f14610245578063ad5c464814610266578063df08aed51461028d57600080fd5b80634df3cad61161010957806372c12c87116100ee57806372c12c87146101d5578063734273fd146101e85780637b1039991461020b57600080fd5b80634df3cad6146101af5780636edc6632146101c257600080fd5b80630c340a241461013b57806313f6986d1461017f5780631d4ef30a14610189578063310301621461019c575b600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61018761037c565b005b610187610197366004611a34565b610432565b6101876101aa366004611aa0565b6105f5565b6101556101bd366004611aea565b6106e0565b6101876101d0366004611b05565b6107af565b6101876101e3366004611b47565b61090b565b6101fb6101f6366004611b47565b610919565b6040519015158152602001610176565b6101557f000000000000000000000000000000000000000000000000000000000000000081565b610187610240366004611b47565b61095c565b610258610253366004611b7a565b6109cc565b604051908152602001610176565b6101557f000000000000000000000000000000000000000000000000000000000000000081565b6101fb61029b366004611aea565b60015473ffffffffffffffffffffffffffffffffffffffff91821691161490565b60015473ffffffffffffffffffffffffffffffffffffffff16610155565b6101fb6102e8366004611aea565b60005473ffffffffffffffffffffffffffffffffffffffff91821691161490565b610337610317366004611b47565b600260209081526000928352604080842090915290825290205460ff1681565b6040516101769190611c03565b6003546103549063ffffffff1681565b60405163ffffffff9091168152602001610176565b610187610377366004611aea565b610b1d565b60015473ffffffffffffffffffffffffffffffffffffffff163314610428576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f476f7665726e61626c653a206f6e6c792070656e64696e6720676f7665726e6f60448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610430610baa565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b8281146104ec576040517f0dc7722a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156105b15782828281811061050957610509611c44565b905060200201602081019061051e9190611aea565b6005600087878581811061053457610534611c44565b90506020020160208101906105499190611aea565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002080547fffffffffffffffffffffffff00000000000000000000000000000000000000001692909116919091179055806105a981611ca2565b9150506104ef565b507f25967af46669513d9b32b10bce9dc8b094f9638e01d68bd4253fb634873b3d17848484846040516105e79493929190611d2e565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff83169081179091556040519081527f55ab0355f542386898a10e20731ebdfe9303c36ea9cbc480909adb8beaf4a7c0906020015b60405180910390a150565b600046600114801561074e575073ffffffffffffffffffffffffffffffffffffffff821673eb4c2781e4eba804ce9a9803c67d0893436bb27d148061074e575073ffffffffffffffffffffffffffffffffffffffff8216732260fac5e5542a773aa44fbcfedf7c193bc2c599145b1561076e575073bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb919050565b73ffffffffffffffffffffffffffffffffffffffff80831660009081526005602052604090205416806107a157826107a3565b805b9392505050565b919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610830576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b60005b818110156108cd5760016004600085858581811061085357610853611c44565b90506020020160208101906108689190611aea565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806108c581611ca2565b915050610833565b507f0e1316bdb62d8b87b8c288a81e4bc638fbf187056521cd5f525a3c70dd812abf82826040516108ff929190611d60565b60405180910390a15050565b6109158282610c9e565b5050565b60008060006109288585610dd1565b9150915060006109388383610e1c565b9050600081600781111561094e5761094e611bd4565b141593505050505b92915050565b6000806109698484610dd1565b9092509050600073ffffffffffffffffffffffffffffffffffffffff80841660009081526002602090815260408083209386168352929052205460ff1660078111156109b7576109b7611bd4565b036109c6576109c68484610c9e565b50505050565b60008060006109db8685610dd1565b73ffffffffffffffffffffffffffffffffffffffff808316600090815260026020908152604080832093851683529290529081205492945090925060ff90911690816007811115610a2e57610a2e611bd4565b03610a65576040517f65db466f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a7088610f6b565b90506000610a7d87610f6b565b90506003836007811115610a9357610a93611bd4565b11610ac457610ab8898884848c6fffffffffffffffffffffffffffffffff1688610fdc565b955050505050506107a3565b6005836007811115610ad857610ad8611bd4565b11610afd57610ab8898884848c6fffffffffffffffffffffffffffffffff16886111c7565b610ab8898884848c6fffffffffffffffffffffffffffffffff168861125f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b610ba7816113ca565b50565b60015473ffffffffffffffffffffffffffffffffffffffff16610c29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f476f7665726e61626c653a206e6f2070656e64696e6720676f7665726e6f7200604482015260640161041f565b60018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff84161782559091169091556040517fdc57ca23c46d823853915ed5a090ca0ee9db5eb6a46f5c58e1c9158de861fd769190a1565b600080610cab8484610dd1565b915091506000610cbb8383610e1c565b90506000816007811115610cd157610cd1611bd4565b03610d08576040517f65db466f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020908152604080832093861683529290522080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836007811115610d7557610d75611bd4565b02179055506040805173ffffffffffffffffffffffffffffffffffffffff8086168252841660208201527fa0f87b02ca47ea06fb7d8fd30abf826222301c4e0cc359211c4254d49b4736ad910160405180910390a15050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610610e0e578284610e11565b83835b909590945092505050565b600080610e28846114ba565b90506000610e35846114ba565b905073ffffffffffffffffffffffffffffffffffffffff8581167f0000000000000000000000000000000000000000000000000000000000000000821690811491861614818015610e835750825b80610e935750838015610e935750805b15610ea5576001945050505050610956565b828015610eb0575083155b15610ecd57610ec28760026007611593565b945050505050610956565b838015610ed8575082155b15610eea57610ec28660026006611593565b8015610efd57610ec28760066003611593565b8115610f1057610ec28660076003611593565b610f1c87610348611648565b15610f2e57610ec28660046006611593565b610f4c8773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee611648565b15610f5e57610ec28660076005611593565b5060009695505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fb8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109569190611d7c565b600080806003846007811115610ff457610ff4611bd4565b14611000576008611003565b60125b905060006110108a6114ba565b806110825750600385600781111561102a5761102a611bd4565b14801561108257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16145b9050600185600781111561109857611098611bd4565b036110ac576110a5611756565b925061115f565b60028560078111156110c0576110c0611bd4565b036110e1576110a56110d18a6114ba565b6110db578961177d565b8a61177d565b60038560078111156110f5576110f5611bd4565b0361115f5761115c7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161461115657896117b0565b8a6117b0565b92505b806111985761118e6111718785611d9f565b8961117c858b611ddc565b6111869190611ddc565b60000b61183a565b93505050506111bd565b61118e836111aa886111868b87611e3e565b6111b49190611e9f565b6111868a611eda565b9695505050505050565b60008060048360078111156111de576111de611bd4565b146111fd5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee611201565b6103485b905060006112176112118a6106e0565b8361187e565b9050600061122d6112278a6106e0565b8461187e565b90506112518161123d8489611d9f565b6112479190611e9f565b6111868a8a611ddc565b9a9950505050505050505050565b600080600683600781111561127657611276611bd4565b1480156112ae57508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16105b80611300575060078360078111156112c8576112c8611bd4565b14801561130057508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16115b9050600061130c611756565b9050811561137657600061131f8a61177d565b9050600061132c8a6117b0565b9050600061135361133d848a611d9f565b60126113498d8d611ddc565b6111869190611e3e565b9050816113608583611e9f565b61136a9190611e9f565b955050505050506111bd565b60006113818a6117b0565b9050600061138e8a61177d565b90506113bf818461139f858b611d9f565b6113a99190611d9f565b6113b39190611e9f565b601261117c8c8c611ddc565b9450505050506111bd565b73ffffffffffffffffffffffffffffffffffffffff8116611447576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f476f7665726e61626c653a207a65726f20616464726573730000000000000000604482015260640161041f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f56bddfa0cee9697cebddf9acd7f23dc6583663b05e007b877056d05017994def906020016106d5565b60008046600114801561155d575073ffffffffffffffffffffffffffffffffffffffff8316736b175474e89094c44da98b954eedeac495271d0f1480611529575073ffffffffffffffffffffffffffffffffffffffff831673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48145b8061155d575073ffffffffffffffffffffffffffffffffffffffff831673dac17f958d2ee523a2206206994597c13d831ec7145b905080806107a35750505073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b60008060008060008560078111156115ad576115ad611bd4565b8760078111156115bf576115bf611bd4565b106115e35773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee86610348896115fe565b6103488773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee885b93509350935093506116108885611648565b1561162157829450505050506107a3565b61162b8883611648565b1561163b5793506107a392505050565b60009450505050506107a3565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663bcfd032d61168f856106e0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260440160a060405180830381865afa92505050801561173a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261173791810190611f32565b60015b61174657506000610956565b6000841395505050505050610956565b600061177873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61034861187e565b905090565b6000611788826114ba565b6117a5576117a0611798836106e0565b61034861187e565b610956565b6305f5e10092915050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461182b576117a0611811836106e0565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61187e565b670de0b6b3a764000092915050565b6000808212156118695761184d82611f82565b61185890600a6120da565b6118629084611e9f565b9050610956565b61187482600a6120da565b6118629084611d9f565b6040517fbcfd032d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528281166024830152600091829182917f00000000000000000000000000000000000000000000000000000000000000009091169063bcfd032d9060440160a060405180830381865afa15801561191b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193f9190611f32565b509350509250506000821361197f576040517ebfc92100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003544263ffffffff9091161080156119a957506003546119a69063ffffffff16426120e6565b81105b156119e0576040517f46ea729300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b60008083601f8401126119fa57600080fd5b50813567ffffffffffffffff811115611a1257600080fd5b6020830191508360208260051b8501011115611a2d57600080fd5b9250929050565b60008060008060408587031215611a4a57600080fd5b843567ffffffffffffffff80821115611a6257600080fd5b611a6e888389016119e8565b90965094506020870135915080821115611a8757600080fd5b50611a94878288016119e8565b95989497509550505050565b600060208284031215611ab257600080fd5b813563ffffffff811681146107a357600080fd5b803573ffffffffffffffffffffffffffffffffffffffff811681146107aa57600080fd5b600060208284031215611afc57600080fd5b6107a382611ac6565b60008060208385031215611b1857600080fd5b823567ffffffffffffffff811115611b2f57600080fd5b611b3b858286016119e8565b90969095509350505050565b60008060408385031215611b5a57600080fd5b611b6383611ac6565b9150611b7160208401611ac6565b90509250929050565b600080600060608486031215611b8f57600080fd5b611b9884611ac6565b925060208401356fffffffffffffffffffffffffffffffff81168114611bbd57600080fd5b9150611bcb60408501611ac6565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160088310611c3e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611cd357611cd3611c73565b5060010190565b8183526000602080850194508260005b85811015611d235773ffffffffffffffffffffffffffffffffffffffff611d1083611ac6565b1687529582019590820190600101611cea565b509495945050505050565b604081526000611d42604083018688611cda565b8281036020840152611d55818587611cda565b979650505050505050565b602081526000611d74602083018486611cda565b949350505050565b600060208284031215611d8e57600080fd5b815160ff811681146107a357600080fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611dd757611dd7611c73565b500290565b60008160000b8360000b60008112817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8001831281151615611e1f57611e1f611c73565b81607f018313811615611e3457611e34611c73565b5090039392505050565b60008160000b8360000b6000821282607f03821381151615611e6257611e62611c73565b827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80038212811615611e9657611e96611c73565b50019392505050565b600082611ed5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008160000b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808103611f0f57611f0f611c73565b60000392915050565b805169ffffffffffffffffffff811681146107aa57600080fd5b600080600080600060a08688031215611f4a57600080fd5b611f5386611f18565b9450602086015193506040860151925060608601519150611f7660808701611f18565b90509295509295909350565b60007f80000000000000000000000000000000000000000000000000000000000000008203611fb357611fb3611c73565b5060000390565b600181815b8085111561201357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611ff957611ff9611c73565b8085161561200657918102915b93841c9390800290611fbf565b509250929050565b60008261202a57506001610956565b8161203757506000610956565b816001811461204d576002811461205757612073565b6001915050610956565b60ff84111561206857612068611c73565b50506001821b610956565b5060208310610133831016604e8410600b8410161715612096575081810a610956565b6120a08383611fba565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156120d2576120d2611c73565b029392505050565b60006107a3838361201b565b6000828210156120f8576120f8611c73565b50039056fea2646970667358221220f410abe8f5617b408fe7ed2c8d15c8a3662699fd6d42a9e9ce9fdcfa3846bf9164736f6c634300080d003300000000000000000000000042000000000000000000000000000000000000060000000000000000000000002dfb2c5c013826a0728440d8036305b254ad9cce00000000000000000000000000000000000000000000000000000000000151800000000000000000000000001a00e1e311009e56e3b0b9ed6f86f5ce128a1c01

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101365760003560e01c80637f55db3a116100b2578063e3056a3411610081578063e82138cd11610066578063e82138cd14610309578063ed49d2f814610344578063f235757f1461036957600080fd5b8063e3056a34146102bc578063e43581b8146102da57600080fd5b80637f55db3a14610232578063a513355f14610245578063ad5c464814610266578063df08aed51461028d57600080fd5b80634df3cad61161010957806372c12c87116100ee57806372c12c87146101d5578063734273fd146101e85780637b1039991461020b57600080fd5b80634df3cad6146101af5780636edc6632146101c257600080fd5b80630c340a241461013b57806313f6986d1461017f5780631d4ef30a14610189578063310301621461019c575b600080fd5b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61018761037c565b005b610187610197366004611a34565b610432565b6101876101aa366004611aa0565b6105f5565b6101556101bd366004611aea565b6106e0565b6101876101d0366004611b05565b6107af565b6101876101e3366004611b47565b61090b565b6101fb6101f6366004611b47565b610919565b6040519015158152602001610176565b6101557f0000000000000000000000002dfb2c5c013826a0728440d8036305b254ad9cce81565b610187610240366004611b47565b61095c565b610258610253366004611b7a565b6109cc565b604051908152602001610176565b6101557f000000000000000000000000420000000000000000000000000000000000000681565b6101fb61029b366004611aea565b60015473ffffffffffffffffffffffffffffffffffffffff91821691161490565b60015473ffffffffffffffffffffffffffffffffffffffff16610155565b6101fb6102e8366004611aea565b60005473ffffffffffffffffffffffffffffffffffffffff91821691161490565b610337610317366004611b47565b600260209081526000928352604080842090915290825290205460ff1681565b6040516101769190611c03565b6003546103549063ffffffff1681565b60405163ffffffff9091168152602001610176565b610187610377366004611aea565b610b1d565b60015473ffffffffffffffffffffffffffffffffffffffff163314610428576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f476f7665726e61626c653a206f6e6c792070656e64696e6720676f7665726e6f60448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610430610baa565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b8281146104ec576040517f0dc7722a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156105b15782828281811061050957610509611c44565b905060200201602081019061051e9190611aea565b6005600087878581811061053457610534611c44565b90506020020160208101906105499190611aea565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002080547fffffffffffffffffffffffff00000000000000000000000000000000000000001692909116919091179055806105a981611ca2565b9150506104ef565b507f25967af46669513d9b32b10bce9dc8b094f9638e01d68bd4253fb634873b3d17848484846040516105e79493929190611d2e565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff83169081179091556040519081527f55ab0355f542386898a10e20731ebdfe9303c36ea9cbc480909adb8beaf4a7c0906020015b60405180910390a150565b600046600114801561074e575073ffffffffffffffffffffffffffffffffffffffff821673eb4c2781e4eba804ce9a9803c67d0893436bb27d148061074e575073ffffffffffffffffffffffffffffffffffffffff8216732260fac5e5542a773aa44fbcfedf7c193bc2c599145b1561076e575073bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb919050565b73ffffffffffffffffffffffffffffffffffffffff80831660009081526005602052604090205416806107a157826107a3565b805b9392505050565b919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610830576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b60005b818110156108cd5760016004600085858581811061085357610853611c44565b90506020020160208101906108689190611aea565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806108c581611ca2565b915050610833565b507f0e1316bdb62d8b87b8c288a81e4bc638fbf187056521cd5f525a3c70dd812abf82826040516108ff929190611d60565b60405180910390a15050565b6109158282610c9e565b5050565b60008060006109288585610dd1565b9150915060006109388383610e1c565b9050600081600781111561094e5761094e611bd4565b141593505050505b92915050565b6000806109698484610dd1565b9092509050600073ffffffffffffffffffffffffffffffffffffffff80841660009081526002602090815260408083209386168352929052205460ff1660078111156109b7576109b7611bd4565b036109c6576109c68484610c9e565b50505050565b60008060006109db8685610dd1565b73ffffffffffffffffffffffffffffffffffffffff808316600090815260026020908152604080832093851683529290529081205492945090925060ff90911690816007811115610a2e57610a2e611bd4565b03610a65576040517f65db466f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610a7088610f6b565b90506000610a7d87610f6b565b90506003836007811115610a9357610a93611bd4565b11610ac457610ab8898884848c6fffffffffffffffffffffffffffffffff1688610fdc565b955050505050506107a3565b6005836007811115610ad857610ad8611bd4565b11610afd57610ab8898884848c6fffffffffffffffffffffffffffffffff16886111c7565b610ab8898884848c6fffffffffffffffffffffffffffffffff168861125f565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f476f7665726e61626c653a206f6e6c7920676f7665726e6f7200000000000000604482015260640161041f565b610ba7816113ca565b50565b60015473ffffffffffffffffffffffffffffffffffffffff16610c29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f476f7665726e61626c653a206e6f2070656e64696e6720676f7665726e6f7200604482015260640161041f565b60018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff84161782559091169091556040517fdc57ca23c46d823853915ed5a090ca0ee9db5eb6a46f5c58e1c9158de861fd769190a1565b600080610cab8484610dd1565b915091506000610cbb8383610e1c565b90506000816007811115610cd157610cd1611bd4565b03610d08576040517f65db466f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020908152604080832093861683529290522080548291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001836007811115610d7557610d75611bd4565b02179055506040805173ffffffffffffffffffffffffffffffffffffffff8086168252841660208201527fa0f87b02ca47ea06fb7d8fd30abf826222301c4e0cc359211c4254d49b4736ad910160405180910390a15050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610610e0e578284610e11565b83835b909590945092505050565b600080610e28846114ba565b90506000610e35846114ba565b905073ffffffffffffffffffffffffffffffffffffffff8581167f0000000000000000000000004200000000000000000000000000000000000006821690811491861614818015610e835750825b80610e935750838015610e935750805b15610ea5576001945050505050610956565b828015610eb0575083155b15610ecd57610ec28760026007611593565b945050505050610956565b838015610ed8575082155b15610eea57610ec28660026006611593565b8015610efd57610ec28760066003611593565b8115610f1057610ec28660076003611593565b610f1c87610348611648565b15610f2e57610ec28660046006611593565b610f4c8773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee611648565b15610f5e57610ec28660076005611593565b5060009695505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fb8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109569190611d7c565b600080806003846007811115610ff457610ff4611bd4565b14611000576008611003565b60125b905060006110108a6114ba565b806110825750600385600781111561102a5761102a611bd4565b14801561108257507f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16145b9050600185600781111561109857611098611bd4565b036110ac576110a5611756565b925061115f565b60028560078111156110c0576110c0611bd4565b036110e1576110a56110d18a6114ba565b6110db578961177d565b8a61177d565b60038560078111156110f5576110f5611bd4565b0361115f5761115c7f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161461115657896117b0565b8a6117b0565b92505b806111985761118e6111718785611d9f565b8961117c858b611ddc565b6111869190611ddc565b60000b61183a565b93505050506111bd565b61118e836111aa886111868b87611e3e565b6111b49190611e9f565b6111868a611eda565b9695505050505050565b60008060048360078111156111de576111de611bd4565b146111fd5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee611201565b6103485b905060006112176112118a6106e0565b8361187e565b9050600061122d6112278a6106e0565b8461187e565b90506112518161123d8489611d9f565b6112479190611e9f565b6111868a8a611ddc565b9a9950505050505050505050565b600080600683600781111561127657611276611bd4565b1480156112ae57508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16105b80611300575060078360078111156112c8576112c8611bd4565b14801561130057508673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16115b9050600061130c611756565b9050811561137657600061131f8a61177d565b9050600061132c8a6117b0565b9050600061135361133d848a611d9f565b60126113498d8d611ddc565b6111869190611e3e565b9050816113608583611e9f565b61136a9190611e9f565b955050505050506111bd565b60006113818a6117b0565b9050600061138e8a61177d565b90506113bf818461139f858b611d9f565b6113a99190611d9f565b6113b39190611e9f565b601261117c8c8c611ddc565b9450505050506111bd565b73ffffffffffffffffffffffffffffffffffffffff8116611447576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f476f7665726e61626c653a207a65726f20616464726573730000000000000000604482015260640161041f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f56bddfa0cee9697cebddf9acd7f23dc6583663b05e007b877056d05017994def906020016106d5565b60008046600114801561155d575073ffffffffffffffffffffffffffffffffffffffff8316736b175474e89094c44da98b954eedeac495271d0f1480611529575073ffffffffffffffffffffffffffffffffffffffff831673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48145b8061155d575073ffffffffffffffffffffffffffffffffffffffff831673dac17f958d2ee523a2206206994597c13d831ec7145b905080806107a35750505073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b60008060008060008560078111156115ad576115ad611bd4565b8760078111156115bf576115bf611bd4565b106115e35773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee86610348896115fe565b6103488773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee885b93509350935093506116108885611648565b1561162157829450505050506107a3565b61162b8883611648565b1561163b5793506107a392505050565b60009450505050506107a3565b60007f0000000000000000000000002dfb2c5c013826a0728440d8036305b254ad9cce73ffffffffffffffffffffffffffffffffffffffff1663bcfd032d61168f856106e0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9182166004820152908516602482015260440160a060405180830381865afa92505050801561173a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261173791810190611f32565b60015b61174657506000610956565b6000841395505050505050610956565b600061177873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61034861187e565b905090565b6000611788826114ba565b6117a5576117a0611798836106e0565b61034861187e565b610956565b6305f5e10092915050565b60007f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461182b576117a0611811836106e0565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee61187e565b670de0b6b3a764000092915050565b6000808212156118695761184d82611f82565b61185890600a6120da565b6118629084611e9f565b9050610956565b61187482600a6120da565b6118629084611d9f565b6040517fbcfd032d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528281166024830152600091829182917f0000000000000000000000002dfb2c5c013826a0728440d8036305b254ad9cce9091169063bcfd032d9060440160a060405180830381865afa15801561191b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193f9190611f32565b509350509250506000821361197f576040517ebfc92100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003544263ffffffff9091161080156119a957506003546119a69063ffffffff16426120e6565b81105b156119e0576040517f46ea729300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509392505050565b60008083601f8401126119fa57600080fd5b50813567ffffffffffffffff811115611a1257600080fd5b6020830191508360208260051b8501011115611a2d57600080fd5b9250929050565b60008060008060408587031215611a4a57600080fd5b843567ffffffffffffffff80821115611a6257600080fd5b611a6e888389016119e8565b90965094506020870135915080821115611a8757600080fd5b50611a94878288016119e8565b95989497509550505050565b600060208284031215611ab257600080fd5b813563ffffffff811681146107a357600080fd5b803573ffffffffffffffffffffffffffffffffffffffff811681146107aa57600080fd5b600060208284031215611afc57600080fd5b6107a382611ac6565b60008060208385031215611b1857600080fd5b823567ffffffffffffffff811115611b2f57600080fd5b611b3b858286016119e8565b90969095509350505050565b60008060408385031215611b5a57600080fd5b611b6383611ac6565b9150611b7160208401611ac6565b90509250929050565b600080600060608486031215611b8f57600080fd5b611b9884611ac6565b925060208401356fffffffffffffffffffffffffffffffff81168114611bbd57600080fd5b9150611bcb60408501611ac6565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160088310611c3e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611cd357611cd3611c73565b5060010190565b8183526000602080850194508260005b85811015611d235773ffffffffffffffffffffffffffffffffffffffff611d1083611ac6565b1687529582019590820190600101611cea565b509495945050505050565b604081526000611d42604083018688611cda565b8281036020840152611d55818587611cda565b979650505050505050565b602081526000611d74602083018486611cda565b949350505050565b600060208284031215611d8e57600080fd5b815160ff811681146107a357600080fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611dd757611dd7611c73565b500290565b60008160000b8360000b60008112817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8001831281151615611e1f57611e1f611c73565b81607f018313811615611e3457611e34611c73565b5090039392505050565b60008160000b8360000b6000821282607f03821381151615611e6257611e62611c73565b827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80038212811615611e9657611e96611c73565b50019392505050565b600082611ed5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008160000b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808103611f0f57611f0f611c73565b60000392915050565b805169ffffffffffffffffffff811681146107aa57600080fd5b600080600080600060a08688031215611f4a57600080fd5b611f5386611f18565b9450602086015193506040860151925060608601519150611f7660808701611f18565b90509295509295909350565b60007f80000000000000000000000000000000000000000000000000000000000000008203611fb357611fb3611c73565b5060000390565b600181815b8085111561201357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611ff957611ff9611c73565b8085161561200657918102915b93841c9390800290611fbf565b509250929050565b60008261202a57506001610956565b8161203757506000610956565b816001811461204d576002811461205757612073565b6001915050610956565b60ff84111561206857612068611c73565b50506001821b610956565b5060208310610133831016604e8410600b8410161715612096575081810a610956565b6120a08383611fba565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156120d2576120d2611c73565b029392505050565b60006107a3838361201b565b6000828210156120f8576120f8611c73565b50039056fea2646970667358221220f410abe8f5617b408fe7ed2c8d15c8a3662699fd6d42a9e9ce9fdcfa3846bf9164736f6c634300080d0033

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

00000000000000000000000042000000000000000000000000000000000000060000000000000000000000002dfb2c5c013826a0728440d8036305b254ad9cce00000000000000000000000000000000000000000000000000000000000151800000000000000000000000001a00e1e311009e56e3b0b9ed6f86f5ce128a1c01

-----Decoded View---------------
Arg [0] : _WETH (address): 0x4200000000000000000000000000000000000006
Arg [1] : _registry (address): 0x2DFb2C5C013826a0728440D8036305b254Ad9cCE
Arg [2] : _maxDelay (uint32): 86400
Arg [3] : _governor (address): 0x1a00e1E311009E56e3b0B9Ed6F86f5Ce128a1C01

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000004200000000000000000000000000000000000006
Arg [1] : 0000000000000000000000002dfb2c5c013826a0728440d8036305b254ad9cce
Arg [2] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [3] : 0000000000000000000000001a00e1e311009e56e3b0b9ed6f86f5ce128a1c01


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.