Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ERC20
- Optimization enabled
- true
- Compiler version
- v0.8.18+commit.87f61d96
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-04-23T02:02:33.953177Z
contracts/ERC20.sol
// SPDX-License-Identifier: MITpragma solidity ^0.8.10;import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol";import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";contract ERC20 is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, ERC20PausableUpgradeable, AccessControlUpgradeable, ERC20PermitUpgradeable, UUPSUpgradeable {bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");/// @custom:oz-upgrades-unsafe-allow constructorconstructor() {_disableInitializers();}function initialize(string memory name, string memory symbol, address defaultAdmin, address pauser, address minter, address upgrader)initializer public{__ERC20_init(name, symbol);__ERC20Burnable_init();__ERC20Pausable_init();__AccessControl_init();__ERC20Permit_init(name);__UUPSUpgradeable_init();_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);_grantRole(PAUSER_ROLE, pauser);_mint(msg.sender, 10000000000 * 10 ** decimals());_grantRole(MINTER_ROLE, minter);_grantRole(UPGRADER_ROLE, upgrader);}function pause() public onlyRole(PAUSER_ROLE) {_pause();}
@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)pragma solidity ^0.8.0;import "./IAccessControlUpgradeable.sol";import "../utils/ContextUpgradeable.sol";import "../utils/StringsUpgradeable.sol";import "../utils/introspection/ERC165Upgradeable.sol";import {Initializable} from "../proxy/utils/Initializable.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:** ```solidity* 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}:** ```solidity* 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
@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.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 IAccessControlUpgradeable {/*** @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);
@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)pragma solidity ^0.8.0;/*** @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.** _Available since v4.8.3._*/interface IERC1967Upgradeable {/*** @dev Emitted when the implementation is upgraded.*/event Upgraded(address indexed implementation);/*** @dev Emitted when the admin account has changed.*/event AdminChanged(address previousAdmin, address newAdmin);/*** @dev Emitted when the beacon is changed.*/event BeaconUpgraded(address indexed beacon);}
@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)pragma solidity ^0.8.0;interface IERC5267Upgradeable {/*** @dev MAY be emitted to signal that the domain could have changed.*/event EIP712DomainChanged();/*** @dev returns the fields and values that describe the domain separator used by this contract for EIP-712* signature.*/function eip712Domain()externalviewreturns (bytes1 fields,string memory name,string memory version,uint256 chainId,address verifyingContract,bytes32 salt,uint256[] memory extensions);}
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)pragma solidity ^0.8.0;/*** @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified* proxy whose upgrades are fully controlled by the current implementation.*/interface IERC1822ProxiableUpgradeable {/*** @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation* address.** IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this* function revert if invoked through a proxy.*/function proxiableUUID() external view returns (bytes32);}
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)pragma solidity ^0.8.2;import "../beacon/IBeaconUpgradeable.sol";import "../../interfaces/IERC1967Upgradeable.sol";import "../../interfaces/draft-IERC1822Upgradeable.sol";import "../../utils/AddressUpgradeable.sol";import "../../utils/StorageSlotUpgradeable.sol";import {Initializable} from "../utils/Initializable.sol";/*** @dev This abstract contract provides getters and event emitting update functions for* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.** _Available since v4.1._*/abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;/*** @dev Storage slot with the address of the current implementation.* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is* validated in the constructor.*/bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;function __ERC1967Upgrade_init() internal onlyInitializing {}function __ERC1967Upgrade_init_unchained() internal onlyInitializing {}/*** @dev Returns the current implementation address.*/function _getImplementation() internal view returns (address) {return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;}
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)pragma solidity ^0.8.0;/*** @dev This is the interface that {BeaconProxy} expects of its beacon.*/interface IBeaconUpgradeable {/*** @dev Must return an address that can be used as a delegate call target.** {BeaconProxy} will check that this address is a contract.*/function implementation() external view returns (address);}
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)pragma solidity ^0.8.2;import "../../utils/AddressUpgradeable.sol";/*** @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.** The initialization functions use a version number. Once a version number is used, it is consumed and cannot be* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in* case an upgrade adds a module that needs to be initialized.** For example:** [.hljs-theme-light.nopadding]* ```solidity* contract MyToken is ERC20Upgradeable {* function initialize() initializer public {* __ERC20_init("MyToken", "MTK");* }* }** contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {* function initializeV2() reinitializer(2) public {* __ERC20Permit_init("MyToken");* }* }* ```** TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.** CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.** [CAUTION]
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)pragma solidity ^0.8.0;import "../../interfaces/draft-IERC1822Upgradeable.sol";import "../ERC1967/ERC1967UpgradeUpgradeable.sol";import {Initializable} from "./Initializable.sol";/*** @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.** A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing* `UUPSUpgradeable` with a custom implementation of upgrades.** The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.** _Available since v4.1._*/abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignmentaddress private immutable __self = address(this);/*** @dev Check that the execution is being performed through a delegatecall call and that the execution context is* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to* fail.*/modifier onlyProxy() {require(address(this) != __self, "Function must be called through delegatecall");require(_getImplementation() == __self, "Function must be called through active proxy");_;}/*** @dev Check that the execution is not being performed through a delegate call. This allows a function to be* callable on the implementing contract but not through proxies.
@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)pragma solidity ^0.8.0;import "../utils/ContextUpgradeable.sol";import {Initializable} from "../proxy/utils/Initializable.sol";/*** @dev Contract module which allows children to implement an emergency stop* mechanism that can be triggered by an authorized account.** This module is used through inheritance. It will make available the* modifiers `whenNotPaused` and `whenPaused`, which can be applied to* the functions of your contract. Note that they will not be pausable by* simply including this module, only once the modifiers are put in place.*/abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {/*** @dev Emitted when the pause is triggered by `account`.*/event Paused(address account);/*** @dev Emitted when the pause is lifted by `account`.*/event Unpaused(address account);bool private _paused;/*** @dev Initializes the contract in unpaused state.*/function __Pausable_init() internal onlyInitializing {__Pausable_init_unchained();}function __Pausable_init_unchained() internal onlyInitializing {_paused = false;}
@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)pragma solidity ^0.8.0;import "./IERC20Upgradeable.sol";import "./extensions/IERC20MetadataUpgradeable.sol";import "../../utils/ContextUpgradeable.sol";import {Initializable} from "../../proxy/utils/Initializable.sol";/*** @dev Implementation of the {IERC20} interface.** This implementation is agnostic to the way tokens are created. This means* that a supply mechanism has to be added in a derived contract using {_mint}.* For a generic mechanism see {ERC20PresetMinterPauser}.** TIP: For a detailed writeup see our guide* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How* to implement supply mechanisms].** The default value of {decimals} is 18. To change this, you should override* this function so it returns a different value.** We have followed general OpenZeppelin Contracts guidelines: functions revert* instead returning `false` on failure. This behavior is nonetheless* conventional and does not conflict with the expectations of ERC20* applications.** Additionally, an {Approval} event is emitted on calls to {transferFrom}.* This allows applications to reconstruct the allowance for all accounts just* by listening to said events. Other implementations of the EIP may not emit* these events, as it isn't required by the specification.** Finally, the non-standard {decreaseAllowance} and {increaseAllowance}* functions have been added to mitigate the well-known issues around setting* allowances. See {IERC20-approve}.*/contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {mapping(address => uint256) private _balances;
@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)pragma solidity ^0.8.0;/*** @dev Interface of the ERC20 standard as defined in the EIP.*/interface IERC20Upgradeable {/*** @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);/*** @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 `to`.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.*/function transfer(address to, uint256 amount) external returns (bool);
@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)pragma solidity ^0.8.0;import "../ERC20Upgradeable.sol";import "../../../utils/ContextUpgradeable.sol";import {Initializable} from "../../../proxy/utils/Initializable.sol";/*** @dev Extension of {ERC20} that allows token holders to destroy both their own* tokens and those that they have an allowance for, in a way that can be* recognized off-chain (via event analysis).*/abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable {function __ERC20Burnable_init() internal onlyInitializing {}function __ERC20Burnable_init_unchained() internal onlyInitializing {}/*** @dev Destroys `amount` tokens from the caller.** See {ERC20-_burn}.*/function burn(uint256 amount) public virtual {_burn(_msgSender(), amount);}/*** @dev Destroys `amount` tokens from `account`, deducting from the caller's* allowance.** See {ERC20-_burn} and {ERC20-allowance}.** Requirements:** - the caller must have allowance for ``accounts``'s tokens of at least* `amount`.*/function burnFrom(address account, uint256 amount) public virtual {
@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Pausable.sol)pragma solidity ^0.8.0;import "../ERC20Upgradeable.sol";import "../../../security/PausableUpgradeable.sol";import {Initializable} from "../../../proxy/utils/Initializable.sol";/*** @dev ERC20 token with pausable token transfers, minting and burning.** Useful for scenarios such as preventing trades until the end of an evaluation* period, or having an emergency switch for freezing all token transfers in the* event of a large bug.** IMPORTANT: This contract does not include public pause and unpause functions. In* addition to inheriting this contract, you must define both functions, invoking the* {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate* access control, e.g. using {AccessControl} or {Ownable}. Not doing so will* make the contract unpausable.*/abstract contract ERC20PausableUpgradeable is Initializable, ERC20Upgradeable, PausableUpgradeable {function __ERC20Pausable_init() internal onlyInitializing {__Pausable_init_unchained();}function __ERC20Pausable_init_unchained() internal onlyInitializing {}/*** @dev See {ERC20-_beforeTokenTransfer}.** Requirements:** - the contract must not be paused.*/function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {super._beforeTokenTransfer(from, to, amount);require(!paused(), "ERC20Pausable: token transfer while paused");}
@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/ERC20Permit.sol)pragma solidity ^0.8.0;import "./IERC20PermitUpgradeable.sol";import "../ERC20Upgradeable.sol";import "../../../utils/cryptography/ECDSAUpgradeable.sol";import "../../../utils/cryptography/EIP712Upgradeable.sol";import "../../../utils/CountersUpgradeable.sol";import {Initializable} from "../../../proxy/utils/Initializable.sol";/*** @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].** Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by* presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't* need to send a transaction, and thus is not required to hold Ether at all.** _Available since v3.4._** @custom:storage-size 51*/abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {using CountersUpgradeable for CountersUpgradeable.Counter;mapping(address => CountersUpgradeable.Counter) private _nonces;// solhint-disable-next-line var-name-mixedcasebytes32 private constant _PERMIT_TYPEHASH =keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");/*** @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.* However, to ensure consistency with the upgradeable transpiler, we will continue* to reserve a slot.* @custom:oz-renamed-from _PERMIT_TYPEHASH*/// solhint-disable-next-line var-name-mixedcasebytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;
@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)pragma solidity ^0.8.0;import "../IERC20Upgradeable.sol";/*** @dev Interface for the optional metadata functions from the ERC20 standard.** _Available since v4.1._*/interface IERC20MetadataUpgradeable is IERC20Upgradeable {/*** @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);}
@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)pragma solidity ^0.8.0;/*** @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].** Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't* need to send a transaction, and thus is not required to hold Ether at all.** ==== Security Considerations** There are two important considerations concerning the use of `permit`. The first is that a valid permit signature* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be* considered as an intention to spend the allowance in any specific way. The second is that because permits have* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be* generally recommended is:** ```solidity* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}* doThing(..., value);* }** function doThing(..., uint256 value) public {* token.safeTransferFrom(msg.sender, address(this), value);* ...* }* ```** Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also* {SafeERC20-safeTransferFrom}).** Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so* contracts should have entry points that don't rely on permit.*/
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)pragma solidity ^0.8.1;/*** @dev Collection of functions related to the address type*/library AddressUpgradeable {/*** @dev Returns true if `account` is a contract.** [IMPORTANT]* ====* It is unsafe to assume that an address for which this function returns* false is an externally-owned account (EOA) and not a contract.** Among others, `isContract` will return false for the following* types of addresses:** - an externally-owned account* - a contract in construction* - an address where a contract will be created* - an address where a contract lived, but was destroyed** Furthermore, `isContract` will also return true if the target contract within* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,* which only has an effect at the end of a transaction.* ====** [IMPORTANT]* ====* You shouldn't rely on `isContract` to protect against flash loan attacks!** Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract* constructor.* ====*/function isContract(address account) internal view returns (bool) {// This method relies on extcodesize/address.code.length, which returns 0
@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)pragma solidity ^0.8.0;import {Initializable} from "../proxy/utils/Initializable.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 ContextUpgradeable is Initializable {function __Context_init() internal onlyInitializing {}function __Context_init_unchained() internal onlyInitializing {}function _msgSender() internal view virtual returns (address) {return msg.sender;}function _msgData() internal view virtual returns (bytes calldata) {return msg.data;}function _contextSuffixLength() internal view virtual returns (uint256) {return 0;}/*** @dev This empty reserved space is put in place to allow future versions to add new* variables without shifting down storage in the inheritance chain.* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps*/uint256[50] private __gap;}
@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)pragma solidity ^0.8.0;/*** @title Counters* @author Matt Condon (@shrugs)* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number* of elements in a mapping, issuing ERC721 ids, or counting request ids.** Include with `using Counters for Counters.Counter;`*/library CountersUpgradeable {struct Counter {// This variable should never be directly accessed by users of the library: interactions must be restricted to// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add// this feature: see https://github.com/ethereum/solidity/issues/4637uint256 _value; // default: 0}function current(Counter storage counter) internal view returns (uint256) {return counter._value;}function increment(Counter storage counter) internal {unchecked {counter._value += 1;}}function decrement(Counter storage counter) internal {uint256 value = counter._value;require(value > 0, "Counter: decrement overflow");unchecked {counter._value = value - 1;}}function reset(Counter storage counter) internal {counter._value = 0;
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.pragma solidity ^0.8.0;/*** @dev Library for reading and writing primitive types to specific storage slots.** Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.* This library helps with reading and writing to such slots without the need for inline assembly.** The functions in this library return Slot structs that contain a `value` member that can be used to read or write.** Example usage to set ERC1967 implementation slot:* ```solidity* contract ERC1967 {* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;** function _getImplementation() internal view returns (address) {* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;* }** function _setImplementation(address newImplementation) internal {* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;* }* }* ```** _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._* _Available since v4.9 for `string`, `bytes`._*/library StorageSlotUpgradeable {struct AddressSlot {address value;}struct BooleanSlot {bool value;}
@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)pragma solidity ^0.8.0;import "./math/MathUpgradeable.sol";import "./math/SignedMathUpgradeable.sol";/*** @dev String operations.*/library StringsUpgradeable {bytes16 private constant _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) {unchecked {uint256 length = MathUpgradeable.log10(value) + 1;string memory buffer = new string(length);uint256 ptr;/// @solidity memory-safe-assemblyassembly {ptr := add(buffer, add(32, length))}while (true) {ptr--;/// @solidity memory-safe-assemblyassembly {mstore8(ptr, byte(mod(value, 10), _SYMBOLS))}value /= 10;if (value == 0) break;}return buffer;}}/**
@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)pragma solidity ^0.8.0;import "../StringsUpgradeable.sol";/*** @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.** These functions can be used to verify that a message was signed by the holder* of the private keys of a given address.*/library ECDSAUpgradeable {enum RecoverError {NoError,InvalidSignature,InvalidSignatureLength,InvalidSignatureS,InvalidSignatureV // Deprecated in v4.8}function _throwError(RecoverError error) private pure {if (error == RecoverError.NoError) {return; // no error: do nothing} else if (error == RecoverError.InvalidSignature) {revert("ECDSA: invalid signature");} else if (error == RecoverError.InvalidSignatureLength) {revert("ECDSA: invalid signature length");} else if (error == RecoverError.InvalidSignatureS) {revert("ECDSA: invalid signature 's' value");}}/*** @dev Returns the address that signed a hashed message (`hash`) with* `signature` or error string. This address can then be used for verification purposes.** The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:* this function rejects them by requiring the `s` value to be in the lower* half order, and the `v` value to be either 27 or 28.
@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)pragma solidity ^0.8.8;import "./ECDSAUpgradeable.sol";import "../../interfaces/IERC5267Upgradeable.sol";import {Initializable} from "../../proxy/utils/Initializable.sol";/*** @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.** The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding* they need in their contracts using a combination of `abi.encode` and `keccak256`.** This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA* ({_hashTypedDataV4}).** The implementation of the domain separator was designed to be as efficient as possible while still properly updating* the chain id to protect against replay attacks on an eventual fork of the chain.** NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].** NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain* separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the* separator from the immutable values, which is cheaper than accessing a cached version in cold storage.** _Available since v3.4._** @custom:storage-size 52*/abstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {bytes32 private constant _TYPE_HASH =keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");/// @custom:oz-renamed-from _HASHED_NAMEbytes32 private _hashedName;/// @custom:oz-renamed-from _HASHED_VERSION
@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)pragma solidity ^0.8.0;import "./IERC165Upgradeable.sol";import {Initializable} from "../../proxy/utils/Initializable.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 ERC165Upgradeable is Initializable, IERC165Upgradeable {function __ERC165_init() internal onlyInitializing {}function __ERC165_init_unchained() internal onlyInitializing {}/*** @dev See {IERC165-supportsInterface}.*/function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {return interfaceId == type(IERC165Upgradeable).interfaceId;}/*** @dev This empty reserved space is put in place to allow future versions to add new* variables without shifting down storage in the inheritance chain.* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps*/uint256[50] private __gap;
@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {/*** @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);}
@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)pragma solidity ^0.8.0;/*** @dev Standard math utilities missing in the Solidity language.*/library MathUpgradeable {enum Rounding {Down, // Toward negative infinityUp, // Toward infinityZero // Toward zero}/*** @dev Returns the largest of two numbers.*/function max(uint256 a, uint256 b) internal pure returns (uint256) {return a > b ? a : b;}/*** @dev Returns the smallest of two numbers.*/function min(uint256 a, uint256 b) internal pure returns (uint256) {return a < b ? a : b;}/*** @dev Returns the average of two numbers. The result is rounded towards* zero.*/function average(uint256 a, uint256 b) internal pure returns (uint256) {// (a + b) / 2 can overflow.return (a & b) + (a ^ b) / 2;}/*** @dev Returns the ceiling of the division of two numbers.*
@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)pragma solidity ^0.8.0;/*** @dev Standard signed math utilities missing in the Solidity language.*/library SignedMathUpgradeable {/*** @dev Returns the largest of two signed numbers.*/function max(int256 a, int256 b) internal pure returns (int256) {return a > b ? a : b;}/*** @dev Returns the smallest of two signed numbers.*/function min(int256 a, int256 b) internal pure returns (int256) {return a < b ? a : b;}/*** @dev Returns the average of two signed numbers without overflow.* The result is rounded towards zero.*/function average(int256 a, int256 b) internal pure returns (int256) {// Formula from the book "Hacker's Delight"int256 x = (a & b) + ((a ^ b) >> 1);return x + (int256(uint256(x) >> 255) & (a ^ b));}/*** @dev Returns the absolute unsigned value of a signed value.*/function abs(int256 n) internal pure returns (uint256) {unchecked {// must be unchecked in order to support `n = type(int256).min`return uint256(n >= 0 ? n : -n);}
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{}}
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":"DOMAIN_SEPARATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"MINTER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"PAUSER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"UPGRADER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burn","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burnFrom","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes1","name":"fields","internalType":"bytes1"},{"type":"string","name":"name","internalType":"string"},{"type":"string","name":"version","internalType":"string"},{"type":"uint256","name":"chainId","internalType":"uint256"},{"type":"address","name":"verifyingContract","internalType":"address"},{"type":"bytes32","name":"salt","internalType":"bytes32"},{"type":"uint256[]","name":"extensions","internalType":"uint256[]"}],"name":"eip712Domain","inputs":[]},{"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":"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":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"string","name":"symbol","internalType":"string"},{"type":"address","name":"defaultAdmin","internalType":"address"},{"type":"address","name":"pauser","internalType":"address"},{"type":"address","name":"minter","internalType":"address"},{"type":"address","name":"upgrader","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mint","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nonces","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"permit","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"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":"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":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgradeTo","inputs":[{"type":"address","name":"newImplementation","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"upgradeToAndCall","inputs":[{"type":"address","name":"newImplementation","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"event","name":"AdminChanged","inputs":[{"type":"address","name":"previousAdmin","indexed":false},{"type":"address","name":"newAdmin","indexed":false}],"anonymous":false},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"spender","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"BeaconUpgraded","inputs":[{"type":"address","name":"beacon","indexed":true}],"anonymous":false},{"type":"event","name":"EIP712DomainChanged","inputs":[],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","indexed":false}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","indexed":false}],"anonymous":false},{"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},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","indexed":false}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","indexed":true}],"anonymous":false}]
Contract Creation Code
0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e7565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051612cbc6200011f6000396000818161084b0152818161088b015281816109aa015281816109ea0152610a790152612cbc6000f3fe6080604052600436106102045760003560e01c80635c975abb11610118578063a457c2d7116100a0578063d547741f1161006f578063d547741f146105c9578063dd62ed3e146105e9578063e56f2fe414610609578063e63ab1e914610629578063f72c0d8b1461064b57600080fd5b8063a457c2d714610535578063a9059cbb14610555578063d505accf14610575578063d53913931461059557600080fd5b80638456cb59116100e75780638456cb59146104ae57806384b0196e146104c357806391d14854146104eb57806395d89b411461050b578063a217fddf1461052057600080fd5b80635c975abb1461042057806370a082311461043857806379cc67901461046e5780637ecebe001461048e57600080fd5b80633644e5151161019b5780633f4ba83a1161016a5780633f4ba83a146103a357806340c10f19146103b857806342966c68146103d85780634f1ef286146103f857806352d1902d1461040b57600080fd5b80633644e5151461032e57806336568abe146103435780633659cfe614610363578063395093511461038357600080fd5b806323b872dd116101d757806323b872dd1461029f578063248a9ca3146102bf5780632f2ff15d146102f0578063313ce5671461031257600080fd5b806301ffc9a71461020957806306fdde031461023e578063095ea7b31461026057806318160ddd14610280575b600080fd5b34801561021557600080fd5b50610229610224366004612385565b61067f565b60405190151581526020015b60405180910390f35b34801561024a57600080fd5b506102536106b6565b60405161023591906123ff565b34801561026c57600080fd5b5061022961027b36600461242e565b610748565b34801561028c57600080fd5b506035545b604051908152602001610235565b3480156102ab57600080fd5b506102296102ba366004612458565b610760565b3480156102cb57600080fd5b506102916102da366004612494565b600090815261012d602052604090206001015490565b3480156102fc57600080fd5b5061031061030b3660046124ad565b610784565b005b34801561031e57600080fd5b5060405160128152602001610235565b34801561033a57600080fd5b506102916107af565b34801561034f57600080fd5b5061031061035e3660046124ad565b6107be565b34801561036f57600080fd5b5061031061037e3660046124d9565b610841565b34801561038f57600080fd5b5061022961039e36600461242e565b610920565b3480156103af57600080fd5b50610310610942565b3480156103c457600080fd5b506103106103d336600461242e565b610962565b3480156103e457600080fd5b506103106103f3366004612494565b610996565b610310610406366004612580565b6109a0565b34801561041757600080fd5b50610291610a6c565b34801561042c57600080fd5b5060975460ff16610229565b34801561044457600080fd5b506102916104533660046124d9565b6001600160a01b031660009081526033602052604090205490565b34801561047a57600080fd5b5061031061048936600461242e565b610b1f565b34801561049a57600080fd5b506102916104a93660046124d9565b610b34565b3480156104ba57600080fd5b50610310610b53565b3480156104cf57600080fd5b506104d8610b73565b60405161023597969594939291906125e2565b3480156104f757600080fd5b506102296105063660046124ad565b610c13565b34801561051757600080fd5b50610253610c3f565b34801561052c57600080fd5b50610291600081565b34801561054157600080fd5b5061022961055036600461242e565b610c4e565b34801561056157600080fd5b5061022961057036600461242e565b610cc9565b34801561058157600080fd5b50610310610590366004612678565b610cd7565b3480156105a157600080fd5b506102917f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b3480156105d557600080fd5b506103106105e43660046124ad565b610e3b565b3480156105f557600080fd5b506102916106043660046126eb565b610e61565b34801561061557600080fd5b50610310610624366004612735565b610e8c565b34801561063557600080fd5b50610291600080516020612c4083398151915281565b34801561065757600080fd5b506102917f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b60006001600160e01b03198216637965db0b60e01b14806106b057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060603680546106c5906127da565b80601f01602080910402602001604051908101604052809291908181526020018280546106f1906127da565b801561073e5780601f106107135761010080835404028352916020019161073e565b820191906000526020600020905b81548152906001019060200180831161072157829003601f168201915b5050505050905090565b600033610756818585611069565b5060019392505050565b60003361076e85828561118d565b610779858585611207565b506001949350505050565b600082815261012d60205260409020600101546107a0816113bd565b6107aa83836113c7565b505050565b60006107b961144e565b905090565b6001600160a01b03811633146108335760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61083d8282611458565b5050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036108895760405162461bcd60e51b815260040161082a9061280e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108d2600080516020612c20833981519152546001600160a01b031690565b6001600160a01b0316146108f85760405162461bcd60e51b815260040161082a9061285a565b610901816114c0565b6040805160008082526020820190925261091d918391906114ea565b50565b6000336107568185856109338383610e61565b61093d91906128bc565b611069565b600080516020612c4083398151915261095a816113bd565b61091d611655565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661098c816113bd565b6107aa83836116a7565b61091d3382611774565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036109e85760405162461bcd60e51b815260040161082a9061280e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610a31600080516020612c20833981519152546001600160a01b031690565b6001600160a01b031614610a575760405162461bcd60e51b815260040161082a9061285a565b610a60826114c0565b61083d828260016114ea565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b0c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161082a565b50600080516020612c2083398151915290565b610b2a82338361118d565b61083d8282611774565b6001600160a01b038116600090815261019360205260408120546106b0565b600080516020612c40833981519152610b6b816113bd565b61091d6118b4565b60006060806000806000606061015f546000801b148015610b95575061016054155b610bd95760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b604482015260640161082a565b610be16118f1565b610be9611901565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b600091825261012d602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060603780546106c5906127da565b60003381610c5c8286610e61565b905083811015610cbc5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161082a565b6107798286868403611069565b600033610756818585611207565b83421115610d275760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015260640161082a565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610d568c611911565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610db18261193a565b90506000610dc182878787611967565b9050896001600160a01b0316816001600160a01b031614610e245760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015260640161082a565b610e2f8a8a8a611069565b50505050505050505050565b600082815261012d6020526040902060010154610e57816113bd565b6107aa8383611458565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b600054610100900460ff1615808015610eac5750600054600160ff909116105b80610ec65750303b158015610ec6575060005460ff166001145b610f295760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161082a565b6000805460ff191660011790558015610f4c576000805461ff0019166101001790555b610f568787611991565b610f5e6119c2565b610f666119eb565b610f6e6119c2565b610f7787611a1a565b610f7f6119c2565b610f8a6000866113c7565b610fa2600080516020612c40833981519152856113c7565b610fc633610fb26012600a6129b3565b610fc1906402540be4006129c2565b6116a7565b610ff07f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6846113c7565b61101a7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3836113c7565b8015611060576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b6001600160a01b0383166110cb5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161082a565b6001600160a01b03821661112c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161082a565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006111998484610e61565b9050600019811461120157818110156111f45760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161082a565b6112018484848403611069565b50505050565b6001600160a01b03831661126b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161082a565b6001600160a01b0382166112cd5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161082a565b6112d8838383611a64565b6001600160a01b038316600090815260336020526040902054818110156113505760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161082a565b6001600160a01b0380851660008181526033602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906113b09086815260200190565b60405180910390a3611201565b61091d8133611a77565b6113d18282610c13565b61083d57600082815261012d602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561140a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006107b9611ad0565b6114628282610c13565b1561083d57600082815261012d602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e361083d816113bd565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561151d576107aa83611b44565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611577575060408051601f3d908101601f19168201909252611574918101906129d9565b60015b6115da5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161082a565b600080516020612c2083398151915281146116495760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161082a565b506107aa838383611be0565b61165d611c05565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166116fd5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161082a565b61170960008383611a64565b806035600082825461171b91906128bc565b90915550506001600160a01b0382166000818152603360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166117d45760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161082a565b6117e082600083611a64565b6001600160a01b038216600090815260336020526040902054818110156118545760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161082a565b6001600160a01b03831660008181526033602090815260408083208686039055603580548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6118bc611c4e565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861168a3390565b606061016180546106c5906127da565b606061016280546106c5906127da565b6001600160a01b0381166000908152610193602052604090208054600181018255905b50919050565b60006106b061194761144e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600061197887878787611c94565b9150915061198581611d58565b5090505b949350505050565b600054610100900460ff166119b85760405162461bcd60e51b815260040161082a906129f2565b61083d8282611ea2565b600054610100900460ff166119e95760405162461bcd60e51b815260040161082a906129f2565b565b600054610100900460ff16611a125760405162461bcd60e51b815260040161082a906129f2565b6119e9611ee2565b600054610100900460ff16611a415760405162461bcd60e51b815260040161082a906129f2565b61091d81604051806040016040528060018152602001603160f81b815250611f15565b611a6c611c4e565b6107aa838383611f68565b611a818282610c13565b61083d57611a8e81611fce565b611a99836020611fe0565b604051602001611aaa929190612a3d565b60408051601f198184030181529082905262461bcd60e51b825261082a916004016123ff565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611afb612183565b611b036121dd565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0381163b611bb15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161082a565b600080516020612c2083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b611be98361220f565b600082511180611bf65750805b156107aa57611201838361224f565b60975460ff166119e95760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161082a565b60975460ff16156119e95760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161082a565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611ccb5750600090506003611d4f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611d1f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611d4857600060019250925050611d4f565b9150600090505b94509492505050565b6000816004811115611d6c57611d6c612ab2565b03611d745750565b6001816004811115611d8857611d88612ab2565b03611dd55760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161082a565b6002816004811115611de957611de9612ab2565b03611e365760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161082a565b6003816004811115611e4a57611e4a612ab2565b0361091d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161082a565b600054610100900460ff16611ec95760405162461bcd60e51b815260040161082a906129f2565b6036611ed58382612b16565b5060376107aa8282612b16565b600054610100900460ff16611f095760405162461bcd60e51b815260040161082a906129f2565b6097805460ff19169055565b600054610100900460ff16611f3c5760405162461bcd60e51b815260040161082a906129f2565b610161611f498382612b16565b50610162611f578282612b16565b5050600061015f8190556101605550565b60975460ff16156107aa5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b606482015260840161082a565b60606106b06001600160a01b03831660145b60606000611fef8360026129c2565b611ffa9060026128bc565b67ffffffffffffffff811115612012576120126124f4565b6040519080825280601f01601f19166020018201604052801561203c576020820181803683370190505b509050600360fc1b8160008151811061205757612057612bd6565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061208657612086612bd6565b60200101906001600160f81b031916908160001a90535060006120aa8460026129c2565b6120b59060016128bc565b90505b600181111561212d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106120e9576120e9612bd6565b1a60f81b8282815181106120ff576120ff612bd6565b60200101906001600160f81b031916908160001a90535060049490941c9361212681612bec565b90506120b8565b50831561217c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161082a565b9392505050565b60008061218e6118f1565b8051909150156121a5578051602090910120919050565b61015f5480156121b55792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b6000806121e8611901565b8051909150156121ff578051602090910120919050565b6101605480156121b55792915050565b61221881611b44565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b606061217c8383604051806060016040528060278152602001612c60602791396060600080856001600160a01b03168560405161228c9190612c03565b600060405180830381855af49150503d80600081146122c7576040519150601f19603f3d011682016040523d82523d6000602084013e6122cc565b606091505b50915091506122dd868383876122e7565b9695505050505050565b6060831561235657825160000361234f576001600160a01b0385163b61234f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161082a565b5081611989565b611989838381511561236b5781518083602001fd5b8060405162461bcd60e51b815260040161082a91906123ff565b60006020828403121561239757600080fd5b81356001600160e01b03198116811461217c57600080fd5b60005b838110156123ca5781810151838201526020016123b2565b50506000910152565b600081518084526123eb8160208601602086016123af565b601f01601f19169290920160200192915050565b60208152600061217c60208301846123d3565b80356001600160a01b038116811461242957600080fd5b919050565b6000806040838503121561244157600080fd5b61244a83612412565b946020939093013593505050565b60008060006060848603121561246d57600080fd5b61247684612412565b925061248460208501612412565b9150604084013590509250925092565b6000602082840312156124a657600080fd5b5035919050565b600080604083850312156124c057600080fd5b823591506124d060208401612412565b90509250929050565b6000602082840312156124eb57600080fd5b61217c82612412565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612525576125256124f4565b604051601f8501601f19908116603f0116810190828211818310171561254d5761254d6124f4565b8160405280935085815286868601111561256657600080fd5b858560208301376000602087830101525050509392505050565b6000806040838503121561259357600080fd5b61259c83612412565b9150602083013567ffffffffffffffff8111156125b857600080fd5b8301601f810185136125c957600080fd5b6125d88582356020840161250a565b9150509250929050565b60ff60f81b881681526000602060e08184015261260260e084018a6123d3565b8381036040850152612614818a6123d3565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156126665783518352928401929184019160010161264a565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561269357600080fd5b61269c88612412565b96506126aa60208901612412565b95506040880135945060608801359350608088013560ff811681146126ce57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156126fe57600080fd5b61270783612412565b91506124d060208401612412565b600082601f83011261272657600080fd5b61217c8383356020850161250a565b60008060008060008060c0878903121561274e57600080fd5b863567ffffffffffffffff8082111561276657600080fd5b6127728a838b01612715565b9750602089013591508082111561278857600080fd5b5061279589828a01612715565b9550506127a460408801612412565b93506127b260608801612412565b92506127c060808801612412565b91506127ce60a08801612412565b90509295509295509295565b600181811c908216806127ee57607f821691505b60208210810361193457634e487b7160e01b600052602260045260246000fd5b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b808201808211156106b0576106b06128a6565b600181815b8085111561290a5781600019048211156128f0576128f06128a6565b808516156128fd57918102915b93841c93908002906128d4565b509250929050565b600082612921575060016106b0565b8161292e575060006106b0565b8160018114612944576002811461294e5761296a565b60019150506106b0565b60ff84111561295f5761295f6128a6565b50506001821b6106b0565b5060208310610133831016604e8410600b841016171561298d575081810a6106b0565b61299783836128cf565b80600019048211156129ab576129ab6128a6565b029392505050565b600061217c60ff841683612912565b80820281158282048414176106b0576106b06128a6565b6000602082840312156129eb57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612a758160178501602088016123af565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612aa68160288401602088016123af565b01602801949350505050565b634e487b7160e01b600052602160045260246000fd5b601f8211156107aa57600081815260208120601f850160051c81016020861015612aef5750805b601f850160051c820191505b81811015612b0e57828155600101612afb565b505050505050565b815167ffffffffffffffff811115612b3057612b306124f4565b612b4481612b3e84546127da565b84612ac8565b602080601f831160018114612b795760008415612b615750858301515b600019600386901b1c1916600185901b178555612b0e565b600085815260208120601f198616915b82811015612ba857888601518255948401946001909101908401612b89565b5085821015612bc65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b600081612bfb57612bfb6128a6565b506000190190565b60008251612c158184602087016123af565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220f9aad7c91082494bdf7a7c18ca6a28a1c6bf0d4f119d38c1c77eca5081afbcc564736f6c63430008120033
Deployed ByteCode
0x6080604052600436106102045760003560e01c80635c975abb11610118578063a457c2d7116100a0578063d547741f1161006f578063d547741f146105c9578063dd62ed3e146105e9578063e56f2fe414610609578063e63ab1e914610629578063f72c0d8b1461064b57600080fd5b8063a457c2d714610535578063a9059cbb14610555578063d505accf14610575578063d53913931461059557600080fd5b80638456cb59116100e75780638456cb59146104ae57806384b0196e146104c357806391d14854146104eb57806395d89b411461050b578063a217fddf1461052057600080fd5b80635c975abb1461042057806370a082311461043857806379cc67901461046e5780637ecebe001461048e57600080fd5b80633644e5151161019b5780633f4ba83a1161016a5780633f4ba83a146103a357806340c10f19146103b857806342966c68146103d85780634f1ef286146103f857806352d1902d1461040b57600080fd5b80633644e5151461032e57806336568abe146103435780633659cfe614610363578063395093511461038357600080fd5b806323b872dd116101d757806323b872dd1461029f578063248a9ca3146102bf5780632f2ff15d146102f0578063313ce5671461031257600080fd5b806301ffc9a71461020957806306fdde031461023e578063095ea7b31461026057806318160ddd14610280575b600080fd5b34801561021557600080fd5b50610229610224366004612385565b61067f565b60405190151581526020015b60405180910390f35b34801561024a57600080fd5b506102536106b6565b60405161023591906123ff565b34801561026c57600080fd5b5061022961027b36600461242e565b610748565b34801561028c57600080fd5b506035545b604051908152602001610235565b3480156102ab57600080fd5b506102296102ba366004612458565b610760565b3480156102cb57600080fd5b506102916102da366004612494565b600090815261012d602052604090206001015490565b3480156102fc57600080fd5b5061031061030b3660046124ad565b610784565b005b34801561031e57600080fd5b5060405160128152602001610235565b34801561033a57600080fd5b506102916107af565b34801561034f57600080fd5b5061031061035e3660046124ad565b6107be565b34801561036f57600080fd5b5061031061037e3660046124d9565b610841565b34801561038f57600080fd5b5061022961039e36600461242e565b610920565b3480156103af57600080fd5b50610310610942565b3480156103c457600080fd5b506103106103d336600461242e565b610962565b3480156103e457600080fd5b506103106103f3366004612494565b610996565b610310610406366004612580565b6109a0565b34801561041757600080fd5b50610291610a6c565b34801561042c57600080fd5b5060975460ff16610229565b34801561044457600080fd5b506102916104533660046124d9565b6001600160a01b031660009081526033602052604090205490565b34801561047a57600080fd5b5061031061048936600461242e565b610b1f565b34801561049a57600080fd5b506102916104a93660046124d9565b610b34565b3480156104ba57600080fd5b50610310610b53565b3480156104cf57600080fd5b506104d8610b73565b60405161023597969594939291906125e2565b3480156104f757600080fd5b506102296105063660046124ad565b610c13565b34801561051757600080fd5b50610253610c3f565b34801561052c57600080fd5b50610291600081565b34801561054157600080fd5b5061022961055036600461242e565b610c4e565b34801561056157600080fd5b5061022961057036600461242e565b610cc9565b34801561058157600080fd5b50610310610590366004612678565b610cd7565b3480156105a157600080fd5b506102917f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b3480156105d557600080fd5b506103106105e43660046124ad565b610e3b565b3480156105f557600080fd5b506102916106043660046126eb565b610e61565b34801561061557600080fd5b50610310610624366004612735565b610e8c565b34801561063557600080fd5b50610291600080516020612c4083398151915281565b34801561065757600080fd5b506102917f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b60006001600160e01b03198216637965db0b60e01b14806106b057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060603680546106c5906127da565b80601f01602080910402602001604051908101604052809291908181526020018280546106f1906127da565b801561073e5780601f106107135761010080835404028352916020019161073e565b820191906000526020600020905b81548152906001019060200180831161072157829003601f168201915b5050505050905090565b600033610756818585611069565b5060019392505050565b60003361076e85828561118d565b610779858585611207565b506001949350505050565b600082815261012d60205260409020600101546107a0816113bd565b6107aa83836113c7565b505050565b60006107b961144e565b905090565b6001600160a01b03811633146108335760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61083d8282611458565b5050565b6001600160a01b037f0000000000000000000000004f51170c61ca6cad9ae13845ac1838fbf63229111630036108895760405162461bcd60e51b815260040161082a9061280e565b7f0000000000000000000000004f51170c61ca6cad9ae13845ac1838fbf63229116001600160a01b03166108d2600080516020612c20833981519152546001600160a01b031690565b6001600160a01b0316146108f85760405162461bcd60e51b815260040161082a9061285a565b610901816114c0565b6040805160008082526020820190925261091d918391906114ea565b50565b6000336107568185856109338383610e61565b61093d91906128bc565b611069565b600080516020612c4083398151915261095a816113bd565b61091d611655565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661098c816113bd565b6107aa83836116a7565b61091d3382611774565b6001600160a01b037f0000000000000000000000004f51170c61ca6cad9ae13845ac1838fbf63229111630036109e85760405162461bcd60e51b815260040161082a9061280e565b7f0000000000000000000000004f51170c61ca6cad9ae13845ac1838fbf63229116001600160a01b0316610a31600080516020612c20833981519152546001600160a01b031690565b6001600160a01b031614610a575760405162461bcd60e51b815260040161082a9061285a565b610a60826114c0565b61083d828260016114ea565b6000306001600160a01b037f0000000000000000000000004f51170c61ca6cad9ae13845ac1838fbf63229111614610b0c5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161082a565b50600080516020612c2083398151915290565b610b2a82338361118d565b61083d8282611774565b6001600160a01b038116600090815261019360205260408120546106b0565b600080516020612c40833981519152610b6b816113bd565b61091d6118b4565b60006060806000806000606061015f546000801b148015610b95575061016054155b610bd95760405162461bcd60e51b81526020600482015260156024820152741152540dcc4c8e88155b9a5b9a5d1a585b1a5e9959605a1b604482015260640161082a565b610be16118f1565b610be9611901565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b600091825261012d602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060603780546106c5906127da565b60003381610c5c8286610e61565b905083811015610cbc5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161082a565b6107798286868403611069565b600033610756818585611207565b83421115610d275760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015260640161082a565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610d568c611911565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610db18261193a565b90506000610dc182878787611967565b9050896001600160a01b0316816001600160a01b031614610e245760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015260640161082a565b610e2f8a8a8a611069565b50505050505050505050565b600082815261012d6020526040902060010154610e57816113bd565b6107aa8383611458565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b600054610100900460ff1615808015610eac5750600054600160ff909116105b80610ec65750303b158015610ec6575060005460ff166001145b610f295760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161082a565b6000805460ff191660011790558015610f4c576000805461ff0019166101001790555b610f568787611991565b610f5e6119c2565b610f666119eb565b610f6e6119c2565b610f7787611a1a565b610f7f6119c2565b610f8a6000866113c7565b610fa2600080516020612c40833981519152856113c7565b610fc633610fb26012600a6129b3565b610fc1906402540be4006129c2565b6116a7565b610ff07f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6846113c7565b61101a7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3836113c7565b8015611060576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b6001600160a01b0383166110cb5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161082a565b6001600160a01b03821661112c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161082a565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006111998484610e61565b9050600019811461120157818110156111f45760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161082a565b6112018484848403611069565b50505050565b6001600160a01b03831661126b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161082a565b6001600160a01b0382166112cd5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161082a565b6112d8838383611a64565b6001600160a01b038316600090815260336020526040902054818110156113505760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161082a565b6001600160a01b0380851660008181526033602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906113b09086815260200190565b60405180910390a3611201565b61091d8133611a77565b6113d18282610c13565b61083d57600082815261012d602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561140a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006107b9611ad0565b6114628282610c13565b1561083d57600082815261012d602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e361083d816113bd565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561151d576107aa83611b44565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611577575060408051601f3d908101601f19168201909252611574918101906129d9565b60015b6115da5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840161082a565b600080516020612c2083398151915281146116495760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840161082a565b506107aa838383611be0565b61165d611c05565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b0382166116fd5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161082a565b61170960008383611a64565b806035600082825461171b91906128bc565b90915550506001600160a01b0382166000818152603360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166117d45760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161082a565b6117e082600083611a64565b6001600160a01b038216600090815260336020526040902054818110156118545760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161082a565b6001600160a01b03831660008181526033602090815260408083208686039055603580548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6118bc611c4e565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861168a3390565b606061016180546106c5906127da565b606061016280546106c5906127da565b6001600160a01b0381166000908152610193602052604090208054600181018255905b50919050565b60006106b061194761144e565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600061197887878787611c94565b9150915061198581611d58565b5090505b949350505050565b600054610100900460ff166119b85760405162461bcd60e51b815260040161082a906129f2565b61083d8282611ea2565b600054610100900460ff166119e95760405162461bcd60e51b815260040161082a906129f2565b565b600054610100900460ff16611a125760405162461bcd60e51b815260040161082a906129f2565b6119e9611ee2565b600054610100900460ff16611a415760405162461bcd60e51b815260040161082a906129f2565b61091d81604051806040016040528060018152602001603160f81b815250611f15565b611a6c611c4e565b6107aa838383611f68565b611a818282610c13565b61083d57611a8e81611fce565b611a99836020611fe0565b604051602001611aaa929190612a3d565b60408051601f198184030181529082905262461bcd60e51b825261082a916004016123ff565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611afb612183565b611b036121dd565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0381163b611bb15760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161082a565b600080516020612c2083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b611be98361220f565b600082511180611bf65750805b156107aa57611201838361224f565b60975460ff166119e95760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161082a565b60975460ff16156119e95760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161082a565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611ccb5750600090506003611d4f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611d1f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611d4857600060019250925050611d4f565b9150600090505b94509492505050565b6000816004811115611d6c57611d6c612ab2565b03611d745750565b6001816004811115611d8857611d88612ab2565b03611dd55760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161082a565b6002816004811115611de957611de9612ab2565b03611e365760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161082a565b6003816004811115611e4a57611e4a612ab2565b0361091d5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161082a565b600054610100900460ff16611ec95760405162461bcd60e51b815260040161082a906129f2565b6036611ed58382612b16565b5060376107aa8282612b16565b600054610100900460ff16611f095760405162461bcd60e51b815260040161082a906129f2565b6097805460ff19169055565b600054610100900460ff16611f3c5760405162461bcd60e51b815260040161082a906129f2565b610161611f498382612b16565b50610162611f578282612b16565b5050600061015f8190556101605550565b60975460ff16156107aa5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b606482015260840161082a565b60606106b06001600160a01b03831660145b60606000611fef8360026129c2565b611ffa9060026128bc565b67ffffffffffffffff811115612012576120126124f4565b6040519080825280601f01601f19166020018201604052801561203c576020820181803683370190505b509050600360fc1b8160008151811061205757612057612bd6565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061208657612086612bd6565b60200101906001600160f81b031916908160001a90535060006120aa8460026129c2565b6120b59060016128bc565b90505b600181111561212d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106120e9576120e9612bd6565b1a60f81b8282815181106120ff576120ff612bd6565b60200101906001600160f81b031916908160001a90535060049490941c9361212681612bec565b90506120b8565b50831561217c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161082a565b9392505050565b60008061218e6118f1565b8051909150156121a5578051602090910120919050565b61015f5480156121b55792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b6000806121e8611901565b8051909150156121ff578051602090910120919050565b6101605480156121b55792915050565b61221881611b44565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b606061217c8383604051806060016040528060278152602001612c60602791396060600080856001600160a01b03168560405161228c9190612c03565b600060405180830381855af49150503d80600081146122c7576040519150601f19603f3d011682016040523d82523d6000602084013e6122cc565b606091505b50915091506122dd868383876122e7565b9695505050505050565b6060831561235657825160000361234f576001600160a01b0385163b61234f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161082a565b5081611989565b611989838381511561236b5781518083602001fd5b8060405162461bcd60e51b815260040161082a91906123ff565b60006020828403121561239757600080fd5b81356001600160e01b03198116811461217c57600080fd5b60005b838110156123ca5781810151838201526020016123b2565b50506000910152565b600081518084526123eb8160208601602086016123af565b601f01601f19169290920160200192915050565b60208152600061217c60208301846123d3565b80356001600160a01b038116811461242957600080fd5b919050565b6000806040838503121561244157600080fd5b61244a83612412565b946020939093013593505050565b60008060006060848603121561246d57600080fd5b61247684612412565b925061248460208501612412565b9150604084013590509250925092565b6000602082840312156124a657600080fd5b5035919050565b600080604083850312156124c057600080fd5b823591506124d060208401612412565b90509250929050565b6000602082840312156124eb57600080fd5b61217c82612412565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612525576125256124f4565b604051601f8501601f19908116603f0116810190828211818310171561254d5761254d6124f4565b8160405280935085815286868601111561256657600080fd5b858560208301376000602087830101525050509392505050565b6000806040838503121561259357600080fd5b61259c83612412565b9150602083013567ffffffffffffffff8111156125b857600080fd5b8301601f810185136125c957600080fd5b6125d88582356020840161250a565b9150509250929050565b60ff60f81b881681526000602060e08184015261260260e084018a6123d3565b8381036040850152612614818a6123d3565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b818110156126665783518352928401929184019160010161264a565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561269357600080fd5b61269c88612412565b96506126aa60208901612412565b95506040880135945060608801359350608088013560ff811681146126ce57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156126fe57600080fd5b61270783612412565b91506124d060208401612412565b600082601f83011261272657600080fd5b61217c8383356020850161250a565b60008060008060008060c0878903121561274e57600080fd5b863567ffffffffffffffff8082111561276657600080fd5b6127728a838b01612715565b9750602089013591508082111561278857600080fd5b5061279589828a01612715565b9550506127a460408801612412565b93506127b260608801612412565b92506127c060808801612412565b91506127ce60a08801612412565b90509295509295509295565b600181811c908216806127ee57607f821691505b60208210810361193457634e487b7160e01b600052602260045260246000fd5b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b808201808211156106b0576106b06128a6565b600181815b8085111561290a5781600019048211156128f0576128f06128a6565b808516156128fd57918102915b93841c93908002906128d4565b509250929050565b600082612921575060016106b0565b8161292e575060006106b0565b8160018114612944576002811461294e5761296a565b60019150506106b0565b60ff84111561295f5761295f6128a6565b50506001821b6106b0565b5060208310610133831016604e8410600b841016171561298d575081810a6106b0565b61299783836128cf565b80600019048211156129ab576129ab6128a6565b029392505050565b600061217c60ff841683612912565b80820281158282048414176106b0576106b06128a6565b6000602082840312156129eb57600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612a758160178501602088016123af565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612aa68160288401602088016123af565b01602801949350505050565b634e487b7160e01b600052602160045260246000fd5b601f8211156107aa57600081815260208120601f850160051c81016020861015612aef5750805b601f850160051c820191505b81811015612b0e57828155600101612afb565b505050505050565b815167ffffffffffffffff811115612b3057612b306124f4565b612b4481612b3e84546127da565b84612ac8565b602080601f831160018114612b795760008415612b615750858301515b600019600386901b1c1916600185901b178555612b0e565b600085815260208120601f198616915b82811015612ba857888601518255948401946001909101908401612b89565b5085821015612bc65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b600081612bfb57612bfb6128a6565b506000190190565b60008251612c158184602087016123af565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220f9aad7c91082494bdf7a7c18ca6a28a1c6bf0d4f119d38c1c77eca5081afbcc564736f6c63430008120033