Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- StdReferenceBasic
- Optimization enabled
- true
- Compiler version
- v0.8.13+commit.abaa5c0e
- Optimization runs
- 200
- EVM Version
- istanbul
- Verified at
- 2023-07-31T09:17:50.766241Z
StdReferenceBasic.sol
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.13; import {StdReferenceBase} from "StdReferenceBase.sol"; import {AccessControl} from "AccessControl.sol"; /// @title BandChain StdReferenceBasic /// @author Band Protocol Team contract StdReferenceBasic is AccessControl, StdReferenceBase { struct RefData { uint64 rate; // USD-rate, multiplied by 1e9. uint64 resolveTime; // UNIX epoch when data is last resolved. uint64 requestID; // BandChain request identifier for this data. } /// Mapping from token symbol to ref data mapping(string => RefData) public refs; bytes32 public constant RELAYER_ROLE = keccak256("RELAYER_ROLE"); constructor() { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(RELAYER_ROLE, msg.sender); } /** * @dev Grants `RELAYER_ROLE` to `accounts`. * * If each `account` had not been already granted `RELAYER_ROLE`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``RELAYER_ROLE``'s admin role. */ function grantRelayers(address[] calldata accounts) external onlyRole(getRoleAdmin(RELAYER_ROLE)) { for (uint256 idx = 0; idx < accounts.length; idx++) { _grantRole(RELAYER_ROLE, accounts[idx]); } } /** * @dev Revokes `RELAYER_ROLE` from `accounts`. * * If each `account` had already granted `RELAYER_ROLE`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must have ``RELAYER_ROLE``'s admin role. */ function revokeRelayers(address[] calldata accounts) external onlyRole(getRoleAdmin(RELAYER_ROLE)) { for (uint256 idx = 0; idx < accounts.length; idx++) { _revokeRole(RELAYER_ROLE, accounts[idx]); } } /// @notice Relay and save a set of price data to the contract only if resolveTime is newer /// @dev All of the lists must be of equal length /// @param symbols A list of symbols whose data is being relayed in this function call /// @param rates A list of the rates associated with each symbol /// @param resolveTime A timestamp of when the rate data was retrieved /// @param requestID A BandChain request ID in which the rate data was retrieved function relay( string[] calldata symbols, uint64[] calldata rates, uint64 resolveTime, uint64 requestID ) external { require(hasRole(RELAYER_ROLE, msg.sender), "NOTARELAYER"); require(rates.length == symbols.length, "BADRATESLENGTH"); for (uint256 idx = 0; idx < symbols.length; idx++) { RefData storage ref = refs[symbols[idx]]; if (resolveTime > ref.resolveTime) { refs[symbols[idx]] = RefData({rate: rates[idx], resolveTime: resolveTime, requestID: requestID}); } } } /// @notice Relay and save a set of price data to the contract /// @dev All of the lists must be of equal length /// @param symbols A list of symbols whose data is being relayed in this function call /// @param rates A list of the rates associated with each symbol /// @param resolveTime A timestamp of when the rate data was retrieved /// @param requestID A BandChain request ID in which the rate data was retrieved function forceRelay( string[] calldata symbols, uint64[] calldata rates, uint64 resolveTime, uint64 requestID ) external { require(hasRole(RELAYER_ROLE, msg.sender), "NOTARELAYER"); require(rates.length == symbols.length, "BADRATESLENGTH"); for (uint256 idx = 0; idx < symbols.length; idx++) { refs[symbols[idx]] = RefData({rate: rates[idx], resolveTime: resolveTime, requestID: requestID}); } } /// @notice Returns the price data for the given base/quote pair. Revert if not available. /// @param base the base symbol of the token pair to query /// @param quote the quote symbol of the token pair to query function getReferenceData(string memory base, string memory quote) public view override returns (ReferenceData memory) { (uint256 baseRate, uint256 baseLastUpdate) = _getRefData(base); (uint256 quoteRate, uint256 quoteLastUpdate) = _getRefData(quote); return ReferenceData({rate: (baseRate * 1e18) / quoteRate, lastUpdatedBase: baseLastUpdate, lastUpdatedQuote: quoteLastUpdate}); } /// @notice Get the price data of a token /// @param symbol the symbol of the token whose price to query function _getRefData(string memory symbol) internal view returns (uint256 rate, uint256 lastUpdate) { if (keccak256(bytes(symbol)) == keccak256(bytes("USD"))) { return (1e9, block.timestamp); } RefData storage refData = refs[symbol]; require(refData.resolveTime > 0, "REFDATANOTAVAILABLE"); return (uint256(refData.rate), uint256(refData.resolveTime)); } }
AccessControl.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "IAccessControl.sol"; import "Context.sol"; import "Strings.sol"; import "ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } }
ERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
IAccessControl.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
IStdReference.sol
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.13; interface IStdReference { /// A structure returned whenever someone requests for standard reference data. struct ReferenceData { uint256 rate; // base/quote exchange rate, multiplied by 1e18. uint256 lastUpdatedBase; // UNIX epoch of the last time when base price gets updated. uint256 lastUpdatedQuote; // UNIX epoch of the last time when quote price gets updated. } /// Returns the price data for the given base/quote pair. Revert if not available. function getReferenceData(string memory _base, string memory _quote) external view returns (ReferenceData memory); /// Similar to getReferenceData, but with multiple base/quote pairs at once. function getReferenceDataBulk(string[] memory _bases, string[] memory _quotes) external view returns (ReferenceData[] memory); }
StdReferenceBase.sol
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.13; import {IStdReference} from "IStdReference.sol"; abstract contract StdReferenceBase is IStdReference { function getReferenceData(string memory _base, string memory _quote) public view virtual override returns (ReferenceData memory); function getReferenceDataBulk(string[] memory _bases, string[] memory _quotes) public view override returns (ReferenceData[] memory) { require(_bases.length == _quotes.length, "BAD_INPUT_LENGTH"); uint256 len = _bases.length; ReferenceData[] memory results = new ReferenceData[](len); for (uint256 idx = 0; idx < len; idx++) { results[idx] = getReferenceData(_bases[idx], _quotes[idx]); } return results; } }
Strings.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @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); } }
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{"StdReferenceBasic.sol":{}},"evmVersion":"istanbul"}
Contract ABI
[{"type":"constructor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DEFAULT_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"RELAYER_ROLE","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"forceRelay","inputs":[{"type":"string[]","name":"symbols","internalType":"string[]"},{"type":"uint64[]","name":"rates","internalType":"uint64[]"},{"type":"uint64","name":"resolveTime","internalType":"uint64"},{"type":"uint64","name":"requestID","internalType":"uint64"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IStdReference.ReferenceData","components":[{"type":"uint256"},{"type":"uint256"},{"type":"uint256"}]}],"name":"getReferenceData","inputs":[{"type":"string","name":"base","internalType":"string"},{"type":"string","name":"quote","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct IStdReference.ReferenceData[]","components":[{"type":"uint256"},{"type":"uint256"},{"type":"uint256"}]}],"name":"getReferenceDataBulk","inputs":[{"type":"string[]","name":"_bases","internalType":"string[]"},{"type":"string[]","name":"_quotes","internalType":"string[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoleAdmin","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRelayers","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"rate","internalType":"uint64"},{"type":"uint64","name":"resolveTime","internalType":"uint64"},{"type":"uint64","name":"requestID","internalType":"uint64"}],"name":"refs","inputs":[{"type":"string","name":"","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"relay","inputs":[{"type":"string[]","name":"symbols","internalType":"string[]"},{"type":"uint64[]","name":"rates","internalType":"uint64[]"},{"type":"uint64","name":"resolveTime","internalType":"uint64"},{"type":"uint64","name":"requestID","internalType":"uint64"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRelayers","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"event","name":"RoleAdminChanged","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"bytes32","name":"previousAdminRole","indexed":true},{"type":"bytes32","name":"newAdminRole","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"address","name":"account","indexed":true},{"type":"address","name":"sender","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","indexed":true},{"type":"address","name":"account","indexed":true},{"type":"address","name":"sender","indexed":true}],"anonymous":false}]
Contract Creation Code
0x608060405234801561001057600080fd5b5061001c60003361004b565b6100467fe2b7fb3b832174769106daebcfd6d1970523240dda11281102db9363b83b0dc43361004b565b6100ea565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166100e6576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556100a53390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b61159c806100f96000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806391d1485411610097578063d547741f11610066578063d547741f14610265578063e42a071b14610278578063eca6ac9e14610298578063efbf2160146102ab57600080fd5b806391d14854146101c1578063926d7d7f146101d4578063a217fddf146101e9578063ab480741146101f157600080fd5b806336568abe116100d357806336568abe146101685780633798c7f21461017b57806365555bcc1461018e57806386814d06146101ae57600080fd5b806301ffc9a7146100fa578063248a9ca3146101225780632f2ff15d14610153575b600080fd5b61010d610108366004610e8a565b6102be565b60405190151581526020015b60405180910390f35b610145610130366004610eb4565b60009081526020819052604090206001015490565b604051908152602001610119565b610166610161366004610ee9565b6102f5565b005b610166610176366004610ee9565b610320565b610166610189366004610f77565b6103a3565b6101a161019c3660046110bb565b6105b6565b604051610119919061111e565b6101666101bc366004610f77565b61063d565b61010d6101cf366004610ee9565b6107e0565b61014560008051602061154783398151915281565b610145600081565b61023b6101ff36600461113f565b80516020818301810180516001825292820191909301209152546001600160401b0380821691600160401b8104821691600160801b9091041683565b604080516001600160401b0394851681529284166020840152921691810191909152606001610119565b610166610273366004610ee9565b610809565b61028b610286366004611219565b61082f565b6040516101199190611272565b6101666102a63660046112d4565b610969565b6101666102b93660046112d4565b610a0d565b60006001600160e01b03198216637965db0b60e01b14806102ef57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000828152602081905260409020600101546103118133610aab565b61031b8383610b0f565b505050565b6001600160a01b03811633146103955760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61039f8282610b93565b5050565b6103bb600080516020611547833981519152336107e0565b6103f55760405162461bcd60e51b815260206004820152600b60248201526a2727aa20a922a620aca2a960a91b604482015260640161038c565b8285146104355760405162461bcd60e51b815260206004820152600e60248201526d0848288a482a88aa6988a9c8ea8960931b604482015260640161038c565b60005b858110156105ad576000600188888481811061045657610456611315565b9050602002810190610468919061132b565b604051610476929190611371565b90815260405190819003602001902080549091506001600160401b03600160401b9091048116908516111561059a5760405180606001604052808787858181106104c2576104c2611315565b90506020020160208101906104d79190611381565b6001600160401b03168152602001856001600160401b03168152602001846001600160401b0316815250600189898581811061051557610515611315565b9050602002810190610527919061132b565b604051610535929190611371565b9081526040805160209281900383019020835181549385015194909201516001600160401b039283166001600160801b031990941693909317600160401b948316949094029390931767ffffffffffffffff60801b1916600160801b91909216021790555b50806105a5816113b2565b915050610438565b50505050505050565b6105da60405180606001604052806000815260200160008152602001600081525090565b6000806105e685610bf8565b915091506000806105f686610bf8565b9150915060405180606001604052808386670de0b6b3a764000061061a91906113cb565b61062491906113ea565b8152602081019490945260409093015250949350505050565b610655600080516020611547833981519152336107e0565b61068f5760405162461bcd60e51b815260206004820152600b60248201526a2727aa20a922a620aca2a960a91b604482015260640161038c565b8285146106cf5760405162461bcd60e51b815260206004820152600e60248201526d0848288a482a88aa6988a9c8ea8960931b604482015260640161038c565b60005b858110156105ad5760405180606001604052808686848181106106f7576106f7611315565b905060200201602081019061070c9190611381565b6001600160401b03168152602001846001600160401b03168152602001836001600160401b0316815250600188888481811061074a5761074a611315565b905060200281019061075c919061132b565b60405161076a929190611371565b9081526040805160209281900383019020835181549385015194909201516001600160401b039283166001600160801b031990941693909317600160401b948316949094029390931767ffffffffffffffff60801b1916600160801b9190921602179055806107d8816113b2565b9150506106d2565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000828152602081905260409020600101546108258133610aab565b61031b8383610b93565b606081518351146108755760405162461bcd60e51b815260206004820152601060248201526f0848288be929ca0aaa8be988a9c8ea8960831b604482015260640161038c565b82516000816001600160401b0381111561089157610891611006565b6040519080825280602002602001820160405280156108e657816020015b6108d360405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816108af5790505b50905060005b828110156109605761093086828151811061090957610909611315565b602002602001015186838151811061092357610923611315565b60200260200101516105b6565b82828151811061094257610942611315565b60200260200101819052508080610958906113b2565b9150506108ec565b50949350505050565b60008051602061154783398151915260009081526020527ffaf93c3d007e112089dc8351e013e6685ef67703975d0224b26fc45941d4f1f6546109ac8133610aab565b60005b82811015610a07576109f56000805160206115478339815191528585848181106109db576109db611315565b90506020020160208101906109f0919061140c565b610b93565b806109ff816113b2565b9150506109af565b50505050565b60008051602061154783398151915260009081526020527ffaf93c3d007e112089dc8351e013e6685ef67703975d0224b26fc45941d4f1f654610a508133610aab565b60005b82811015610a0757610a99600080516020611547833981519152858584818110610a7f57610a7f611315565b9050602002016020810190610a94919061140c565b610b0f565b80610aa3816113b2565b915050610a53565b610ab582826107e0565b61039f57610acd816001600160a01b03166014610ce8565b610ad8836020610ce8565b604051602001610ae9929190611453565b60408051601f198184030181529082905262461bcd60e51b825261038c916004016114c8565b610b1982826107e0565b61039f576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055610b4f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610b9d82826107e0565b1561039f576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6040805180820190915260038152621554d160ea1b60209182015281519082012060009081907f3b51de553f39ab628e2269fca481f424938614245776e4999eea436892e95d6201610c525750633b9aca00924292509050565b6000600184604051610c6491906114fb565b90815260405190819003602001902080549091506001600160401b03600160401b90910416610ccb5760405162461bcd60e51b8152602060048201526013602482015272524546444154414e4f54415641494c41424c4560681b604482015260640161038c565b546001600160401b0380821695600160401b909204169350915050565b60606000610cf78360026113cb565b610d02906002611517565b6001600160401b03811115610d1957610d19611006565b6040519080825280601f01601f191660200182016040528015610d43576020820181803683370190505b509050600360fc1b81600081518110610d5e57610d5e611315565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610d8d57610d8d611315565b60200101906001600160f81b031916908160001a9053506000610db18460026113cb565b610dbc906001611517565b90505b6001811115610e34576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110610df057610df0611315565b1a60f81b828281518110610e0657610e06611315565b60200101906001600160f81b031916908160001a90535060049490941c93610e2d8161152f565b9050610dbf565b508315610e835760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161038c565b9392505050565b600060208284031215610e9c57600080fd5b81356001600160e01b031981168114610e8357600080fd5b600060208284031215610ec657600080fd5b5035919050565b80356001600160a01b0381168114610ee457600080fd5b919050565b60008060408385031215610efc57600080fd5b82359150610f0c60208401610ecd565b90509250929050565b60008083601f840112610f2757600080fd5b5081356001600160401b03811115610f3e57600080fd5b6020830191508360208260051b8501011115610f5957600080fd5b9250929050565b80356001600160401b0381168114610ee457600080fd5b60008060008060008060808789031215610f9057600080fd5b86356001600160401b0380821115610fa757600080fd5b610fb38a838b01610f15565b90985096506020890135915080821115610fcc57600080fd5b50610fd989828a01610f15565b9095509350610fec905060408801610f60565b9150610ffa60608801610f60565b90509295509295509295565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561104457611044611006565b604052919050565b600082601f83011261105d57600080fd5b81356001600160401b0381111561107657611076611006565b611089601f8201601f191660200161101c565b81815284602083860101111561109e57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156110ce57600080fd5b82356001600160401b03808211156110e557600080fd5b6110f18683870161104c565b9350602085013591508082111561110757600080fd5b506111148582860161104c565b9150509250929050565b815181526020808301519082015260408083015190820152606081016102ef565b60006020828403121561115157600080fd5b81356001600160401b0381111561116757600080fd5b6111738482850161104c565b949350505050565b600082601f83011261118c57600080fd5b813560206001600160401b03808311156111a8576111a8611006565b8260051b6111b783820161101c565b93845285810183019383810190888611156111d157600080fd5b84880192505b8583101561120d578235848111156111ef5760008081fd5b6111fd8a87838c010161104c565b83525091840191908401906111d7565b98975050505050505050565b6000806040838503121561122c57600080fd5b82356001600160401b038082111561124357600080fd5b61124f8683870161117b565b9350602085013591508082111561126557600080fd5b506111148582860161117b565b6020808252825182820181905260009190848201906040850190845b818110156112c8576112b58385518051825260208082015190830152604090810151910152565b928401926060929092019160010161128e565b50909695505050505050565b600080602083850312156112e757600080fd5b82356001600160401b038111156112fd57600080fd5b61130985828601610f15565b90969095509350505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261134257600080fd5b8301803591506001600160401b0382111561135c57600080fd5b602001915036819003821315610f5957600080fd5b8183823760009101908152919050565b60006020828403121561139357600080fd5b610e8382610f60565b634e487b7160e01b600052601160045260246000fd5b6000600182016113c4576113c461139c565b5060010190565b60008160001904831182151516156113e5576113e561139c565b500290565b60008261140757634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561141e57600080fd5b610e8382610ecd565b60005b8381101561144257818101518382015260200161142a565b83811115610a075750506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161148b816017850160208801611427565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516114bc816028840160208801611427565b01602801949350505050565b60208152600082518060208401526114e7816040850160208701611427565b601f01601f19169190910160400192915050565b6000825161150d818460208701611427565b9190910192915050565b6000821982111561152a5761152a61139c565b500190565b60008161153e5761153e61139c565b50600019019056fee2b7fb3b832174769106daebcfd6d1970523240dda11281102db9363b83b0dc4a2646970667358221220e94b75c9ef50b4a7a28907b50c3ad2c43b8a9f9407548ab9dc941737b406f9b164736f6c634300080d0033
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806391d1485411610097578063d547741f11610066578063d547741f14610265578063e42a071b14610278578063eca6ac9e14610298578063efbf2160146102ab57600080fd5b806391d14854146101c1578063926d7d7f146101d4578063a217fddf146101e9578063ab480741146101f157600080fd5b806336568abe116100d357806336568abe146101685780633798c7f21461017b57806365555bcc1461018e57806386814d06146101ae57600080fd5b806301ffc9a7146100fa578063248a9ca3146101225780632f2ff15d14610153575b600080fd5b61010d610108366004610e8a565b6102be565b60405190151581526020015b60405180910390f35b610145610130366004610eb4565b60009081526020819052604090206001015490565b604051908152602001610119565b610166610161366004610ee9565b6102f5565b005b610166610176366004610ee9565b610320565b610166610189366004610f77565b6103a3565b6101a161019c3660046110bb565b6105b6565b604051610119919061111e565b6101666101bc366004610f77565b61063d565b61010d6101cf366004610ee9565b6107e0565b61014560008051602061154783398151915281565b610145600081565b61023b6101ff36600461113f565b80516020818301810180516001825292820191909301209152546001600160401b0380821691600160401b8104821691600160801b9091041683565b604080516001600160401b0394851681529284166020840152921691810191909152606001610119565b610166610273366004610ee9565b610809565b61028b610286366004611219565b61082f565b6040516101199190611272565b6101666102a63660046112d4565b610969565b6101666102b93660046112d4565b610a0d565b60006001600160e01b03198216637965db0b60e01b14806102ef57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000828152602081905260409020600101546103118133610aab565b61031b8383610b0f565b505050565b6001600160a01b03811633146103955760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61039f8282610b93565b5050565b6103bb600080516020611547833981519152336107e0565b6103f55760405162461bcd60e51b815260206004820152600b60248201526a2727aa20a922a620aca2a960a91b604482015260640161038c565b8285146104355760405162461bcd60e51b815260206004820152600e60248201526d0848288a482a88aa6988a9c8ea8960931b604482015260640161038c565b60005b858110156105ad576000600188888481811061045657610456611315565b9050602002810190610468919061132b565b604051610476929190611371565b90815260405190819003602001902080549091506001600160401b03600160401b9091048116908516111561059a5760405180606001604052808787858181106104c2576104c2611315565b90506020020160208101906104d79190611381565b6001600160401b03168152602001856001600160401b03168152602001846001600160401b0316815250600189898581811061051557610515611315565b9050602002810190610527919061132b565b604051610535929190611371565b9081526040805160209281900383019020835181549385015194909201516001600160401b039283166001600160801b031990941693909317600160401b948316949094029390931767ffffffffffffffff60801b1916600160801b91909216021790555b50806105a5816113b2565b915050610438565b50505050505050565b6105da60405180606001604052806000815260200160008152602001600081525090565b6000806105e685610bf8565b915091506000806105f686610bf8565b9150915060405180606001604052808386670de0b6b3a764000061061a91906113cb565b61062491906113ea565b8152602081019490945260409093015250949350505050565b610655600080516020611547833981519152336107e0565b61068f5760405162461bcd60e51b815260206004820152600b60248201526a2727aa20a922a620aca2a960a91b604482015260640161038c565b8285146106cf5760405162461bcd60e51b815260206004820152600e60248201526d0848288a482a88aa6988a9c8ea8960931b604482015260640161038c565b60005b858110156105ad5760405180606001604052808686848181106106f7576106f7611315565b905060200201602081019061070c9190611381565b6001600160401b03168152602001846001600160401b03168152602001836001600160401b0316815250600188888481811061074a5761074a611315565b905060200281019061075c919061132b565b60405161076a929190611371565b9081526040805160209281900383019020835181549385015194909201516001600160401b039283166001600160801b031990941693909317600160401b948316949094029390931767ffffffffffffffff60801b1916600160801b9190921602179055806107d8816113b2565b9150506106d2565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000828152602081905260409020600101546108258133610aab565b61031b8383610b93565b606081518351146108755760405162461bcd60e51b815260206004820152601060248201526f0848288be929ca0aaa8be988a9c8ea8960831b604482015260640161038c565b82516000816001600160401b0381111561089157610891611006565b6040519080825280602002602001820160405280156108e657816020015b6108d360405180606001604052806000815260200160008152602001600081525090565b8152602001906001900390816108af5790505b50905060005b828110156109605761093086828151811061090957610909611315565b602002602001015186838151811061092357610923611315565b60200260200101516105b6565b82828151811061094257610942611315565b60200260200101819052508080610958906113b2565b9150506108ec565b50949350505050565b60008051602061154783398151915260009081526020527ffaf93c3d007e112089dc8351e013e6685ef67703975d0224b26fc45941d4f1f6546109ac8133610aab565b60005b82811015610a07576109f56000805160206115478339815191528585848181106109db576109db611315565b90506020020160208101906109f0919061140c565b610b93565b806109ff816113b2565b9150506109af565b50505050565b60008051602061154783398151915260009081526020527ffaf93c3d007e112089dc8351e013e6685ef67703975d0224b26fc45941d4f1f654610a508133610aab565b60005b82811015610a0757610a99600080516020611547833981519152858584818110610a7f57610a7f611315565b9050602002016020810190610a94919061140c565b610b0f565b80610aa3816113b2565b915050610a53565b610ab582826107e0565b61039f57610acd816001600160a01b03166014610ce8565b610ad8836020610ce8565b604051602001610ae9929190611453565b60408051601f198184030181529082905262461bcd60e51b825261038c916004016114c8565b610b1982826107e0565b61039f576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055610b4f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610b9d82826107e0565b1561039f576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6040805180820190915260038152621554d160ea1b60209182015281519082012060009081907f3b51de553f39ab628e2269fca481f424938614245776e4999eea436892e95d6201610c525750633b9aca00924292509050565b6000600184604051610c6491906114fb565b90815260405190819003602001902080549091506001600160401b03600160401b90910416610ccb5760405162461bcd60e51b8152602060048201526013602482015272524546444154414e4f54415641494c41424c4560681b604482015260640161038c565b546001600160401b0380821695600160401b909204169350915050565b60606000610cf78360026113cb565b610d02906002611517565b6001600160401b03811115610d1957610d19611006565b6040519080825280601f01601f191660200182016040528015610d43576020820181803683370190505b509050600360fc1b81600081518110610d5e57610d5e611315565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610d8d57610d8d611315565b60200101906001600160f81b031916908160001a9053506000610db18460026113cb565b610dbc906001611517565b90505b6001811115610e34576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110610df057610df0611315565b1a60f81b828281518110610e0657610e06611315565b60200101906001600160f81b031916908160001a90535060049490941c93610e2d8161152f565b9050610dbf565b508315610e835760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161038c565b9392505050565b600060208284031215610e9c57600080fd5b81356001600160e01b031981168114610e8357600080fd5b600060208284031215610ec657600080fd5b5035919050565b80356001600160a01b0381168114610ee457600080fd5b919050565b60008060408385031215610efc57600080fd5b82359150610f0c60208401610ecd565b90509250929050565b60008083601f840112610f2757600080fd5b5081356001600160401b03811115610f3e57600080fd5b6020830191508360208260051b8501011115610f5957600080fd5b9250929050565b80356001600160401b0381168114610ee457600080fd5b60008060008060008060808789031215610f9057600080fd5b86356001600160401b0380821115610fa757600080fd5b610fb38a838b01610f15565b90985096506020890135915080821115610fcc57600080fd5b50610fd989828a01610f15565b9095509350610fec905060408801610f60565b9150610ffa60608801610f60565b90509295509295509295565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561104457611044611006565b604052919050565b600082601f83011261105d57600080fd5b81356001600160401b0381111561107657611076611006565b611089601f8201601f191660200161101c565b81815284602083860101111561109e57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156110ce57600080fd5b82356001600160401b03808211156110e557600080fd5b6110f18683870161104c565b9350602085013591508082111561110757600080fd5b506111148582860161104c565b9150509250929050565b815181526020808301519082015260408083015190820152606081016102ef565b60006020828403121561115157600080fd5b81356001600160401b0381111561116757600080fd5b6111738482850161104c565b949350505050565b600082601f83011261118c57600080fd5b813560206001600160401b03808311156111a8576111a8611006565b8260051b6111b783820161101c565b93845285810183019383810190888611156111d157600080fd5b84880192505b8583101561120d578235848111156111ef5760008081fd5b6111fd8a87838c010161104c565b83525091840191908401906111d7565b98975050505050505050565b6000806040838503121561122c57600080fd5b82356001600160401b038082111561124357600080fd5b61124f8683870161117b565b9350602085013591508082111561126557600080fd5b506111148582860161117b565b6020808252825182820181905260009190848201906040850190845b818110156112c8576112b58385518051825260208082015190830152604090810151910152565b928401926060929092019160010161128e565b50909695505050505050565b600080602083850312156112e757600080fd5b82356001600160401b038111156112fd57600080fd5b61130985828601610f15565b90969095509350505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261134257600080fd5b8301803591506001600160401b0382111561135c57600080fd5b602001915036819003821315610f5957600080fd5b8183823760009101908152919050565b60006020828403121561139357600080fd5b610e8382610f60565b634e487b7160e01b600052601160045260246000fd5b6000600182016113c4576113c461139c565b5060010190565b60008160001904831182151516156113e5576113e561139c565b500290565b60008261140757634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561141e57600080fd5b610e8382610ecd565b60005b8381101561144257818101518382015260200161142a565b83811115610a075750506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161148b816017850160208801611427565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516114bc816028840160208801611427565b01602801949350505050565b60208152600082518060208401526114e7816040850160208701611427565b601f01601f19169190910160400192915050565b6000825161150d818460208701611427565b9190910192915050565b6000821982111561152a5761152a61139c565b500190565b60008161153e5761153e61139c565b50600019019056fee2b7fb3b832174769106daebcfd6d1970523240dda11281102db9363b83b0dc4a2646970667358221220e94b75c9ef50b4a7a28907b50c3ad2c43b8a9f9407548ab9dc941737b406f9b164736f6c634300080d0033