Contract Address Details
0xD7f7933992c25A504e9Ddf7e76a3c1D6c432b25D
- Contract Name
- WitnetPriceRouter
- Creator
- 0x102cb4–8586da at 0xc13b00–504f76
- Balance
- 0 Doge
- Tokens
-
Fetching tokens...
- Transactions
- 5 Transactions
- Transfers
- 0 Transfers
- Gas Used
- 348,162
- Last Balance Update
- 26739940
- Contract name:
- WitnetPriceRouter
- Optimization enabled
- true
- Compiler version
- v0.8.13+commit.abaa5c0e
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2022-11-07T13:29:41.760941Z
Contract source code
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0 <0.9.0; pragma experimental ABIEncoderV2; // File: ado-contracts\contracts\interfaces\IERC2362.sol /** * @dev EIP2362 Interface for pull oracles * https://github.com/adoracles/EIPs/blob/erc-2362/EIPS/eip-2362.md */ interface IERC2362 { /** * @dev Exposed function pertaining to EIP standards * @param _id bytes32 ID of the query * @return int,uint,uint returns the value, timestamp, and status code of query */ function valueFor(bytes32 _id) external view returns(int256,uint256,uint256); } // File: @openzeppelin\contracts\utils\introspection\IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @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: contracts\interfaces\IERC165.sol // File: contracts\interfaces\IWitnetPriceRouter.sol /// @title The Witnet Price Router basic interface. /// @dev Guides implementation of price feeds aggregation contracts. /// @author The Witnet Foundation. abstract contract IWitnetPriceRouter is IERC2362 { /// Emitted everytime a currency pair is attached to a new price feed contract /// @dev See https://github.com/adoracles/ADOIPs/blob/main/adoip-0010.md /// @dev to learn how these ids are created. event CurrencyPairSet(bytes32 indexed erc2362ID, IERC165 pricefeed); /// Helper pure function: returns hash of the provided ERC2362-compliant currency pair caption (aka ID). function currencyPairId(string memory) external pure virtual returns (bytes32); /// Returns the ERC-165-compliant price feed contract currently serving /// updates on the given currency pair. function getPriceFeed(bytes32 _erc2362id) external view virtual returns (IERC165); /// Returns human-readable ERC2362-based caption of the currency pair being /// served by the given price feed contract address. /// @dev Should fail if the given price feed contract address is not currently /// @dev registered in the router. function getPriceFeedCaption(IERC165) external view virtual returns (string memory); /// Returns human-readable caption of the ERC2362-based currency pair identifier, if known. function lookupERC2362ID(bytes32 _erc2362id) external view virtual returns (string memory); /// Register a price feed contract that will serve updates for the given currency pair. /// @dev Setting zero address to a currency pair implies that it will not be served any longer. /// @dev Otherwise, should fail if the price feed contract does not support the `IWitnetPriceFeed` interface, /// @dev or if given price feed is already serving another currency pair (within this WitnetPriceRouter instance). function setPriceFeed( IERC165 _pricefeed, uint256 _decimals, string calldata _base, string calldata _quote ) external virtual; /// Returns list of known currency pairs IDs. function supportedCurrencyPairs() external view virtual returns (bytes32[] memory); /// Returns `true` if given pair is currently being served by a compliant price feed contract. function supportsCurrencyPair(bytes32 _erc2362id) external view virtual returns (bool); /// Returns `true` if given price feed contract is currently serving updates to any known currency pair. function supportsPriceFeed(IERC165 _priceFeed) external view virtual returns (bool); } // File: node_modules\@openzeppelin\contracts\utils\Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin\contracts\access\Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: contracts\interfaces\IWitnetPriceFeed.sol /// @title The Witnet Price Feed basic interface. /// @dev Guides implementation of active price feed polling contracts. /// @author The Witnet Foundation. interface IWitnetPriceFeed { /// Signals that a new price update request is being posted to the Witnet Request Board event PriceFeeding(address indexed from, uint256 queryId, uint256 extraFee); /// Estimates minimum fee amount in native currency to be paid when /// requesting a new price update. /// @dev Actual fee depends on the gas price of the `requestUpdate()` transaction. /// @param _gasPrice Gas price expected to be paid when calling `requestUpdate()` function estimateUpdateFee(uint256 _gasPrice) external view returns (uint256); /// Returns result of the last valid price update request successfully solved by the Witnet oracle. function lastPrice() external view returns (int256); /// Returns the EVM-timestamp when last valid price was reported back from the Witnet oracle. function lastTimestamp() external view returns (uint256); /// Returns tuple containing last valid price and timestamp, as well as status code of latest update /// request that got posted to the Witnet Request Board. /// @return _lastPrice Last valid price reported back from the Witnet oracle. /// @return _lastTimestamp EVM-timestamp of the last valid price. /// @return _lastDrTxHash Hash of the Witnet Data Request that solved the last valid price. /// @return _latestUpdateStatus Status code of the latest update request. function lastValue() external view returns ( int _lastPrice, uint _lastTimestamp, bytes32 _lastDrTxHash, uint _latestUpdateStatus ); /// Returns identifier of the latest update request posted to the Witnet Request Board. function latestQueryId() external view returns (uint256); /// Returns hash of the Witnet Data Request that solved the latest update request. /// @dev Returning 0 while the latest update request remains unsolved. function latestUpdateDrTxHash() external view returns (bytes32); /// Returns error message of latest update request posted to the Witnet Request Board. /// @dev Returning empty string if the latest update request remains unsolved, or /// @dev if it was succesfully solved with no errors. function latestUpdateErrorMessage() external view returns (string memory); /// Returns status code of latest update request posted to the Witnet Request Board: /// @dev Status codes: /// @dev - 200: update request was succesfully solved with no errors /// @dev - 400: update request was solved with errors /// @dev - 404: update request was not solved yet function latestUpdateStatus() external view returns (uint256); /// Returns `true` if latest update request posted to the Witnet Request Board /// has not been solved yet by the Witnet oracle. function pendingUpdate() external view returns (bool); /// Posts a new price update request to the Witnet Request Board. Requires payment of a fee /// that depends on the value of `tx.gasprice`. See `estimateUpdateFee(uint256)`. /// @dev If previous update request was not solved yet, calling this method again allows /// @dev upgrading the update fee if called with a higher `tx.gasprice` value. function requestUpdate() external payable; /// Tells whether this contract implements the interface defined by `interfaceId`. /// @dev See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] /// @dev to learn more about how these ids are created. function supportsInterface(bytes4) external view returns (bool); } // File: @openzeppelin\contracts\utils\Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: contracts\apps\WitnetPriceRouter.sol contract WitnetPriceRouter is IWitnetPriceRouter, Ownable { using Strings for uint256; struct Pair { IERC165 pricefeed; uint256 decimals; string base; string quote; } mapping (bytes4 => Pair) internal __pairs; mapping (address => bytes32) internal __pricefeedId_; bytes32[] internal __supportedCurrencyPairs; // ======================================================================== // --- Implementation of 'IERC2362' --------------------------------------- /// Returns last valid price value and timestamp, as well as status of /// the latest update request that got posted to the Witnet Request Board. /// @dev Fails if the given currency pair is not currently supported. /// @param _erc2362id Price pair identifier as specified in https://github.com/adoracles/ADOIPs/blob/main/adoip-0010.md /// @return _lastPrice Last valid price reported back from the Witnet oracle. /// @return _lastTimestamp EVM-timestamp of the last valid price. /// @return _latestUpdateStatus Status code of latest update request that got posted to the Witnet Request Board: /// - 200: latest update request was succesfully solved with no errors /// - 400: latest update request was solved with errors /// - 404: latest update request is still pending to be solved function valueFor(bytes32 _erc2362id) external view virtual override returns ( int256 _lastPrice, uint256 _lastTimestamp, uint256 _latestUpdateStatus ) { IWitnetPriceFeed _pricefeed = IWitnetPriceFeed(address(getPriceFeed(_erc2362id))); require(address(_pricefeed) != address(0), "WitnetPriceRouter: unsupported currency pair"); (_lastPrice, _lastTimestamp,, _latestUpdateStatus) = _pricefeed.lastValue(); } // ======================================================================== // --- Implementation of 'IWitnetPriceRouter' --------------------------- /// Helper pure function: returns hash of the provided ERC2362-compliant currency pair caption (aka ID). function currencyPairId(string memory _caption) public pure virtual override returns (bytes32) { return keccak256(bytes(_caption)); } /// Returns the ERC-165-compliant price feed contract currently serving /// updates on the given currency pair. function getPriceFeed(bytes32 _erc2362id) public view virtual override returns (IERC165) { return __pairs[bytes4(_erc2362id)].pricefeed; } /// Returns human-readable ERC2362-based caption of the currency pair being /// served by the given price feed contract address. /// @dev Fails if the given price feed contract address is not currently /// @dev registered in the router. function getPriceFeedCaption(IERC165 _pricefeed) public view virtual override returns (string memory) { require(supportsPriceFeed(_pricefeed), "WitnetPriceRouter: unknown"); return lookupERC2362ID(__pricefeedId_[address(_pricefeed)]); } /// Returns human-readable caption of the ERC2362-based currency pair identifier, if known. function lookupERC2362ID(bytes32 _erc2362id) public view virtual override returns (string memory _caption) { Pair storage _pair = __pairs[bytes4(_erc2362id)]; if ( bytes(_pair.base).length > 0 && bytes(_pair.quote).length > 0 ) { _caption = string(abi.encodePacked( "Price-", _pair.base, "/", _pair.quote, "-", _pair.decimals.toString() )); } } /// Register a price feed contract that will serve updates for the given currency pair. /// @dev Setting zero address to a currency pair implies that it will not be served any longer. /// @dev Otherwise, fails if the price feed contract does not support the `IWitnetPriceFeed` interface, /// @dev or if given price feed is already serving another currency pair (within this WitnetPriceRouter instance). function setPriceFeed( IERC165 _pricefeed, uint256 _decimals, string calldata _base, string calldata _quote ) public virtual override onlyOwner { if (address(_pricefeed) != address(0)) { require( _pricefeed.supportsInterface(type(IWitnetPriceFeed).interfaceId), "WitnetPriceRouter: feed contract is not compliant with IWitnetPriceFeed" ); require( __pricefeedId_[address(_pricefeed)] == bytes32(0), "WitnetPriceRouter: already serving a currency pair" ); } bytes memory _caption = abi.encodePacked( "Price-", bytes(_base), "/", bytes(_quote), "-", _decimals.toString() ); bytes32 _erc2362id = keccak256(_caption); Pair storage _record = __pairs[bytes4(_erc2362id)]; address _currentPriceFeed = address(_record.pricefeed); if (bytes(_record.base).length == 0) { _record.base = _base; _record.quote = _quote; _record.decimals = _decimals; __supportedCurrencyPairs.push(_erc2362id); } else if (_currentPriceFeed != address(0)) { __pricefeedId_[_currentPriceFeed] = bytes32(0); } if (address(_pricefeed) != _currentPriceFeed) { __pricefeedId_[address(_pricefeed)] = _erc2362id; } _record.pricefeed = _pricefeed; emit CurrencyPairSet(_erc2362id, _pricefeed); } /// Returns list of known currency pairs IDs. function supportedCurrencyPairs() external view virtual override returns (bytes32[] memory) { return __supportedCurrencyPairs; } /// Returns `true` if given pair is currently being served by a compliant price feed contract. function supportsCurrencyPair(bytes32 _erc2362id) public view virtual override returns (bool) { return address(__pairs[bytes4(_erc2362id)].pricefeed) != address(0); } /// Returns `true` if given price feed contract is currently serving updates to any known currency pair. function supportsPriceFeed(IERC165 _pricefeed) public view virtual override returns (bool) { return __pairs[bytes4(__pricefeedId_[address(_pricefeed)])].pricefeed == _pricefeed; } }
Contract ABI
[{"type":"event","name":"CurrencyPairSet","inputs":[{"type":"bytes32","name":"erc2362ID","internalType":"bytes32","indexed":true},{"type":"address","name":"pricefeed","internalType":"contract IERC165","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"currencyPairId","inputs":[{"type":"string","name":"_caption","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC165"}],"name":"getPriceFeed","inputs":[{"type":"bytes32","name":"_erc2362id","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getPriceFeedCaption","inputs":[{"type":"address","name":"_pricefeed","internalType":"contract IERC165"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"_caption","internalType":"string"}],"name":"lookupERC2362ID","inputs":[{"type":"bytes32","name":"_erc2362id","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPriceFeed","inputs":[{"type":"address","name":"_pricefeed","internalType":"contract IERC165"},{"type":"uint256","name":"_decimals","internalType":"uint256"},{"type":"string","name":"_base","internalType":"string"},{"type":"string","name":"_quote","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32[]","name":"","internalType":"bytes32[]"}],"name":"supportedCurrencyPairs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsCurrencyPair","inputs":[{"type":"bytes32","name":"_erc2362id","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsPriceFeed","inputs":[{"type":"address","name":"_pricefeed","internalType":"contract IERC165"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"_lastPrice","internalType":"int256"},{"type":"uint256","name":"_lastTimestamp","internalType":"uint256"},{"type":"uint256","name":"_latestUpdateStatus","internalType":"uint256"}],"name":"valueFor","inputs":[{"type":"bytes32","name":"_erc2362id","internalType":"bytes32"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6110278061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806399d32a041161007157806399d32a0414610157578063a027ad1514610177578063bbfa81181461019a578063ca64c540146101ad578063f2fde38b146101e2578063f78eea83146101f557600080fd5b80633fd29ebd146100b9578063715018a6146100d757806377021267146100e1578063835262f5146100f45780638c0adf621461011b5780638da5cb5b14610146575b600080fd5b6100c1610223565b6040516100ce9190610ad4565b60405180910390f35b6100df61027b565b005b6100df6100ef366004610b76565b61028f565b61010d610102366004610c18565b805160209091012090565b6040519081526020016100ce565b61012e610129366004610cc9565b6105b6565b6040516001600160a01b0390911681526020016100ce565b6000546001600160a01b031661012e565b61016a610165366004610cc9565b6105db565b6040516100ce9190610d12565b61018a610185366004610d45565b61066b565b60405190151581526020016100ce565b61016a6101a8366004610d45565b6106a3565b61018a6101bb366004610cc9565b6001600160e01b0319166000908152600160205260409020546001600160a01b0316151590565b6100df6101f0366004610d45565b610722565b610208610203366004610cc9565b61079b565b604080519384526020840192909252908201526060016100ce565b6060600380548060200260200160405190810160405280929190818152602001828054801561027157602002820191906000526020600020905b81548152602001906001019080831161025d575b5050505050905090565b610283610888565b61028d60006108e2565b565b610297610888565b6001600160a01b0386161561041d576040516301ffc9a760e01b8152632089297160e11b60048201526001600160a01b038716906301ffc9a790602401602060405180830381865afa1580156102f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103159190610d69565b61039c5760405162461bcd60e51b815260206004820152604760248201527f5769746e65745072696365526f757465723a206665656420636f6e747261637460448201527f206973206e6f7420636f6d706c69616e74207769746820495769746e657450726064820152661a58d95199595960ca1b608482015260a4015b60405180910390fd5b6001600160a01b0386166000908152600260205260409020541561041d5760405162461bcd60e51b815260206004820152603260248201527f5769746e65745072696365526f757465723a20616c7265616479207365727669604482015271373390309031bab93932b731bc903830b4b960711b6064820152608401610393565b60008484848461042c8a610932565b604051602001610440959493929190610d8b565b60408051601f1981840301815291815281516020808401919091206001600160e01b03198116600090815260019092529190208054600282018054949550929391926001600160a01b039091169161049790610de4565b90506000036104fc576104ae600283018989610a3b565b506104bd600383018787610a3b565b5060018083018a90556003805491820181556000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01839055610525565b6001600160a01b03811615610525576001600160a01b0381166000908152600260205260408120555b806001600160a01b03168a6001600160a01b03161461055a576001600160a01b038a1660009081526002602052604090208390555b81546001600160a01b0319166001600160a01b038b16908117835560405190815283907f2a1586394a17f79a4cc822c7b077653442e5a6fd7c78be98349291aa67a50c219060200160405180910390a250505050505050505050565b6001600160e01b0319166000908152600160205260409020546001600160a01b031690565b6001600160e01b031981166000908152600160205260408120600281018054606093919061060890610de4565b90501180156106275750600081600301805461062390610de4565b9050115b156106655780600201816003016106418360010154610932565b60405160200161065393929190610eb1565b60405160208183030381529060405291505b50919050565b6001600160a01b039081166000818152600260209081526040808320546001600160e01b031916835260019091529020549091161490565b60606106ae8261066b565b6106fa5760405162461bcd60e51b815260206004820152601a60248201527f5769746e65745072696365526f757465723a20756e6b6e6f776e0000000000006044820152606401610393565b6001600160a01b03821660009081526002602052604090205461071c906105db565b92915050565b61072a610888565b6001600160a01b03811661078f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610393565b610798816108e2565b50565b6000806000806107aa856105b6565b90506001600160a01b0381166108175760405162461bcd60e51b815260206004820152602c60248201527f5769746e65745072696365526f757465723a20756e737570706f72746564206360448201526b3ab93932b731bc903830b4b960a11b6064820152608401610393565b806001600160a01b031663431838346040518163ffffffff1660e01b8152600401608060405180830381865afa158015610855573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108799190610f09565b92989197509195509350505050565b6000546001600160a01b0316331461028d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610393565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060816000036109595750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610983578061096d81610f55565b915061097c9050600a83610f84565b915061095d565b60008167ffffffffffffffff81111561099e5761099e610c02565b6040519080825280601f01601f1916602001820160405280156109c8576020820181803683370190505b5090505b8415610a33576109dd600183610f98565b91506109ea600a86610faf565b6109f5906030610fc3565b60f81b818381518110610a0a57610a0a610fdb565b60200101906001600160f81b031916908160001a905350610a2c600a86610f84565b94506109cc565b949350505050565b828054610a4790610de4565b90600052602060002090601f016020900481019282610a695760008555610aaf565b82601f10610a825782800160ff19823516178555610aaf565b82800160010185558215610aaf579182015b82811115610aaf578235825591602001919060010190610a94565b50610abb929150610abf565b5090565b5b80821115610abb5760008155600101610ac0565b6020808252825182820181905260009190848201906040850190845b81811015610b0c57835183529284019291840191600101610af0565b50909695505050505050565b6001600160a01b038116811461079857600080fd5b60008083601f840112610b3f57600080fd5b50813567ffffffffffffffff811115610b5757600080fd5b602083019150836020828501011115610b6f57600080fd5b9250929050565b60008060008060008060808789031215610b8f57600080fd5b8635610b9a81610b18565b955060208701359450604087013567ffffffffffffffff80821115610bbe57600080fd5b610bca8a838b01610b2d565b90965094506060890135915080821115610be357600080fd5b50610bf089828a01610b2d565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215610c2a57600080fd5b813567ffffffffffffffff80821115610c4257600080fd5b818401915084601f830112610c5657600080fd5b813581811115610c6857610c68610c02565b604051601f8201601f19908116603f01168101908382118183101715610c9057610c90610c02565b81604052828152876020848701011115610ca957600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610cdb57600080fd5b5035919050565b60005b83811015610cfd578181015183820152602001610ce5565b83811115610d0c576000848401525b50505050565b6020815260008251806020840152610d31816040850160208701610ce2565b601f01601f19169190910160400192915050565b600060208284031215610d5757600080fd5b8135610d6281610b18565b9392505050565b600060208284031215610d7b57600080fd5b81518015158114610d6257600080fd5b6550726963652d60d01b8152848660068301376000858201602f60f81b600682015284866007830137602d60f81b6007918601918201528351610dd5816008840160208801610ce2565b01600801979650505050505050565b600181811c90821680610df857607f821691505b60208210810361066557634e487b7160e01b600052602260045260246000fd5b8054600090600181811c9080831680610e3257607f831692505b60208084108203610e5357634e487b7160e01b600052602260045260246000fd5b818015610e675760018114610e7857610ea5565b60ff19861689528489019650610ea5565b60008881526020902060005b86811015610e9d5781548b820152908501908301610e84565b505084890196505b50505050505092915050565b6550726963652d60d01b81526000610ecc6006830186610e18565b602f60f81b8152610ee06001820186610e18565b9050602d60f81b81528351610efc816001840160208801610ce2565b0160010195945050505050565b60008060008060808587031215610f1f57600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052601160045260246000fd5b600060018201610f6757610f67610f3f565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082610f9357610f93610f6e565b500490565b600082821015610faa57610faa610f3f565b500390565b600082610fbe57610fbe610f6e565b500690565b60008219821115610fd657610fd6610f3f565b500190565b634e487b7160e01b600052603260045260246000fdfea264697066735822122074439116591690445fccbbee3924f071786fbcaaa052f7bd7f2dc482ab39908664736f6c634300080d0033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100b45760003560e01c806399d32a041161007157806399d32a0414610157578063a027ad1514610177578063bbfa81181461019a578063ca64c540146101ad578063f2fde38b146101e2578063f78eea83146101f557600080fd5b80633fd29ebd146100b9578063715018a6146100d757806377021267146100e1578063835262f5146100f45780638c0adf621461011b5780638da5cb5b14610146575b600080fd5b6100c1610223565b6040516100ce9190610ad4565b60405180910390f35b6100df61027b565b005b6100df6100ef366004610b76565b61028f565b61010d610102366004610c18565b805160209091012090565b6040519081526020016100ce565b61012e610129366004610cc9565b6105b6565b6040516001600160a01b0390911681526020016100ce565b6000546001600160a01b031661012e565b61016a610165366004610cc9565b6105db565b6040516100ce9190610d12565b61018a610185366004610d45565b61066b565b60405190151581526020016100ce565b61016a6101a8366004610d45565b6106a3565b61018a6101bb366004610cc9565b6001600160e01b0319166000908152600160205260409020546001600160a01b0316151590565b6100df6101f0366004610d45565b610722565b610208610203366004610cc9565b61079b565b604080519384526020840192909252908201526060016100ce565b6060600380548060200260200160405190810160405280929190818152602001828054801561027157602002820191906000526020600020905b81548152602001906001019080831161025d575b5050505050905090565b610283610888565b61028d60006108e2565b565b610297610888565b6001600160a01b0386161561041d576040516301ffc9a760e01b8152632089297160e11b60048201526001600160a01b038716906301ffc9a790602401602060405180830381865afa1580156102f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103159190610d69565b61039c5760405162461bcd60e51b815260206004820152604760248201527f5769746e65745072696365526f757465723a206665656420636f6e747261637460448201527f206973206e6f7420636f6d706c69616e74207769746820495769746e657450726064820152661a58d95199595960ca1b608482015260a4015b60405180910390fd5b6001600160a01b0386166000908152600260205260409020541561041d5760405162461bcd60e51b815260206004820152603260248201527f5769746e65745072696365526f757465723a20616c7265616479207365727669604482015271373390309031bab93932b731bc903830b4b960711b6064820152608401610393565b60008484848461042c8a610932565b604051602001610440959493929190610d8b565b60408051601f1981840301815291815281516020808401919091206001600160e01b03198116600090815260019092529190208054600282018054949550929391926001600160a01b039091169161049790610de4565b90506000036104fc576104ae600283018989610a3b565b506104bd600383018787610a3b565b5060018083018a90556003805491820181556000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01839055610525565b6001600160a01b03811615610525576001600160a01b0381166000908152600260205260408120555b806001600160a01b03168a6001600160a01b03161461055a576001600160a01b038a1660009081526002602052604090208390555b81546001600160a01b0319166001600160a01b038b16908117835560405190815283907f2a1586394a17f79a4cc822c7b077653442e5a6fd7c78be98349291aa67a50c219060200160405180910390a250505050505050505050565b6001600160e01b0319166000908152600160205260409020546001600160a01b031690565b6001600160e01b031981166000908152600160205260408120600281018054606093919061060890610de4565b90501180156106275750600081600301805461062390610de4565b9050115b156106655780600201816003016106418360010154610932565b60405160200161065393929190610eb1565b60405160208183030381529060405291505b50919050565b6001600160a01b039081166000818152600260209081526040808320546001600160e01b031916835260019091529020549091161490565b60606106ae8261066b565b6106fa5760405162461bcd60e51b815260206004820152601a60248201527f5769746e65745072696365526f757465723a20756e6b6e6f776e0000000000006044820152606401610393565b6001600160a01b03821660009081526002602052604090205461071c906105db565b92915050565b61072a610888565b6001600160a01b03811661078f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610393565b610798816108e2565b50565b6000806000806107aa856105b6565b90506001600160a01b0381166108175760405162461bcd60e51b815260206004820152602c60248201527f5769746e65745072696365526f757465723a20756e737570706f72746564206360448201526b3ab93932b731bc903830b4b960a11b6064820152608401610393565b806001600160a01b031663431838346040518163ffffffff1660e01b8152600401608060405180830381865afa158015610855573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108799190610f09565b92989197509195509350505050565b6000546001600160a01b0316331461028d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610393565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060816000036109595750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610983578061096d81610f55565b915061097c9050600a83610f84565b915061095d565b60008167ffffffffffffffff81111561099e5761099e610c02565b6040519080825280601f01601f1916602001820160405280156109c8576020820181803683370190505b5090505b8415610a33576109dd600183610f98565b91506109ea600a86610faf565b6109f5906030610fc3565b60f81b818381518110610a0a57610a0a610fdb565b60200101906001600160f81b031916908160001a905350610a2c600a86610f84565b94506109cc565b949350505050565b828054610a4790610de4565b90600052602060002090601f016020900481019282610a695760008555610aaf565b82601f10610a825782800160ff19823516178555610aaf565b82800160010185558215610aaf579182015b82811115610aaf578235825591602001919060010190610a94565b50610abb929150610abf565b5090565b5b80821115610abb5760008155600101610ac0565b6020808252825182820181905260009190848201906040850190845b81811015610b0c57835183529284019291840191600101610af0565b50909695505050505050565b6001600160a01b038116811461079857600080fd5b60008083601f840112610b3f57600080fd5b50813567ffffffffffffffff811115610b5757600080fd5b602083019150836020828501011115610b6f57600080fd5b9250929050565b60008060008060008060808789031215610b8f57600080fd5b8635610b9a81610b18565b955060208701359450604087013567ffffffffffffffff80821115610bbe57600080fd5b610bca8a838b01610b2d565b90965094506060890135915080821115610be357600080fd5b50610bf089828a01610b2d565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215610c2a57600080fd5b813567ffffffffffffffff80821115610c4257600080fd5b818401915084601f830112610c5657600080fd5b813581811115610c6857610c68610c02565b604051601f8201601f19908116603f01168101908382118183101715610c9057610c90610c02565b81604052828152876020848701011115610ca957600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610cdb57600080fd5b5035919050565b60005b83811015610cfd578181015183820152602001610ce5565b83811115610d0c576000848401525b50505050565b6020815260008251806020840152610d31816040850160208701610ce2565b601f01601f19169190910160400192915050565b600060208284031215610d5757600080fd5b8135610d6281610b18565b9392505050565b600060208284031215610d7b57600080fd5b81518015158114610d6257600080fd5b6550726963652d60d01b8152848660068301376000858201602f60f81b600682015284866007830137602d60f81b6007918601918201528351610dd5816008840160208801610ce2565b01600801979650505050505050565b600181811c90821680610df857607f821691505b60208210810361066557634e487b7160e01b600052602260045260246000fd5b8054600090600181811c9080831680610e3257607f831692505b60208084108203610e5357634e487b7160e01b600052602260045260246000fd5b818015610e675760018114610e7857610ea5565b60ff19861689528489019650610ea5565b60008881526020902060005b86811015610e9d5781548b820152908501908301610e84565b505084890196505b50505050505092915050565b6550726963652d60d01b81526000610ecc6006830186610e18565b602f60f81b8152610ee06001820186610e18565b9050602d60f81b81528351610efc816001840160208801610ce2565b0160010195945050505050565b60008060008060808587031215610f1f57600080fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b600052601160045260246000fd5b600060018201610f6757610f67610f3f565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082610f9357610f93610f6e565b500490565b600082821015610faa57610faa610f3f565b500390565b600082610fbe57610fbe610f6e565b500690565b60008219821115610fd657610fd6610f3f565b500190565b634e487b7160e01b600052603260045260246000fdfea264697066735822122074439116591690445fccbbee3924f071786fbcaaa052f7bd7f2dc482ab39908664736f6c634300080d0033