Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 12728656 | 1093 days ago | IN | Create: PToken | 0 ETH | 0.0975971 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
PToken
Compiler Version
v0.6.2+commit.bacdbe57
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-06-29 */ // File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts-upgradeable/proxy/Initializable.sol // SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; /** * @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 a proxied contract can't have 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. * * 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 {UpgradeableProxy-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. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } } // File: @openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN 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 initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable { function __AccessControl_init() internal initializer { __Context_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer { } using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; using AddressUpgradeable for address; struct RoleData { EnumerableSetUpgradeable.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @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 {_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) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/cryptography/ECDSAUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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 { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. 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. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length if (signature.length != 65) { revert("ECDSA: invalid signature length"); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value"); require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value"); // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); require(signer != address(0), "ECDSA: invalid signature"); return signer; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * replicates the behavior of the * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`] * JSON-RPC method. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } } // File: @openzeppelin/contracts-upgradeable/GSN/IRelayRecipientUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Base interface for a contract that will be called via the GSN from {IRelayHub}. * * TIP: You don't need to write an implementation yourself! Inherit from {GSNRecipient} instead. */ interface IRelayRecipientUpgradeable { /** * @dev Returns the address of the {IRelayHub} instance this recipient interacts with. */ function getHubAddr() external view returns (address); /** * @dev Called by {IRelayHub} to validate if this recipient accepts being charged for a relayed call. Note that the * recipient will be charged regardless of the execution result of the relayed call (i.e. if it reverts or not). * * The relay request was originated by `from` and will be served by `relay`. `encodedFunction` is the relayed call * calldata, so its first four bytes are the function selector. The relayed call will be forwarded `gasLimit` gas, * and the transaction executed with a gas price of at least `gasPrice`. ``relay``'s fee is `transactionFee`, and the * recipient will be charged at most `maxPossibleCharge` (in wei). `nonce` is the sender's (`from`) nonce for * replay attack protection in {IRelayHub}, and `approvalData` is a optional parameter that can be used to hold a signature * over all or some of the previous values. * * Returns a tuple, where the first value is used to indicate approval (0) or rejection (custom non-zero error code, * values 1 to 10 are reserved) and the second one is data to be passed to the other {IRelayRecipient} functions. * * {acceptRelayedCall} is called with 50k gas: if it runs out during execution, the request will be considered * rejected. A regular revert will also trigger a rejection. */ function acceptRelayedCall( address relay, address from, bytes calldata encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes calldata approvalData, uint256 maxPossibleCharge ) external view returns (uint256, bytes memory); /** * @dev Called by {IRelayHub} on approved relay call requests, before the relayed call is executed. This allows to e.g. * pre-charge the sender of the transaction. * * `context` is the second value returned in the tuple by {acceptRelayedCall}. * * Returns a value to be passed to {postRelayedCall}. * * {preRelayedCall} is called with 100k gas: if it runs out during execution or otherwise reverts, the relayed call * will not be executed, but the recipient will still be charged for the transaction's cost. */ function preRelayedCall(bytes calldata context) external returns (bytes32); /** * @dev Called by {IRelayHub} on approved relay call requests, after the relayed call is executed. This allows to e.g. * charge the user for the relayed call costs, return any overcharges from {preRelayedCall}, or perform * contract-specific bookkeeping. * * `context` is the second value returned in the tuple by {acceptRelayedCall}. `success` is the execution status of * the relayed call. `actualCharge` is an estimate of how much the recipient will be charged for the transaction, * not including any gas used by {postRelayedCall} itself. `preRetVal` is {preRelayedCall}'s return value. * * * {postRelayedCall} is called with 100k gas: if it runs out during execution or otherwise reverts, the relayed call * and the call to {preRelayedCall} will be reverted retroactively, but the recipient will still be charged for the * transaction's cost. */ function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external; } // File: @openzeppelin/contracts-upgradeable/GSN/IRelayHubUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract * directly. * * See the https://github.com/OpenZeppelin/openzeppelin-gsn-helpers[OpenZeppelin GSN helpers] for more information on * how to deploy an instance of `RelayHub` on your local test network. */ interface IRelayHubUpgradeable { // Relay management /** * @dev Adds stake to a relay and sets its `unstakeDelay`. If the relay does not exist, it is created, and the caller * of this function becomes its owner. If the relay already exists, only the owner can call this function. A relay * cannot be its own owner. * * All Ether in this function call will be added to the relay's stake. * Its unstake delay will be assigned to `unstakeDelay`, but the new value must be greater or equal to the current one. * * Emits a {Staked} event. */ function stake(address relayaddr, uint256 unstakeDelay) external payable; /** * @dev Emitted when a relay's stake or unstakeDelay are increased */ event Staked(address indexed relay, uint256 stake, uint256 unstakeDelay); /** * @dev Registers the caller as a relay. * The relay must be staked for, and not be a contract (i.e. this function must be called directly from an EOA). * * This function can be called multiple times, emitting new {RelayAdded} events. Note that the received * `transactionFee` is not enforced by {relayCall}. * * Emits a {RelayAdded} event. */ function registerRelay(uint256 transactionFee, string calldata url) external; /** * @dev Emitted when a relay is registered or re-registered. Looking at these events (and filtering out * {RelayRemoved} events) lets a client discover the list of available relays. */ event RelayAdded(address indexed relay, address indexed owner, uint256 transactionFee, uint256 stake, uint256 unstakeDelay, string url); /** * @dev Removes (deregisters) a relay. Unregistered (but staked for) relays can also be removed. * * Can only be called by the owner of the relay. After the relay's `unstakeDelay` has elapsed, {unstake} will be * callable. * * Emits a {RelayRemoved} event. */ function removeRelayByOwner(address relay) external; /** * @dev Emitted when a relay is removed (deregistered). `unstakeTime` is the time when unstake will be callable. */ event RelayRemoved(address indexed relay, uint256 unstakeTime); /** Deletes the relay from the system, and gives back its stake to the owner. * * Can only be called by the relay owner, after `unstakeDelay` has elapsed since {removeRelayByOwner} was called. * * Emits an {Unstaked} event. */ function unstake(address relay) external; /** * @dev Emitted when a relay is unstaked for, including the returned stake. */ event Unstaked(address indexed relay, uint256 stake); // States a relay can be in enum RelayState { Unknown, // The relay is unknown to the system: it has never been staked for Staked, // The relay has been staked for, but it is not yet active Registered, // The relay has registered itself, and is active (can relay calls) Removed // The relay has been removed by its owner and can no longer relay calls. It must wait for its unstakeDelay to elapse before it can unstake } /** * @dev Returns a relay's status. Note that relays can be deleted when unstaked or penalized, causing this function * to return an empty entry. */ function getRelay(address relay) external view returns (uint256 totalStake, uint256 unstakeDelay, uint256 unstakeTime, address payable owner, RelayState state); // Balance management /** * @dev Deposits Ether for a contract, so that it can receive (and pay for) relayed transactions. * * Unused balance can only be withdrawn by the contract itself, by calling {withdraw}. * * Emits a {Deposited} event. */ function depositFor(address target) external payable; /** * @dev Emitted when {depositFor} is called, including the amount and account that was funded. */ event Deposited(address indexed recipient, address indexed from, uint256 amount); /** * @dev Returns an account's deposits. These can be either a contract's funds, or a relay owner's revenue. */ function balanceOf(address target) external view returns (uint256); /** * Withdraws from an account's balance, sending it back to it. Relay owners call this to retrieve their revenue, and * contracts can use it to reduce their funding. * * Emits a {Withdrawn} event. */ function withdraw(uint256 amount, address payable dest) external; /** * @dev Emitted when an account withdraws funds from `RelayHub`. */ event Withdrawn(address indexed account, address indexed dest, uint256 amount); // Relaying /** * @dev Checks if the `RelayHub` will accept a relayed operation. * Multiple things must be true for this to happen: * - all arguments must be signed for by the sender (`from`) * - the sender's nonce must be the current one * - the recipient must accept this transaction (via {acceptRelayedCall}) * * Returns a `PreconditionCheck` value (`OK` when the transaction can be relayed), or a recipient-specific error * code if it returns one in {acceptRelayedCall}. */ function canRelay( address relay, address from, address to, bytes calldata encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes calldata signature, bytes calldata approvalData ) external view returns (uint256 status, bytes memory recipientContext); // Preconditions for relaying, checked by canRelay and returned as the corresponding numeric values. enum PreconditionCheck { OK, // All checks passed, the call can be relayed WrongSignature, // The transaction to relay is not signed by requested sender WrongNonce, // The provided nonce has already been used by the sender AcceptRelayedCallReverted, // The recipient rejected this call via acceptRelayedCall InvalidRecipientStatusCode // The recipient returned an invalid (reserved) status code } /** * @dev Relays a transaction. * * For this to succeed, multiple conditions must be met: * - {canRelay} must `return PreconditionCheck.OK` * - the sender must be a registered relay * - the transaction's gas price must be larger or equal to the one that was requested by the sender * - the transaction must have enough gas to not run out of gas if all internal transactions (calls to the * recipient) use all gas available to them * - the recipient must have enough balance to pay the relay for the worst-case scenario (i.e. when all gas is * spent) * * If all conditions are met, the call will be relayed and the recipient charged. {preRelayedCall}, the encoded * function and {postRelayedCall} will be called in that order. * * Parameters: * - `from`: the client originating the request * - `to`: the target {IRelayRecipient} contract * - `encodedFunction`: the function call to relay, including data * - `transactionFee`: fee (%) the relay takes over actual gas cost * - `gasPrice`: gas price the client is willing to pay * - `gasLimit`: gas to forward when calling the encoded function * - `nonce`: client's nonce * - `signature`: client's signature over all previous params, plus the relay and RelayHub addresses * - `approvalData`: dapp-specific data forwarded to {acceptRelayedCall}. This value is *not* verified by the * `RelayHub`, but it still can be used for e.g. a signature. * * Emits a {TransactionRelayed} event. */ function relayCall( address from, address to, bytes calldata encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes calldata signature, bytes calldata approvalData ) external; /** * @dev Emitted when an attempt to relay a call failed. * * This can happen due to incorrect {relayCall} arguments, or the recipient not accepting the relayed call. The * actual relayed call was not executed, and the recipient not charged. * * The `reason` parameter contains an error code: values 1-10 correspond to `PreconditionCheck` entries, and values * over 10 are custom recipient error codes returned from {acceptRelayedCall}. */ event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason); /** * @dev Emitted when a transaction is relayed. * Useful when monitoring a relay's operation and relayed calls to a contract * * Note that the actual encoded function might be reverted: this is indicated in the `status` parameter. * * `charge` is the Ether value deducted from the recipient's balance, paid to the relay's owner. */ event TransactionRelayed(address indexed relay, address indexed from, address indexed to, bytes4 selector, RelayCallStatus status, uint256 charge); // Reason error codes for the TransactionRelayed event enum RelayCallStatus { OK, // The transaction was successfully relayed and execution successful - never included in the event RelayedCallFailed, // The transaction was relayed, but the relayed call failed PreRelayedFailed, // The transaction was not relayed due to preRelatedCall reverting PostRelayedFailed, // The transaction was relayed and reverted due to postRelatedCall reverting RecipientBalanceChanged // The transaction was relayed and reverted due to the recipient's balance changing } /** * @dev Returns how much gas should be forwarded to a call to {relayCall}, in order to relay a transaction that will * spend up to `relayedCallStipend` gas. */ function requiredGas(uint256 relayedCallStipend) external view returns (uint256); /** * @dev Returns the maximum recipient charge, given the amount of gas forwarded, gas price and relay fee. */ function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) external view returns (uint256); // Relay penalization. // Any account can penalize relays, removing them from the system immediately, and rewarding the // reporter with half of the relay's stake. The other half is burned so that, even if the relay penalizes itself, it // still loses half of its stake. /** * @dev Penalize a relay that signed two transactions using the same nonce (making only the first one valid) and * different data (gas price, gas limit, etc. may be different). * * The (unsigned) transaction data and signature for both transactions must be provided. */ function penalizeRepeatedNonce(bytes calldata unsignedTx1, bytes calldata signature1, bytes calldata unsignedTx2, bytes calldata signature2) external; /** * @dev Penalize a relay that sent a transaction that didn't target ``RelayHub``'s {registerRelay} or {relayCall}. */ function penalizeIllegalTransaction(bytes calldata unsignedTx, bytes calldata signature) external; /** * @dev Emitted when a relay is penalized. */ event Penalized(address indexed relay, address sender, uint256 amount); /** * @dev Returns an account's nonce in `RelayHub`. */ function getNonce(address from) external view returns (uint256); } // File: @openzeppelin/contracts-upgradeable/GSN/GSNRecipientUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Base GSN recipient contract: includes the {IRelayRecipient} interface * and enables GSN support on all contracts in the inheritance tree. * * TIP: This contract is abstract. The functions {IRelayRecipient-acceptRelayedCall}, * {_preRelayedCall}, and {_postRelayedCall} are not implemented and must be * provided by derived contracts. See the * xref:ROOT:gsn-strategies.adoc#gsn-strategies[GSN strategies] for more * information on how to use the pre-built {GSNRecipientSignature} and * {GSNRecipientERC20Fee}, or how to write your own. */ abstract contract GSNRecipientUpgradeable is Initializable, IRelayRecipientUpgradeable, ContextUpgradeable { function __GSNRecipient_init() internal initializer { __Context_init_unchained(); __GSNRecipient_init_unchained(); } function __GSNRecipient_init_unchained() internal initializer { _relayHub = 0xD216153c06E857cD7f72665E0aF1d7D82172F494; } // Default RelayHub address, deployed on mainnet and all testnets at the same address address private _relayHub; uint256 constant private _RELAYED_CALL_ACCEPTED = 0; uint256 constant private _RELAYED_CALL_REJECTED = 11; // How much gas is forwarded to postRelayedCall uint256 constant internal _POST_RELAYED_CALL_MAX_GAS = 100000; /** * @dev Emitted when a contract changes its {IRelayHub} contract to a new one. */ event RelayHubChanged(address indexed oldRelayHub, address indexed newRelayHub); /** * @dev Returns the address of the {IRelayHub} contract for this recipient. */ function getHubAddr() public view virtual override returns (address) { return _relayHub; } /** * @dev Switches to a new {IRelayHub} instance. This method is added for future-proofing: there's no reason to not * use the default instance. * * IMPORTANT: After upgrading, the {GSNRecipient} will no longer be able to receive relayed calls from the old * {IRelayHub} instance. Additionally, all funds should be previously withdrawn via {_withdrawDeposits}. */ function _upgradeRelayHub(address newRelayHub) internal virtual { address currentRelayHub = _relayHub; require(newRelayHub != address(0), "GSNRecipient: new RelayHub is the zero address"); require(newRelayHub != currentRelayHub, "GSNRecipient: new RelayHub is the current one"); emit RelayHubChanged(currentRelayHub, newRelayHub); _relayHub = newRelayHub; } /** * @dev Returns the version string of the {IRelayHub} for which this recipient implementation was built. If * {_upgradeRelayHub} is used, the new {IRelayHub} instance should be compatible with this version. */ // This function is view for future-proofing, it may require reading from // storage in the future. function relayHubVersion() public view virtual returns (string memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return "1.0.0"; } /** * @dev Withdraws the recipient's deposits in `RelayHub`. * * Derived contracts should expose this in an external interface with proper access control. */ function _withdrawDeposits(uint256 amount, address payable payee) internal virtual { IRelayHubUpgradeable(getHubAddr()).withdraw(amount, payee); } // Overrides for Context's functions: when called from RelayHub, sender and // data require some pre-processing: the actual sender is stored at the end // of the call data, which in turns means it needs to be removed from it // when handling said data. /** * @dev Replacement for msg.sender. Returns the actual sender of a transaction: msg.sender for regular transactions, * and the end-user for GSN relayed calls (where msg.sender is actually `RelayHub`). * * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead. */ function _msgSender() internal view virtual override returns (address payable) { if (msg.sender != getHubAddr()) { return msg.sender; } else { return _getRelayedCallSender(); } } /** * @dev Replacement for msg.data. Returns the actual calldata of a transaction: msg.data for regular transactions, * and a reduced version for GSN relayed calls (where msg.data contains additional information). * * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.data`, and use {_msgData} instead. */ function _msgData() internal view virtual override returns (bytes memory) { if (msg.sender != getHubAddr()) { return msg.data; } else { return _getRelayedCallData(); } } // Base implementations for pre and post relayedCall: only RelayHub can invoke them, and data is forwarded to the // internal hook. /** * @dev See `IRelayRecipient.preRelayedCall`. * * This function should not be overridden directly, use `_preRelayedCall` instead. * * * Requirements: * * - the caller must be the `RelayHub` contract. */ function preRelayedCall(bytes memory context) public virtual override returns (bytes32) { require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub"); return _preRelayedCall(context); } /** * @dev See `IRelayRecipient.preRelayedCall`. * * Called by `GSNRecipient.preRelayedCall`, which asserts the caller is the `RelayHub` contract. Derived contracts * must implement this function with any relayed-call preprocessing they may wish to do. * */ function _preRelayedCall(bytes memory context) internal virtual returns (bytes32); /** * @dev See `IRelayRecipient.postRelayedCall`. * * This function should not be overridden directly, use `_postRelayedCall` instead. * * * Requirements: * * - the caller must be the `RelayHub` contract. */ function postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) public virtual override { require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub"); _postRelayedCall(context, success, actualCharge, preRetVal); } /** * @dev See `IRelayRecipient.postRelayedCall`. * * Called by `GSNRecipient.postRelayedCall`, which asserts the caller is the `RelayHub` contract. Derived contracts * must implement this function with any relayed-call postprocessing they may wish to do. * */ function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal virtual; /** * @dev Return this in acceptRelayedCall to proceed with the execution of a relayed call. Note that this contract * will be charged a fee by RelayHub */ function _approveRelayedCall() internal pure virtual returns (uint256, bytes memory) { return _approveRelayedCall(""); } /** * @dev See `GSNRecipient._approveRelayedCall`. * * This overload forwards `context` to _preRelayedCall and _postRelayedCall. */ function _approveRelayedCall(bytes memory context) internal pure virtual returns (uint256, bytes memory) { return (_RELAYED_CALL_ACCEPTED, context); } /** * @dev Return this in acceptRelayedCall to impede execution of a relayed call. No fees will be charged. */ function _rejectRelayedCall(uint256 errorCode) internal pure virtual returns (uint256, bytes memory) { return (_RELAYED_CALL_REJECTED + errorCode, ""); } /* * @dev Calculates how much RelayHub will charge a recipient for using `gas` at a `gasPrice`, given a relayer's * `serviceFee`. */ function _computeCharge(uint256 gas, uint256 gasPrice, uint256 serviceFee) internal pure virtual returns (uint256) { // The fee is expressed as a percentage. E.g. a value of 40 stands for a 40% fee, so the recipient will be // charged for 1.4 times the spent amount. return (gas * gasPrice * (100 + serviceFee)) / 100; } function _getRelayedCallSender() private pure returns (address payable result) { // We need to read 20 bytes (an address) located at array index msg.data.length - 20. In memory, the array // is prefixed with a 32-byte length value, so we first add 32 to get the memory read index. However, doing // so would leave the address in the upper 20 bytes of the 32-byte word, which is inconvenient and would // require bit shifting. We therefore subtract 12 from the read index so the address lands on the lower 20 // bytes. This can always be done due to the 32-byte prefix. // The final memory read index is msg.data.length - 20 + 32 - 12 = msg.data.length. Using inline assembly is the // easiest/most-efficient way to perform this operation. // These fields are not accessible from assembly bytes memory array = msg.data; uint256 index = msg.data.length; // solhint-disable-next-line no-inline-assembly assembly { // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those. result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff) } return result; } function _getRelayedCallData() private pure returns (bytes memory) { // RelayHub appends the sender address at the end of the calldata, so in order to retrieve the actual msg.data, // we must strip the last 20 bytes (length of an address type) from it. uint256 actualDataLength = msg.data.length - 20; bytes memory actualData = new bytes(actualDataLength); for (uint256 i = 0; i < actualDataLength; ++i) { actualData[i] = msg.data[i]; } return actualData; } uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; } // File: @openzeppelin/contracts-upgradeable/token/ERC777/IERC777Upgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC777Token standard as defined in the EIP. * * This contract uses the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let * token holders and recipients react to token movements by using setting implementers * for the associated interfaces in said registry. See {IERC1820Registry} and * {ERC1820Implementer}. */ interface IERC777Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() external view returns (string memory); /** * @dev Returns the smallest part of the token that is not divisible. This * means all token operations (creation, movement and destruction) must have * amounts that are a multiple of this number. * * For most token contracts, this value will equal 1. */ function granularity() external view returns (uint256); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by an account (`owner`). */ function balanceOf(address owner) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * If send or receive hooks are registered for the caller and `recipient`, * the corresponding functions will be called with `data` and empty * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - the caller must have at least `amount` tokens. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function send(address recipient, uint256 amount, bytes calldata data) external; /** * @dev Destroys `amount` tokens from the caller's account, reducing the * total supply. * * If a send hook is registered for the caller, the corresponding function * will be called with `data` and empty `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - the caller must have at least `amount` tokens. */ function burn(uint256 amount, bytes calldata data) external; /** * @dev Returns true if an account is an operator of `tokenHolder`. * Operators can send and burn tokens on behalf of their owners. All * accounts are their own operator. * * See {operatorSend} and {operatorBurn}. */ function isOperatorFor(address operator, address tokenHolder) external view returns (bool); /** * @dev Make an account an operator of the caller. * * See {isOperatorFor}. * * Emits an {AuthorizedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function authorizeOperator(address operator) external; /** * @dev Revoke an account's operator status for the caller. * * See {isOperatorFor} and {defaultOperators}. * * Emits a {RevokedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function revokeOperator(address operator) external; /** * @dev Returns the list of default operators. These accounts are operators * for all token holders, even if {authorizeOperator} was never called on * them. * * This list is immutable, but individual holders may revoke these via * {revokeOperator}, in which case {isOperatorFor} will return false. */ function defaultOperators() external view returns (address[] memory); /** * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must * be an operator of `sender`. * * If send or receive hooks are registered for `sender` and `recipient`, * the corresponding functions will be called with `data` and * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - `sender` cannot be the zero address. * - `sender` must have at least `amount` tokens. * - the caller must be an operator for `sender`. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function operatorSend( address sender, address recipient, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; /** * @dev Destroys `amount` tokens from `account`, reducing the total supply. * The caller must be an operator of `account`. * * If a send hook is registered for `account`, the corresponding function * will be called with `data` and `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. * - the caller must be an operator for `account`. */ function operatorBurn( address account, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; event Sent( address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData ); event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); event AuthorizedOperator(address indexed operator, address indexed tokenHolder); event RevokedOperator(address indexed operator, address indexed tokenHolder); } // File: @openzeppelin/contracts-upgradeable/token/ERC777/IERC777RecipientUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. * * Accounts can be notified of {IERC777} tokens being sent to them by having a * contract implement this interface (contract holders can be their own * implementer) and registering it on the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. * * See {IERC1820Registry} and {ERC1820Implementer}. */ interface IERC777RecipientUpgradeable { /** * @dev Called by an {IERC777} token contract whenever tokens are being * moved or created into a registered account (`to`). The type of operation * is conveyed by `from` being the zero address or not. * * This call occurs _after_ the token contract's state is updated, so * {IERC777-balanceOf}, etc., can be used to query the post-operation state. * * This function may revert to prevent the operation from being executed. */ function tokensReceived( address operator, address from, address to, uint256 amount, bytes calldata userData, bytes calldata operatorData ) external; } // File: @openzeppelin/contracts-upgradeable/token/ERC777/IERC777SenderUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC777TokensSender standard as defined in the EIP. * * {IERC777} Token holders can be notified of operations performed on their * tokens by having a contract implement this interface (contract holders can be * their own implementer) and registering it on the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. * * See {IERC1820Registry} and {ERC1820Implementer}. */ interface IERC777SenderUpgradeable { /** * @dev Called by an {IERC777} token contract whenever a registered holder's * (`from`) tokens are about to be moved or destroyed. The type of operation * is conveyed by `to` being the zero address or not. * * This call occurs _before_ the token contract's state is updated, so * {IERC777-balanceOf}, etc., can be used to query the pre-operation state. * * This function may revert to prevent the operation from being executed. */ function tokensToSend( address operator, address from, address to, uint256 amount, bytes calldata userData, bytes calldata operatorData ) external; } // File: @openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathUpgradeable { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } } // File: @openzeppelin/contracts-upgradeable/introspection/IERC1820RegistryUpgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the global ERC1820 Registry, as defined in the * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register * implementers for interfaces in this registry, as well as query support. * * Implementers may be shared by multiple accounts, and can also implement more * than a single interface for each account. Contracts can implement interfaces * for themselves, but externally-owned accounts (EOA) must delegate this to a * contract. * * {IERC165} interfaces can also be queried via the registry. * * For an in-depth explanation and source code analysis, see the EIP text. */ interface IERC1820RegistryUpgradeable { /** * @dev Sets `newManager` as the manager for `account`. A manager of an * account is able to set interface implementers for it. * * By default, each account is its own manager. Passing a value of `0x0` in * `newManager` will reset the manager to this initial state. * * Emits a {ManagerChanged} event. * * Requirements: * * - the caller must be the current manager for `account`. */ function setManager(address account, address newManager) external; /** * @dev Returns the manager for `account`. * * See {setManager}. */ function getManager(address account) external view returns (address); /** * @dev Sets the `implementer` contract as ``account``'s implementer for * `interfaceHash`. * * `account` being the zero address is an alias for the caller's address. * The zero address can also be used in `implementer` to remove an old one. * * See {interfaceHash} to learn how these are created. * * Emits an {InterfaceImplementerSet} event. * * Requirements: * * - the caller must be the current manager for `account`. * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not * end in 28 zeroes). * - `implementer` must implement {IERC1820Implementer} and return true when * queried for support, unless `implementer` is the caller. See * {IERC1820Implementer-canImplementInterfaceForAddress}. */ function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external; /** * @dev Returns the implementer of `interfaceHash` for `account`. If no such * implementer is registered, returns the zero address. * * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 * zeroes), `account` will be queried for support of it. * * `account` being the zero address is an alias for the caller's address. */ function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); /** * @dev Returns the interface hash for an `interfaceName`, as defined in the * corresponding * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. */ function interfaceHash(string calldata interfaceName) external pure returns (bytes32); /** * @notice Updates the cache with whether the contract implements an ERC165 interface or not. * @param account Address of the contract for which to update the cache. * @param interfaceId ERC165 interface for which to update the cache. */ function updateERC165Cache(address account, bytes4 interfaceId) external; /** * @notice Checks whether a contract implements an ERC165 interface or not. * If the result is not cached a direct lookup on the contract address is performed. * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling * {updateERC165Cache} with the contract address. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); /** * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); event ManagerChanged(address indexed account, address indexed newManager); } // File: contracts/ERC777Upgradeable.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Implementation of the {IERC777} 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}. * * Support for ERC20 is included in this contract, as specified by the EIP: both * the ERC777 and ERC20 interfaces can be safely used when interacting with it. * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token * movements. * * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there * are no special restrictions in the amount of tokens that created, moved, or * destroyed. This makes integration with ERC20 applications seamless. */ contract ERC777Upgradeable is Initializable, ContextUpgradeable, IERC777Upgradeable, IERC20Upgradeable { using SafeMathUpgradeable for uint256; using AddressUpgradeable for address; IERC1820RegistryUpgradeable constant internal _ERC1820_REGISTRY = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); mapping(address => uint256) private _balances; uint256 private _totalSupply; string private _name; string private _symbol; // We inline the result of the following hashes because Solidity doesn't resolve them at compile time. // See https://github.com/ethereum/solidity/issues/4024. // keccak256("ERC777TokensSender") bytes32 constant private _TOKENS_SENDER_INTERFACE_HASH = 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895; // keccak256("ERC777TokensRecipient") bytes32 constant private _TOKENS_RECIPIENT_INTERFACE_HASH = 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b; // This isn't ever read from - it's only used to respond to the defaultOperators query. address[] private _defaultOperatorsArray; // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators). mapping(address => bool) private _defaultOperators; // For each account, a mapping of its operators and revoked default operators. mapping(address => mapping(address => bool)) private _operators; mapping(address => mapping(address => bool)) private _revokedDefaultOperators; // ERC20-allowances mapping (address => mapping (address => uint256)) private _allowances; // Safemoon balance augmentation factors // Precision reflects SafeMoon's max supply of 1e15 + the 9 decimals the token has. uint256 constant private MULTIPLICATION_FACTOR_PRECISION = 1 * 10 ** 24; uint256 public userBalanceMultiplicationFactor; function augmentAmount( uint256 _amount ) internal view returns (uint256) { return _amount.mul(userBalanceMultiplicationFactor).div(MULTIPLICATION_FACTOR_PRECISION); } function deaugmentAmount( uint256 _amount ) internal view returns (uint256) { return _amount.mul(MULTIPLICATION_FACTOR_PRECISION).div(userBalanceMultiplicationFactor); } /** * @dev `defaultOperators` may be an empty array. */ function __ERC777_init( string memory name_, string memory symbol_, address[] memory defaultOperators_ ) internal initializer { __Context_init_unchained(); __ERC777_init_unchained(name_, symbol_, defaultOperators_); } function __ERC777_init_unchained( string memory name_, string memory symbol_, address[] memory defaultOperators_ ) internal initializer { _name = name_; _symbol = symbol_; _defaultOperatorsArray = defaultOperators_; for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) { _defaultOperators[_defaultOperatorsArray[i]] = true; } // register interfaces _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this)); _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this)); userBalanceMultiplicationFactor = MULTIPLICATION_FACTOR_PRECISION; } /** * @dev See {IERC777-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC777-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {ERC20-decimals}. * * Always returns 18, as per the * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility). */ function decimals() public pure virtual returns (uint8) { return 18; } /** * @dev See {IERC777-granularity}. * * This implementation always returns `1`. */ function granularity() public view virtual override returns (uint256) { return 1; } /** * @dev See {IERC777-totalSupply}. */ function totalSupply() public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) { return _totalSupply; } /** * @dev Returns the amount of tokens owned by an account (`tokenHolder`). */ function balanceOf(address tokenHolder) public view virtual override(IERC20Upgradeable, IERC777Upgradeable) returns (uint256) { return augmentAmount( _balances[tokenHolder]); } /** * @dev See {IERC777-send}. * * Also emits a {IERC20-Transfer} event for ERC20 compatibility. */ function send(address recipient, uint256 amount, bytes memory data) public virtual override { _send(_msgSender(), recipient, amount, data, "", true); } /** * @dev See {IERC20-transfer}. * * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient} * interface if it is a contract. * * Also emits a {Sent} event. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { require(recipient != address(0), "ERC777: transfer to the zero address"); address from = _msgSender(); _callTokensToSend(from, from, recipient, amount, "", ""); _move(from, from, recipient, amount, "", ""); _callTokensReceived(from, from, recipient, amount, "", "", false); return true; } /** * @dev See {IERC777-burn}. * * Also emits a {IERC20-Transfer} event for ERC20 compatibility. */ function burn(uint256 amount, bytes memory data) public virtual override { _burn(_msgSender(), amount, data, ""); } /** * @dev See {IERC777-isOperatorFor}. */ function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) { return operator == tokenHolder || (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) || _operators[tokenHolder][operator]; } /** * @dev See {IERC777-authorizeOperator}. */ function authorizeOperator(address operator) public virtual override { require(_msgSender() != operator, "ERC777: authorizing self as operator"); if (_defaultOperators[operator]) { delete _revokedDefaultOperators[_msgSender()][operator]; } else { _operators[_msgSender()][operator] = true; } emit AuthorizedOperator(operator, _msgSender()); } /** * @dev See {IERC777-revokeOperator}. */ function revokeOperator(address operator) public virtual override { require(operator != _msgSender(), "ERC777: revoking self as operator"); if (_defaultOperators[operator]) { _revokedDefaultOperators[_msgSender()][operator] = true; } else { delete _operators[_msgSender()][operator]; } emit RevokedOperator(operator, _msgSender()); } /** * @dev See {IERC777-defaultOperators}. */ function defaultOperators() public view virtual override returns (address[] memory) { return _defaultOperatorsArray; } /** * @dev See {IERC777-operatorSend}. * * Emits {Sent} and {IERC20-Transfer} events. */ function operatorSend( address sender, address recipient, uint256 amount, bytes memory data, bytes memory operatorData ) public virtual override { require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder"); _send(sender, recipient, amount, data, operatorData, true); } /** * @dev See {IERC777-operatorBurn}. * * Emits {Burned} and {IERC20-Transfer} events. */ function operatorBurn(address account, uint256 amount, bytes memory data, bytes memory operatorData) public virtual override { require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder"); _burn(account, amount, data, operatorData); } /** * @dev See {IERC20-allowance}. * * Note that operator and allowance concepts are orthogonal: operators may * not have allowance, and accounts with allowance may not be operators * themselves. */ function allowance(address holder, address spender) public view virtual override returns (uint256) { return _allowances[holder][spender]; } /** * @dev See {IERC20-approve}. * * Note that accounts cannot have allowance issued by their operators. */ function approve(address spender, uint256 value) public virtual override returns (bool) { address holder = _msgSender(); _approve(holder, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Note that operator and allowance concepts are orthogonal: operators cannot * call `transferFrom` (unless they have allowance), and accounts with * allowance cannot call `operatorSend` (unless they are operators). * * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events. */ function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) { require(recipient != address(0), "ERC777: transfer to the zero address"); require(holder != address(0), "ERC777: transfer from the zero address"); address spender = _msgSender(); _callTokensToSend(spender, holder, recipient, amount, "", ""); _move(spender, holder, recipient, amount, "", ""); _approve(holder, spender, _allowances[holder][spender].sub(amount, "ERC777: transfer amount exceeds allowance")); _callTokensReceived(spender, holder, recipient, amount, "", "", false); return true; } /** * @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * If a send hook is registered for `account`, the corresponding function * will be called with `operator`, `data` and `operatorData`. * * See {IERC777Sender} and {IERC777Recipient}. * * Emits {Minted} and {IERC20-Transfer} events. * * Requirements * * - `account` cannot be the zero address. * - if `account` is a contract, it must implement the {IERC777Recipient} * interface. */ function _mint( address account, uint256 amount, bytes memory metadata, bytes memory operatorData ) internal virtual { require(account != address(0), "ERC777: mint to the zero address"); address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), account, amount); // Ensure the metadata meets the expected length to parse out the two values we require. require(metadata.length >= 32 * 7, 'Not enough metadata to mint SafeMoon tokens!'); // Decode the pTokens core metadata wrapping // NOTE: See here for format: // https://github.com/provable-things/ptokens-core-private/blob/f2f7a680f36408c1ccdf04db77b5d89aeea80dfd/src/metadata/mod.rs#L21 (, bytes memory safeMoonSpecificMetadata, ,) = abi.decode( metadata, (bytes1, bytes, bytes4, address) ); // Decode the SafeMoon vault's metadata // NOTE See here for format: // https://github.com/provable-things/ptokens-safemoon-vault/blob/d5ff4269dd71ad3356bcaca0e8c6c7959bda01f1/contracts/Erc20Vault.sol#L316 (uint256 lastSentTotalSupply, uint256 newTotalSupply, ) = abi.decode( safeMoonSpecificMetadata, (uint256, uint256, bytes) ); // Update total supply if (totalSupply() == 0) { userBalanceMultiplicationFactor = 1 * MULTIPLICATION_FACTOR_PRECISION; } else { uint256 inflightPegouts = lastSentTotalSupply.sub(totalSupply()); newTotalSupply = newTotalSupply.sub(inflightPegouts); userBalanceMultiplicationFactor = userBalanceMultiplicationFactor .mul(newTotalSupply.sub(amount)) .div(totalSupply()); } // Update state variables _totalSupply = newTotalSupply; _balances[account] = deaugmentAmount(balanceOf(account).add(amount)); _callTokensReceived(operator, address(0), account, amount, metadata, operatorData, true); emit Minted(operator, account, amount, metadata, operatorData); emit Transfer(address(0), account, amount); } /** * @dev Send tokens * @param from address token holder address * @param to address recipient address * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient */ function _send( address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData, bool requireReceptionAck ) internal virtual { require(from != address(0), "ERC777: send from the zero address"); require(to != address(0), "ERC777: send to the zero address"); address operator = _msgSender(); _callTokensToSend(operator, from, to, amount, userData, operatorData); _move(operator, from, to, amount, userData, operatorData); _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck); } /** * @dev Burn tokens * @param from address token holder address * @param amount uint256 amount of tokens to burn * @param data bytes extra information provided by the token holder * @param operatorData bytes extra information provided by the operator (if any) */ function _burn( address from, uint256 amount, bytes memory data, bytes memory operatorData ) internal virtual { require(from != address(0), "ERC777: burn from the zero address"); address operator = _msgSender(); _callTokensToSend(operator, from, address(0), amount, data, operatorData); _beforeTokenTransfer(operator, from, address(0), amount); // Update state variables _balances[from] = _balances[from].sub(deaugmentAmount(amount), "ERC777: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Burned(operator, from, amount, data, operatorData); emit Transfer(from, address(0), amount); } function _move( address operator, address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData ) private { _beforeTokenTransfer(operator, from, to, amount); _balances[from] = _balances[from].sub(deaugmentAmount(amount), "ERC777: transfer amount exceeds balance"); _balances[to] = _balances[to].add(deaugmentAmount(amount)); emit Sent(operator, from, to, amount, userData, operatorData); emit Transfer(from, to, amount); } /** * @dev See {ERC20-_approve}. * * Note that accounts cannot have allowance issued by their operators. */ function _approve(address holder, address spender, uint256 value) internal { require(holder != address(0), "ERC777: approve from the zero address"); require(spender != address(0), "ERC777: approve to the zero address"); _allowances[holder][spender] = value; emit Approval(holder, spender, value); } /** * @dev Call from.tokensToSend() if the interface is registered * @param operator address operator requesting the transfer * @param from address token holder address * @param to address recipient address * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) */ function _callTokensToSend( address operator, address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData ) private { address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH); if (implementer != address(0)) { IERC777SenderUpgradeable(implementer).tokensToSend(operator, from, to, amount, userData, operatorData); } } /** * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but * tokensReceived() was not registered for the recipient * @param operator address operator requesting the transfer * @param from address token holder address * @param to address recipient address * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient */ function _callTokensReceived( address operator, address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData, bool requireReceptionAck ) private { address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH); if (implementer != address(0)) { IERC777RecipientUpgradeable(implementer).tokensReceived(operator, from, to, amount, userData, operatorData); } else if (requireReceptionAck) { require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient"); } } /** * @dev Hook that is called before any token transfer. This includes * calls to {send}, {transfer}, {operatorSend}, minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual { } uint256[41] private __gap; } // File: contracts/ERC777GSN.sol pragma solidity ^0.6.2; contract ERC777GSNUpgreadable is Initializable, OwnableUpgradeable, GSNRecipientUpgradeable, ERC777Upgradeable { using ECDSAUpgradeable for bytes32; uint256 constant GSN_RATE_UNIT = 10**18; enum GSNErrorCodes { INVALID_SIGNER, INSUFFICIENT_BALANCE } address public gsnTrustedSigner; address public gsnFeeTarget; uint256 public gsnExtraGas; // the gas cost of _postRelayedCall() function __ERC777GSNUpgreadable_init( address _gsnTrustedSigner, address _gsnFeeTarget ) public initializer { __GSNRecipient_init(); __Ownable_init(); require(_gsnTrustedSigner != address(0), "trusted signer is the zero address"); gsnTrustedSigner = _gsnTrustedSigner; require(_gsnFeeTarget != address(0), "fee target is the zero address"); gsnFeeTarget = _gsnFeeTarget; gsnExtraGas = 40000; } function _msgSender() internal view virtual override(ContextUpgradeable, GSNRecipientUpgradeable) returns (address payable) { return GSNRecipientUpgradeable._msgSender(); } function _msgData() internal view virtual override(ContextUpgradeable, GSNRecipientUpgradeable) returns (bytes memory) { return GSNRecipientUpgradeable._msgData(); } function setTrustedSigner(address _gsnTrustedSigner) public onlyOwner { require(_gsnTrustedSigner != address(0), "trusted signer is the zero address"); gsnTrustedSigner = _gsnTrustedSigner; } function setFeeTarget(address _gsnFeeTarget) public onlyOwner { require(_gsnFeeTarget != address(0), "fee target is the zero address"); gsnFeeTarget = _gsnFeeTarget; } function setGSNExtraGas(uint _gsnExtraGas) public onlyOwner { gsnExtraGas = _gsnExtraGas; } /** * @dev Ensures that only transactions with a trusted signature can be relayed through the GSN. */ function acceptRelayedCall( address relay, address from, bytes memory encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes memory approvalData, uint256 /* maxPossibleCharge */ ) override public view returns (uint256, bytes memory) { (uint256 feeRate, bytes memory signature) = abi.decode(approvalData, (uint, bytes)); bytes memory blob = abi.encodePacked( feeRate, relay, from, encodedFunction, transactionFee, gasPrice, gasLimit, nonce, // Prevents replays on RelayHub getHubAddr(), // Prevents replays in multiple RelayHubs address(this) // Prevents replays in multiple recipients ); if (keccak256(blob).toEthSignedMessageHash().recover(signature) == gsnTrustedSigner) { return _approveRelayedCall(abi.encode(feeRate, from, transactionFee, gasPrice)); } else { return _rejectRelayedCall(uint256(GSNErrorCodes.INVALID_SIGNER)); } } function _preRelayedCall(bytes memory context) override internal returns (bytes32) {} function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) override internal { (uint256 feeRate, address from, uint256 transactionFee, uint256 gasPrice) = abi.decode(context, (uint256, address, uint256, uint256)); // actualCharge is an _estimated_ charge, which assumes postRelayedCall will use all available gas. // This implementation's gas cost can be roughly estimated as 10k gas, for the two SSTORE operations in an // ERC20 transfer. uint256 overestimation = _computeCharge(_POST_RELAYED_CALL_MAX_GAS.sub(gsnExtraGas), gasPrice, transactionFee); uint fee = actualCharge.sub(overestimation).mul(feeRate).div(GSN_RATE_UNIT); if (fee > 0) { _send(from, gsnFeeTarget, fee, "", "", false); } } } // File: contracts/ERC777WithAdminOperator.sol pragma solidity ^0.6.2; contract ERC777WithAdminOperatorUpgreadable is Initializable, ERC777Upgradeable { address public adminOperator; event AdminOperatorChange(address oldOperator, address newOperator); event AdminTransferInvoked(address operator); function __ERC777WithAdminOperatorUpgreadable_init( address _adminOperator ) public initializer { adminOperator = _adminOperator; } /** * @dev Similar to {IERC777-operatorSend}. * * Emits {Sent} and {IERC20-Transfer} events. */ function adminTransfer( address sender, address recipient, uint256 amount, bytes memory data, bytes memory operatorData ) public { require(_msgSender() == adminOperator, "caller is not the admin operator"); _send(sender, recipient, amount, data, operatorData, false); emit AdminTransferInvoked(adminOperator); } /** * @dev Only the actual admin operator can change the address */ function setAdminOperator(address adminOperator_) public { require(_msgSender() == adminOperator, "Only the actual admin operator can change the address"); emit AdminOperatorChange(adminOperator, adminOperator_); adminOperator = adminOperator_; } } // File: contracts/pToken.sol pragma solidity ^0.6.2; /** * @dev Note that the `ERC777Upgradeable` contract is inherited via the `ERC777GSN` contract. */ contract PToken is Initializable, AccessControlUpgradeable, ERC777GSNUpgreadable, ERC777WithAdminOperatorUpgreadable { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); event Redeem( address indexed redeemer, uint256 value, string underlyingAssetRecipient, bytes userData ); function initialize( string memory tokenName, string memory tokenSymbol, address defaultAdmin ) public initializer { address[] memory defaultOperators; __AccessControl_init(); __ERC777_init(tokenName, tokenSymbol, defaultOperators); __ERC777GSNUpgreadable_init(defaultAdmin, defaultAdmin); __ERC777WithAdminOperatorUpgreadable_init(defaultAdmin); _setupRole(DEFAULT_ADMIN_ROLE, defaultAdmin); } function mint( address recipient, uint256 value, bytes memory userData, bytes memory operatorData ) public returns (bool) { require(recipient != address(this) , "Recipient cannot be the token contract address!"); require(hasRole(MINTER_ROLE, _msgSender()), "Caller is not a minter"); _mint(recipient, value, userData, operatorData); return true; } function redeem( uint256 amount, string calldata underlyingAssetRecipient ) external returns (bool) { redeem(amount, "", underlyingAssetRecipient); return true; } function redeem( uint256 amount, bytes memory userData, string memory underlyingAssetRecipient ) public { _burn(_msgSender(), amount, userData, ""); emit Redeem(_msgSender(), amount, underlyingAssetRecipient, userData); } function operatorRedeem( address account, uint256 amount, bytes calldata userData, bytes calldata operatorData, string calldata underlyingAssetRecipient ) external { require( isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder" ); _burn(account, amount, userData, operatorData); emit Redeem(account, amount, underlyingAssetRecipient, userData); } function grantMinterRole(address _account) external { grantRole(MINTER_ROLE, _account); } function revokeMinterRole(address _account) external { revokeRole(MINTER_ROLE, _account); } function hasMinterRole(address _account) external view returns (bool) { return hasRole(MINTER_ROLE, _account); } function _msgSender() internal view override(ContextUpgradeable, ERC777GSNUpgreadable) returns (address payable) { return GSNRecipientUpgradeable._msgSender(); } function _msgData() internal view override(ContextUpgradeable, ERC777GSNUpgreadable) returns (bytes memory) { return GSNRecipientUpgradeable._msgData(); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOperator","type":"address"},{"indexed":false,"internalType":"address","name":"newOperator","type":"address"}],"name":"AdminOperatorChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"AdminTransferInvoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"tokenHolder","type":"address"}],"name":"AuthorizedOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"string","name":"underlyingAssetRecipient","type":"string"},{"indexed":false,"internalType":"bytes","name":"userData","type":"bytes"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldRelayHub","type":"address"},{"indexed":true,"internalType":"address","name":"newRelayHub","type":"address"}],"name":"RelayHubChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"tokenHolder","type":"address"}],"name":"RevokedOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Sent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gsnTrustedSigner","type":"address"},{"internalType":"address","name":"_gsnFeeTarget","type":"address"}],"name":"__ERC777GSNUpgreadable_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adminOperator","type":"address"}],"name":"__ERC777WithAdminOperatorUpgreadable_init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"relay","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes","name":"encodedFunction","type":"bytes"},{"internalType":"uint256","name":"transactionFee","type":"uint256"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"approvalData","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"acceptRelayedCall","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"adminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"authorizeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenHolder","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"defaultOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHubAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"grantMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"granularity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gsnExtraGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gsnFeeTarget","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gsnTrustedSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"hasMinterRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"address","name":"defaultAdmin","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"tokenHolder","type":"address"}],"name":"isOperatorFor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"operatorBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"},{"internalType":"string","name":"underlyingAssetRecipient","type":"string"}],"name":"operatorRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"operatorSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"context","type":"bytes"},{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint256","name":"actualCharge","type":"uint256"},{"internalType":"bytes32","name":"preRetVal","type":"bytes32"}],"name":"postRelayedCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"context","type":"bytes"}],"name":"preRelayedCall","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"underlyingAssetRecipient","type":"string"}],"name":"redeem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"userData","type":"bytes"},{"internalType":"string","name":"underlyingAssetRecipient","type":"string"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"relayHubVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"revokeMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"revokeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"adminOperator_","type":"address"}],"name":"setAdminOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gsnFeeTarget","type":"address"}],"name":"setFeeTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gsnExtraGas","type":"uint256"}],"name":"setGSNExtraGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gsnTrustedSigner","type":"address"}],"name":"setTrustedSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"userBalanceMultiplicationFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061574e806100206000396000f3fe608060405234801561001057600080fd5b506004361061035d5760003560e01c806391d14854116101d3578063d547741f11610104578063e06e0e22116100a2578063fad8b32a1161007c578063fad8b32a14611475578063fc673c4f1461149b578063fc876754146115d9578063fe9d9303146115e15761035d565b8063e06e0e2214611396578063e900a49114611447578063f2fde38b1461144f5761035d565b8063dc3ca1bf116100de578063dc3ca1bf146111de578063dcdc7dd014611204578063dd62ed3e14611342578063de7a8064146113705761035d565b8063d547741f1461117c578063d95b6371146111a8578063dab02527146111d65761035d565b8063a9059cbb11610171578063ca15c8731161014b578063ca15c8731461101f578063cbe1f06c1461103c578063ce67c00314611044578063d5391393146111745761035d565b8063a9059cbb14610ea2578063ad61ccd514610ece578063bcc33e9d14610ed65761035d565b80639a7ed350116101ad5780639a7ed35014610d965780639bd9bbc614610dc45780639bf8d82f14610e7d578063a217fddf14610e9a5761035d565b806391d1485414610d3c578063959b8c3f14610d6857806395d89b4114610d8e5761035d565b806336568abe116102ad57806370a082311161024b57806380274db71161022557806380274db714610a9157806383947ea014610b355780638da5cb5b14610d115780639010d07c14610d195761035d565b806370a0823114610a3f578063715018a614610a6557806374e861d614610a6d5761035d565b8063556f0dc711610287578063556f0dc7146108a257806356a1c701146108aa57806362ad1b83146108d057806369e2f0fb14610a195761035d565b806336568abe1461082a578063394f0231146108565780633dd1eb611461087c5761035d565b80631e9cee741161031a57806324b76fd5116102f457806324b76fd5146107635780632f2ff15d146107d8578063308eae8614610804578063313ce5671461080c5761035d565b80631e9cee74146105ed57806323b872dd14610710578063248a9ca3146107465761035d565b806306e485381461036257806306fdde03146103ba578063077f224a14610437578063095ea7b31461056d578063099db017146105ad57806318160ddd146105d3575b600080fd5b61036a61168c565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a657818101518382015260200161038e565b505050509050019250505060405180910390f35b6103c26116ef565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103fc5781810151838201526020016103e4565b50505050905090810190601f1680156104295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61056b6004803603606081101561044d57600080fd5b810190602081018135600160201b81111561046757600080fd5b82018360208201111561047957600080fd5b803590602001918460018302840111600160201b8311171561049a57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104ec57600080fd5b8201836020820111156104fe57600080fd5b803590602001918460018302840111600160201b8311171561051f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b0316915061177c9050565b005b6105996004803603604081101561058357600080fd5b506001600160a01b038135169060200135611855565b604080519115158252519081900360200190f35b610599600480360360208110156105c357600080fd5b50356001600160a01b0316611879565b6105db6118a6565b60408051918252519081900360200190f35b61056b600480360360a081101561060357600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561063257600080fd5b82018360208201111561064457600080fd5b803590602001918460018302840111600160201b8311171561066557600080fd5b919390929091602081019035600160201b81111561068257600080fd5b82018360208201111561069457600080fd5b803590602001918460018302840111600160201b831117156106b557600080fd5b919390929091602081019035600160201b8111156106d257600080fd5b8201836020820111156106e457600080fd5b803590602001918460018302840111600160201b8311171561070557600080fd5b5090925090506118ac565b6105996004803603606081101561072657600080fd5b506001600160a01b03813581169160208101359091169060400135611a15565b6105db6004803603602081101561075c57600080fd5b5035611b98565b6105996004803603604081101561077957600080fd5b81359190810190604081016020820135600160201b81111561079a57600080fd5b8201836020820111156107ac57600080fd5b803590602001918460018302840111600160201b831117156107cd57600080fd5b509092509050611bad565b61056b600480360360408110156107ee57600080fd5b50803590602001356001600160a01b0316611c09565b6105db611c75565b610814611c7b565b6040805160ff9092168252519081900360200190f35b61056b6004803603604081101561084057600080fd5b50803590602001356001600160a01b0316611c80565b61056b6004803603602081101561086c57600080fd5b50356001600160a01b0316611ce1565b61056b6004803603602081101561089257600080fd5b50356001600160a01b0316611da4565b6105db611dd1565b61056b600480360360208110156108c057600080fd5b50356001600160a01b0316611dd6565b61056b600480360360a08110156108e657600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561092057600080fd5b82018360208201111561093257600080fd5b803590602001918460018302840111600160201b8311171561095357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156109a557600080fd5b8201836020820111156109b757600080fd5b803590602001918460018302840111600160201b831117156109d857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611e9f945050505050565b61056b60048036036020811015610a2f57600080fd5b50356001600160a01b0316611f01565b6105db60048036036020811015610a5557600080fd5b50356001600160a01b0316611f2b565b61056b611f4d565b610a75611ff9565b604080516001600160a01b039092168252519081900360200190f35b6105db60048036036020811015610aa757600080fd5b810190602081018135600160201b811115610ac157600080fd5b820183602082011115610ad357600080fd5b803590602001918460018302840111600160201b83111715610af457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612008945050505050565b610c926004803603610120811015610b4c57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610b7f57600080fd5b820183602082011115610b9157600080fd5b803590602001918460018302840111600160201b83111715610bb257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929584359560208601359560408101359550606081013594509192509060a081019060800135600160201b811115610c1c57600080fd5b820183602082011115610c2e57600080fd5b803590602001918460018302840111600160201b83111715610c4f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925061206a915050565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cd5578181015183820152602001610cbd565b50505050905090810190601f168015610d025780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610a756122db565b610a7560048036036040811015610d2f57600080fd5b50803590602001356122ea565b61059960048036036040811015610d5257600080fd5b50803590602001356001600160a01b031661230f565b61056b60048036036020811015610d7e57600080fd5b50356001600160a01b031661232d565b6103c2612479565b61056b60048036036040811015610dac57600080fd5b506001600160a01b03813581169160200135166124da565b61056b60048036036060811015610dda57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610e0957600080fd5b820183602082011115610e1b57600080fd5b803590602001918460018302840111600160201b83111715610e3c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612667945050505050565b61056b60048036036020811015610e9357600080fd5b503561268c565b6105db6126f3565b61059960048036036040811015610eb857600080fd5b506001600160a01b0381351690602001356126f8565b6103c26127d1565b61056b600480360360a0811015610eec57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610f2657600080fd5b820183602082011115610f3857600080fd5b803590602001918460018302840111600160201b83111715610f5957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610fab57600080fd5b820183602082011115610fbd57600080fd5b803590602001918460018302840111600160201b83111715610fde57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506127f0945050505050565b6105db6004803603602081101561103557600080fd5b50356128b4565b6105db6128cb565b61056b6004803603606081101561105a57600080fd5b81359190810190604081016020820135600160201b81111561107b57600080fd5b82018360208201111561108d57600080fd5b803590602001918460018302840111600160201b831117156110ae57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561110057600080fd5b82018360208201111561111257600080fd5b803590602001918460018302840111600160201b8311171561113357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506128d1945050505050565b6105db612a11565b61056b6004803603604081101561119257600080fd5b50803590602001356001600160a01b0316612a34565b610599600480360360408110156111be57600080fd5b506001600160a01b0381358116916020013516612a8d565b610a75612b2e565b61056b600480360360208110156111f457600080fd5b50356001600160a01b0316612b3d565b6105996004803603608081101561121a57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561124957600080fd5b82018360208201111561125b57600080fd5b803590602001918460018302840111600160201b8311171561127c57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156112ce57600080fd5b8201836020820111156112e057600080fd5b803590602001918460018302840111600160201b8311171561130157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612c1c945050505050565b6105db6004803603604081101561135857600080fd5b506001600160a01b0381358116916020013516612ce8565b61056b6004803603602081101561138657600080fd5b50356001600160a01b0316612d13565b61056b600480360360808110156113ac57600080fd5b810190602081018135600160201b8111156113c657600080fd5b8201836020820111156113d857600080fd5b803590602001918460018302840111600160201b831117156113f957600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050505080351515915060208101359060400135612dd0565b610a75612e33565b61056b6004803603602081101561146557600080fd5b50356001600160a01b0316612e42565b61056b6004803603602081101561148b57600080fd5b50356001600160a01b0316612f45565b61056b600480360360808110156114b157600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156114e057600080fd5b8201836020820111156114f257600080fd5b803590602001918460018302840111600160201b8311171561151357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561156557600080fd5b82018360208201111561157757600080fd5b803590602001918460018302840111600160201b8311171561159857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613091945050505050565b610a756130e9565b61056b600480360360408110156115f757600080fd5b81359190810190604081016020820135600160201b81111561161857600080fd5b82018360208201111561162a57600080fd5b803590602001918460018302840111600160201b8311171561164b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506130f8945050505050565b606060cd8054806020026020016040519081016040528092919081815260200182805480156116e457602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116116c6575b505050505090505b90565b60cb8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156116e45780601f10611750576101008083540402835291602001916116e4565b820191906000526020600020905b81548152906001019060200180831161175e57509395945050505050565b600054610100900460ff1680611795575061179561311a565b806117a3575060005460ff16155b6117de5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015611809576000805460ff1961ff0019909116610100171660011790555b606061181361312b565b61181e8585836131dc565b61182883846124da565b61183183612d13565b61183c600084611c67565b50801561184f576000805461ff00191690555b50505050565b600080611860613293565b905061186d8185856132a2565b60019150505b92915050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020600090611873908361230f565b60ca5490565b6118bd6118b7613293565b89612a8d565b6118f85760405162461bcd60e51b815260040180806020018281038252602c815260200180615629602c913960400191505060405180910390fd5b61196d888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525061338e92505050565b876001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad688884848a8a6040518086815260200180602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f1916909201829003995090975050505050505050a25050505050505050565b60006001600160a01b038316611a5c5760405162461bcd60e51b81526004018080602001828103825260248152602001806155e16024913960400191505060405180910390fd5b6001600160a01b038416611aa15760405162461bcd60e51b815260040180806020018281038252602681526020018061567e6026913960400191505060405180910390fd5b6000611aab613293565b9050611ad98186868660405180602001604052806000815250604051806020016040528060008152506135dc565b611b05818686866040518060200160405280600081525060405180602001604052806000815250613824565b611b5f8582611b5a86604051806060016040528060298152602001615655602991396001600160a01b03808c16600090815260d160209081526040808320938b1683529290522054919063ffffffff613a6716565b6132a2565b611b8d8186868660405180602001604052806000815250604051806020016040528060008152506000613afe565b506001949350505050565b60009081526033602052604090206002015490565b6000611bff846040518060200160405280600081525085858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128d192505050565b5060019392505050565b600082815260336020526040902060020154611c2c90611c27613293565b61230f565b611c675760405162461bcd60e51b815260040180806020018281038252602f815260200180615304602f913960400191505060405180910390fd5b611c718282613d9e565b5050565b60d25481565b601290565b611c88613293565b6001600160a01b0316816001600160a01b031614611cd75760405162461bcd60e51b815260040180806020018281038252602f8152602001806156ea602f913960400191505060405180910390fd5b611c718282613e0d565b60ff546001600160a01b0316611cf5613293565b6001600160a01b031614611d3a5760405162461bcd60e51b815260040180806020018281038252603581526020018061553f6035913960400191505060405180910390fd5b60ff54604080516001600160a01b039283168152918316602083015280517fe8fdc5340d9288e129a7c6af86dc4002f708091280d69f89583f7e6349c0a8d69281900390910190a160ff80546001600160a01b0319166001600160a01b0392909216919091179055565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dce9082611c09565b50565b600190565b611dde613293565b6001600160a01b0316611def6122db565b6001600160a01b031614611e38576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6001600160a01b038116611e7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806153c76022913960400191505060405180910390fd5b60fc80546001600160a01b0319166001600160a01b0392909216919091179055565b611eb0611eaa613293565b86612a8d565b611eeb5760405162461bcd60e51b815260040180806020018281038252602c815260200180615629602c913960400191505060405180910390fd5b611efa85858585856001613e7c565b5050505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dce9082612a34565b6001600160a01b038116600090815260c9602052604081205461187390613f53565b611f55613293565b6001600160a01b0316611f666122db565b6001600160a01b031614611faf576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b6097546001600160a01b031690565b6000612012611ff9565b6001600160a01b0316336001600160a01b0316146120615760405162461bcd60e51b81526004018080602001828103825260248152602001806156056024913960400191505060405180910390fd5b61187382613f84565b600060606000606085806020019051604081101561208757600080fd5b815160208301805160405192949293830192919084600160201b8211156120ad57600080fd5b9083019060208201858111156120c257600080fd5b8251600160201b8111828201881017156120db57600080fd5b82525081516020918201929091019080838360005b838110156121085781810151838201526020016120f0565b50505050905090810190601f1680156121355780820380516001836020036101000a031916815260200191505b50604052505050915091506060828e8e8e8e8e8e8e612152611ff9565b30604051602001808b81526020018a6001600160a01b03166001600160a01b031660601b8152601401896001600160a01b03166001600160a01b031660601b815260140188805190602001908083835b602083106121c15780518252601f1990920191602091820191016121a2565b51815160209384036101000a6000190180199092169116179052920198895250878101969096525060408087019490945260608087019390935290821b6bffffffffffffffffffffffff199081166080870152911b1660948401528051808403608801815260a8909301905260fc548251918301919091209196506001600160a01b0316945061226593508692506122599150613f8a565b9063ffffffff613fdb16565b6001600160a01b031614156122c35760408051602081018590526001600160a01b038f1681830152606081018d905260808082018d90528251808303909101815260a09091019091526122b79061405b565b945094505050506122cd565b6122b76000614060565b995099975050505050505050565b6065546001600160a01b031690565b6000828152603360205260408120612308908363ffffffff61407816565b9392505050565b6000828152603360205260408120612308908363ffffffff61408416565b806001600160a01b031661233f613293565b6001600160a01b031614156123855760405162461bcd60e51b815260040180806020018281038252602481526020018061540b6024913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff16156123e85760d060006123b2613293565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff1916905561242f565b600160cf60006123f6613293565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b612437613293565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60cc8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156116e45780601f10611750576101008083540402835291602001916116e4565b600054610100900460ff16806124f357506124f361311a565b80612501575060005460ff16155b61253c5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015612567576000805460ff1961ff0019909116610100171660011790555b61256f614099565b612577614136565b6001600160a01b0383166125bc5760405162461bcd60e51b81526004018080602001828103825260228152602001806153c76022913960400191505060405180910390fd5b60fc80546001600160a01b0319166001600160a01b0385811691909117909155821661262f576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fd80546001600160a01b0319166001600160a01b038416179055619c4060fe558015612662576000805461ff00191690555b505050565b612662612672613293565b848484604051806020016040528060008152506001613e7c565b612694613293565b6001600160a01b03166126a56122db565b6001600160a01b0316146126ee576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b60fe55565b600081565b60006001600160a01b03831661273f5760405162461bcd60e51b81526004018080602001828103825260248152602001806155e16024913960400191505060405180910390fd5b6000612749613293565b90506127778182868660405180602001604052806000815250604051806020016040528060008152506135dc565b6127a3818286866040518060200160405280600081525060405180602001604052806000815250613824565b61186d8182868660405180602001604052806000815250604051806020016040528060008152506000613afe565b6040805180820190915260058152640312e302e360dc1b602082015290565b60ff546001600160a01b0316612804613293565b6001600160a01b03161461285f576040805162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74207468652061646d696e206f70657261746f72604482015290519081900360640190fd5b61286e85858585856000613e7c565b60ff54604080516001600160a01b039092168252517fb22a57ba0314fafe219dc14abcf1f22e86e6e82d599c0c31177a2d7c2e1b17e19181900360200190a15050505050565b6000818152603360205260408120611873906141d3565b60fe5481565b6128f36128dc613293565b84846040518060200160405280600081525061338e565b6128fb613293565b6001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad68848385604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561296f578181015183820152602001612957565b50505050905090810190601f16801561299c5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156129cf5781810151838201526020016129b7565b50505050905090810190601f1680156129fc5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b01902081565b600082815260336020526040902060020154612a5290611c27613293565b611cd75760405162461bcd60e51b81526004018080602001828103825260308152602001806154516030913960400191505060405180910390fd5b6000816001600160a01b0316836001600160a01b03161480612af857506001600160a01b038316600090815260ce602052604090205460ff168015612af857506001600160a01b03808316600090815260d0602090815260408083209387168352929052205460ff16155b806123085750506001600160a01b03908116600090815260cf602090815260408083209490931682529290925290205460ff1690565b60fd546001600160a01b031681565b612b45613293565b6001600160a01b0316612b566122db565b6001600160a01b031614612b9f576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6001600160a01b038116612bfa576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038516301415612c665760405162461bcd60e51b815260040180806020018281038252602f8152602001806152d5602f913960400191505060405180910390fd5b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020612c9290611c27613293565b612cdc576040805162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b4b73a32b960511b604482015290519081900360640190fd5b611b8d858585856141de565b6001600160a01b03918216600090815260d16020908152604080832093909416825291909152205490565b600054610100900460ff1680612d2c5750612d2c61311a565b80612d3a575060005460ff16155b612d755760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015612da0576000805460ff1961ff0019909116610100171660011790555b60ff80546001600160a01b0319166001600160a01b0384161790558015611c71576000805461ff00191690555050565b612dd8611ff9565b6001600160a01b0316336001600160a01b031614612e275760405162461bcd60e51b81526004018080602001828103825260248152602001806156056024913960400191505060405180910390fd5b61184f84848484614674565b60ff546001600160a01b031681565b612e4a613293565b6001600160a01b0316612e5b6122db565b6001600160a01b031614612ea4576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6001600160a01b038116612ee95760405162461bcd60e51b81526004018080602001828103825260268152602001806153a16026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b612f4d613293565b6001600160a01b0316816001600160a01b03161415612f9d5760405162461bcd60e51b81526004018080602001828103825260218152602001806154816021913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff161561300957600160d06000612fcc613293565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055613047565b60cf6000613015613293565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b61304f613293565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b6130a261309c613293565b85612a8d565b6130dd5760405162461bcd60e51b815260040180806020018281038252602c815260200180615629602c913960400191505060405180910390fd5b61184f8484848461338e565b60fc546001600160a01b031681565b611c71613103613293565b83836040518060200160405280600081525061338e565b600061312530614759565b15905090565b600054610100900460ff1680613144575061314461311a565b80613152575060005460ff16155b61318d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff161580156131b8576000805460ff1961ff0019909116610100171660011790555b6131c061475f565b6131c861475f565b8015611dce576000805461ff001916905550565b600054610100900460ff16806131f557506131f561311a565b80613203575060005460ff16155b61323e5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015613269576000805460ff1961ff0019909116610100171660011790555b61327161475f565b61327c8484846147ff565b801561184f576000805461ff001916905550505050565b600061329d614a73565b905090565b6001600160a01b0383166132e75760405162461bcd60e51b81526004018080602001828103825260258152602001806153336025913960400191505060405180910390fd5b6001600160a01b03821661332c5760405162461bcd60e51b81526004018080602001828103825260238152602001806156c76023913960400191505060405180910390fd5b6001600160a01b03808416600081815260d16020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0384166133d35760405162461bcd60e51b81526004018080602001828103825260228152602001806153e96022913960400191505060405180910390fd5b60006133dd613293565b90506133ee818660008787876135dc565b6133fb818660008761184f565b61344661340785614aab565b6040518060600160405280602381526020016156a4602391396001600160a01b038816600090815260c96020526040902054919063ffffffff613a6716565b6001600160a01b038616600090815260c9602052604090205560ca54613472908563ffffffff614acf16565b60ca81905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156134f75781810151838201526020016134df565b50505050905090810190601f1680156135245780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561355757818101518382015260200161353f565b50505050905090810190601f1680156135845780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516000916001600160a01b038816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b6040805163555ddc6560e11b81526001600160a01b03871660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89560248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b15801561366057600080fd5b505afa158015613674573d6000803e3d6000fd5b505050506040513d602081101561368a57600080fd5b505190506001600160a01b0381161561381b57806001600160a01b03166375ab97828888888888886040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015613750578181015183820152602001613738565b50505050905090810190601f16801561377d5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156137b0578181015183820152602001613798565b50505050905090810190601f1680156137dd5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561380257600080fd5b505af1158015613816573d6000803e3d6000fd5b505050505b50505050505050565b6138308686868661184f565b61387b61383c84614aab565b60405180606001604052806027815260200161537a602791396001600160a01b038816600090815260c96020526040902054919063ffffffff613a6716565b6001600160a01b038616600090815260c960205260409020556138c56138a084614aab565b6001600160a01b038616600090815260c960205260409020549063ffffffff614b2c16565b60c96000866001600160a01b03166001600160a01b0316815260200190815260200160002081905550836001600160a01b0316856001600160a01b0316876001600160a01b03167f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561397757818101518382015260200161395f565b50505050905090810190601f1680156139a45780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156139d75781810151838201526020016139bf565b50505050905090810190601f168015613a045780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3505050505050565b60008184841115613af65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613abb578181015183820152602001613aa3565b50505050905090810190601f168015613ae85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6040805163555ddc6560e11b81526001600160a01b03871660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b158015613b8257600080fd5b505afa158015613b96573d6000803e3d6000fd5b505050506040513d6020811015613bac57600080fd5b505190506001600160a01b03811615613d4057806001600160a01b03166223de298989898989896040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015613c71578181015183820152602001613c59565b50505050905090810190601f168015613c9e5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015613cd1578181015183820152602001613cb9565b50505050905090810190601f168015613cfe5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015613d2357600080fd5b505af1158015613d37573d6000803e3d6000fd5b50505050613d94565b8115613d9457613d58866001600160a01b0316614759565b15613d945760405162461bcd60e51b815260040180806020018281038252604d815260200180615594604d913960600191505060405180910390fd5b5050505050505050565b6000828152603360205260409020613dbc908263ffffffff614b8616565b15611c7157613dc9613293565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020613e2b908263ffffffff614b9b16565b15611c7157613e38613293565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038616613ec15760405162461bcd60e51b81526004018080602001828103825260228152602001806153586022913960400191505060405180910390fd5b6001600160a01b038516613f1c576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6000613f26613293565b9050613f368188888888886135dc565b613f44818888888888613824565b61381b81888888888888613afe565b600061187369d3c21bcecceda1000000613f7860d25485614bb090919063ffffffff16565b9063ffffffff614c0916565b50600090565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114614033576040805162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015290519081900360640190fd5b60208201516040830151606084015160001a61405186828585614c70565b9695505050505050565b600091565b604080516020810190915260008152600b9190910191565b60006123088383614dea565b6000612308836001600160a01b038416614e4e565b600054610100900460ff16806140b257506140b261311a565b806140c0575060005460ff16155b6140fb5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015614126576000805460ff1961ff0019909116610100171660011790555b61412e61475f565b6131c8614e66565b600054610100900460ff168061414f575061414f61311a565b8061415d575060005460ff16155b6141985760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff161580156141c3576000805460ff1961ff0019909116610100171660011790555b6141cb61475f565b6131c8614f2d565b600061187382615026565b6001600160a01b038416614239576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6000614243613293565b9050614252816000878761184f565b60e0835110156142935760405162461bcd60e51b815260040180806020018281038252602c8152602001806154d0602c913960400191505060405180910390fd5b60608380602001905160808110156142aa57600080fd5b815160208301805160405192949293830192919084600160201b8211156142d057600080fd5b9083019060208201858111156142e557600080fd5b8251600160201b8111828201881017156142fe57600080fd5b82525081516020918201929091019080838360005b8381101561432b578181015183820152602001614313565b50505050905090810190601f1680156143585780820380516001836020036101000a031916815260200191505b5060405250508151919350600092508291602085019150606081101561437d57600080fd5b81516020830151604080850180519151939592948301929184600160201b8211156143a757600080fd5b9083019060208201858111156143bc57600080fd5b8251600160201b8111828201881017156143d557600080fd5b82525081516020918201929091019080838360005b838110156144025781810151838201526020016143ea565b50505050905090810190601f16801561442f5780820380516001836020036101000a031916815260200191505b5060405250505050915091506144436118a6565b61445a5769d3c21bcecceda100000060d2556144ba565b60006144746144676118a6565b849063ffffffff614acf16565b9050614486828263ffffffff614acf16565b91506144b56144936118a6565b613f786144a6858c63ffffffff614acf16565b60d2549063ffffffff614bb016565b60d255505b60ca8190556144e06144db886144cf8b611f2b565b9063ffffffff614b2c16565b614aab565b6001600160a01b038916600090815260c9602052604081209190915561450d9085908a8a8a8a6001613afe565b876001600160a01b0316846001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d898989604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561458c578181015183820152602001614574565b50505050905090810190601f1680156145b95780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156145ec5781810151838201526020016145d4565b50505050905090810190601f1680156146195780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805188815290516001600160a01b038a16916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050505050565b60008060008087806020019051608081101561468f57600080fd5b5080516020820151604083015160609093015160fe549297509095509193509091506000906146d3906146cc90620186a09063ffffffff614acf16565b838561502a565b90506000614703670de0b6b3a7640000613f78886146f78c8763ffffffff614acf16565b9063ffffffff614bb016565b9050801561474d5761474d8560fd60009054906101000a90046001600160a01b03168360405180602001604052806000815250604051806020016040528060008152506000613e7c565b50505050505050505050565b3b151590565b600054610100900460ff1680614778575061477861311a565b80614786575060005460ff16155b6147c15760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff161580156131c8576000805460ff1961ff0019909116610100171660011790558015611dce576000805461ff001916905550565b600054610100900460ff1680614818575061481861311a565b80614826575060005460ff16155b6148615760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff1615801561488c576000805460ff1961ff0019909116610100171660011790555b835161489f9060cb906020870190615195565b5082516148b39060cc906020860190615195565b5081516148c79060cd906020850190615213565b5060005b60cd5481101561492457600160ce600060cd84815481106148e857fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016148cb565b50604080516a22a9219b9b9baa37b5b2b760a91b8152815190819003600b0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad24916329965a1d91606480830192600092919082900301818387803b1580156149a257600080fd5b505af11580156149b6573d6000803e3d6000fd5b5050604080516922a92199182a37b5b2b760b11b8152815190819003600a0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad2493506329965a1d9250606480830192600092919082900301818387803b158015614a3657600080fd5b505af1158015614a4a573d6000803e3d6000fd5b505069d3c21bcecceda100000060d2555050801561184f576000805461ff001916905550505050565b6000614a7d611ff9565b6001600160a01b0316336001600160a01b031614614a9c5750336116ec565b614aa4615038565b90506116ec565b60d25460009061187390613f788469d3c21bcecceda100000063ffffffff614bb016565b600082821115614b26576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015612308576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000612308836001600160a01b038416615085565b6000612308836001600160a01b0384166150cf565b600082614bbf57506000611873565b82820282848281614bcc57fe5b04146123085760405162461bcd60e51b815260040180806020018281038252602181526020018061551e6021913960400191505060405180910390fd5b6000808211614c5f576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381614c6857fe5b049392505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115614cd15760405162461bcd60e51b815260040180806020018281038252602281526020018061542f6022913960400191505060405180910390fd5b8360ff16601b1480614ce657508360ff16601c145b614d215760405162461bcd60e51b81526004018080602001828103825260228152602001806154fc6022913960400191505060405180910390fd5b604080516000808252602080830180855289905260ff88168385015260608301879052608083018690529251909260019260a080820193601f1981019281900390910190855afa158015614d79573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116614de1576040805162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b81546000908210614e2c5760405162461bcd60e51b81526004018080602001828103825260228152602001806152b36022913960400191505060405180910390fd5b826000018281548110614e3b57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600054610100900460ff1680614e7f5750614e7f61311a565b80614e8d575060005460ff16155b614ec85760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015614ef3576000805460ff1961ff0019909116610100171660011790555b609780546001600160a01b03191673d216153c06e857cd7f72665e0af1d7d82172f4941790558015611dce576000805461ff001916905550565b600054610100900460ff1680614f465750614f4661311a565b80614f54575060005460ff16155b614f8f5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015614fba576000805460ff1961ff0019909116610100171660011790555b6000614fc4613293565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015611dce576000805461ff001916905550565b5490565b606490810191909202020490565b600060606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031692915050565b60006150918383614e4e565b6150c757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611873565b506000611873565b6000818152600183016020526040812054801561518b578354600019808301919081019060009087908390811061510257fe5b906000526020600020015490508087600001848154811061511f57fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061514f57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611873565b6000915050611873565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106151d657805160ff1916838001178555615203565b82800160010185558215615203579182015b828111156152035782518255916020019190600101906151e8565b5061520f929150615274565b5090565b828054828255906000526020600020908101928215615268579160200282015b8281111561526857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615233565b5061520f92915061528e565b6116ec91905b8082111561520f576000815560010161527a565b6116ec91905b8082111561520f5780546001600160a01b031916815560010161529456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473526563697069656e742063616e6e6f742062652074686520746f6b656e20636f6e7472616374206164647265737321416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433737373a20617070726f76652066726f6d20746865207a65726f20616464726573734552433737373a2073656e642066726f6d20746865207a65726f20616464726573734552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737374727573746564207369676e657220697320746865207a65726f20616464726573734552433737373a206275726e2066726f6d20746865207a65726f20616464726573734552433737373a20617574686f72697a696e672073656c66206173206f70657261746f7245434453413a20696e76616c6964207369676e6174757265202773272076616c7565416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433737373a207265766f6b696e672073656c66206173206f70657261746f72496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65644e6f7420656e6f756768206d6574616461746120746f206d696e7420536166654d6f6f6e20746f6b656e732145434453413a20696e76616c6964207369676e6174757265202776272076616c7565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f6e6c79207468652061637475616c2061646d696e206f70657261746f722063616e206368616e67652074686520616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433737373a20746f6b656e20726563697069656e7420636f6e747261637420686173206e6f20696d706c656d656e74657220666f7220455243373737546f6b656e73526563697069656e744552433737373a207472616e7366657220746f20746865207a65726f206164647265737347534e526563697069656e743a2063616c6c6572206973206e6f742052656c61794875624552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f7220666f7220686f6c6465724552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a207472616e736665722066726f6d20746865207a65726f20616464726573734552433737373a206275726e20616d6f756e7420657863656564732062616c616e63654552433737373a20617070726f766520746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212206a7bb94537618b3f802a31b2ad816c9da8ee3d258f07b6c1d12ecbba8aed32b364736f6c63430006020033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061035d5760003560e01c806391d14854116101d3578063d547741f11610104578063e06e0e22116100a2578063fad8b32a1161007c578063fad8b32a14611475578063fc673c4f1461149b578063fc876754146115d9578063fe9d9303146115e15761035d565b8063e06e0e2214611396578063e900a49114611447578063f2fde38b1461144f5761035d565b8063dc3ca1bf116100de578063dc3ca1bf146111de578063dcdc7dd014611204578063dd62ed3e14611342578063de7a8064146113705761035d565b8063d547741f1461117c578063d95b6371146111a8578063dab02527146111d65761035d565b8063a9059cbb11610171578063ca15c8731161014b578063ca15c8731461101f578063cbe1f06c1461103c578063ce67c00314611044578063d5391393146111745761035d565b8063a9059cbb14610ea2578063ad61ccd514610ece578063bcc33e9d14610ed65761035d565b80639a7ed350116101ad5780639a7ed35014610d965780639bd9bbc614610dc45780639bf8d82f14610e7d578063a217fddf14610e9a5761035d565b806391d1485414610d3c578063959b8c3f14610d6857806395d89b4114610d8e5761035d565b806336568abe116102ad57806370a082311161024b57806380274db71161022557806380274db714610a9157806383947ea014610b355780638da5cb5b14610d115780639010d07c14610d195761035d565b806370a0823114610a3f578063715018a614610a6557806374e861d614610a6d5761035d565b8063556f0dc711610287578063556f0dc7146108a257806356a1c701146108aa57806362ad1b83146108d057806369e2f0fb14610a195761035d565b806336568abe1461082a578063394f0231146108565780633dd1eb611461087c5761035d565b80631e9cee741161031a57806324b76fd5116102f457806324b76fd5146107635780632f2ff15d146107d8578063308eae8614610804578063313ce5671461080c5761035d565b80631e9cee74146105ed57806323b872dd14610710578063248a9ca3146107465761035d565b806306e485381461036257806306fdde03146103ba578063077f224a14610437578063095ea7b31461056d578063099db017146105ad57806318160ddd146105d3575b600080fd5b61036a61168c565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a657818101518382015260200161038e565b505050509050019250505060405180910390f35b6103c26116ef565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103fc5781810151838201526020016103e4565b50505050905090810190601f1680156104295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61056b6004803603606081101561044d57600080fd5b810190602081018135600160201b81111561046757600080fd5b82018360208201111561047957600080fd5b803590602001918460018302840111600160201b8311171561049a57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104ec57600080fd5b8201836020820111156104fe57600080fd5b803590602001918460018302840111600160201b8311171561051f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b0316915061177c9050565b005b6105996004803603604081101561058357600080fd5b506001600160a01b038135169060200135611855565b604080519115158252519081900360200190f35b610599600480360360208110156105c357600080fd5b50356001600160a01b0316611879565b6105db6118a6565b60408051918252519081900360200190f35b61056b600480360360a081101561060357600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561063257600080fd5b82018360208201111561064457600080fd5b803590602001918460018302840111600160201b8311171561066557600080fd5b919390929091602081019035600160201b81111561068257600080fd5b82018360208201111561069457600080fd5b803590602001918460018302840111600160201b831117156106b557600080fd5b919390929091602081019035600160201b8111156106d257600080fd5b8201836020820111156106e457600080fd5b803590602001918460018302840111600160201b8311171561070557600080fd5b5090925090506118ac565b6105996004803603606081101561072657600080fd5b506001600160a01b03813581169160208101359091169060400135611a15565b6105db6004803603602081101561075c57600080fd5b5035611b98565b6105996004803603604081101561077957600080fd5b81359190810190604081016020820135600160201b81111561079a57600080fd5b8201836020820111156107ac57600080fd5b803590602001918460018302840111600160201b831117156107cd57600080fd5b509092509050611bad565b61056b600480360360408110156107ee57600080fd5b50803590602001356001600160a01b0316611c09565b6105db611c75565b610814611c7b565b6040805160ff9092168252519081900360200190f35b61056b6004803603604081101561084057600080fd5b50803590602001356001600160a01b0316611c80565b61056b6004803603602081101561086c57600080fd5b50356001600160a01b0316611ce1565b61056b6004803603602081101561089257600080fd5b50356001600160a01b0316611da4565b6105db611dd1565b61056b600480360360208110156108c057600080fd5b50356001600160a01b0316611dd6565b61056b600480360360a08110156108e657600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561092057600080fd5b82018360208201111561093257600080fd5b803590602001918460018302840111600160201b8311171561095357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156109a557600080fd5b8201836020820111156109b757600080fd5b803590602001918460018302840111600160201b831117156109d857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611e9f945050505050565b61056b60048036036020811015610a2f57600080fd5b50356001600160a01b0316611f01565b6105db60048036036020811015610a5557600080fd5b50356001600160a01b0316611f2b565b61056b611f4d565b610a75611ff9565b604080516001600160a01b039092168252519081900360200190f35b6105db60048036036020811015610aa757600080fd5b810190602081018135600160201b811115610ac157600080fd5b820183602082011115610ad357600080fd5b803590602001918460018302840111600160201b83111715610af457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612008945050505050565b610c926004803603610120811015610b4c57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610b7f57600080fd5b820183602082011115610b9157600080fd5b803590602001918460018302840111600160201b83111715610bb257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929584359560208601359560408101359550606081013594509192509060a081019060800135600160201b811115610c1c57600080fd5b820183602082011115610c2e57600080fd5b803590602001918460018302840111600160201b83111715610c4f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925061206a915050565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cd5578181015183820152602001610cbd565b50505050905090810190601f168015610d025780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610a756122db565b610a7560048036036040811015610d2f57600080fd5b50803590602001356122ea565b61059960048036036040811015610d5257600080fd5b50803590602001356001600160a01b031661230f565b61056b60048036036020811015610d7e57600080fd5b50356001600160a01b031661232d565b6103c2612479565b61056b60048036036040811015610dac57600080fd5b506001600160a01b03813581169160200135166124da565b61056b60048036036060811015610dda57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610e0957600080fd5b820183602082011115610e1b57600080fd5b803590602001918460018302840111600160201b83111715610e3c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612667945050505050565b61056b60048036036020811015610e9357600080fd5b503561268c565b6105db6126f3565b61059960048036036040811015610eb857600080fd5b506001600160a01b0381351690602001356126f8565b6103c26127d1565b61056b600480360360a0811015610eec57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610f2657600080fd5b820183602082011115610f3857600080fd5b803590602001918460018302840111600160201b83111715610f5957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610fab57600080fd5b820183602082011115610fbd57600080fd5b803590602001918460018302840111600160201b83111715610fde57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506127f0945050505050565b6105db6004803603602081101561103557600080fd5b50356128b4565b6105db6128cb565b61056b6004803603606081101561105a57600080fd5b81359190810190604081016020820135600160201b81111561107b57600080fd5b82018360208201111561108d57600080fd5b803590602001918460018302840111600160201b831117156110ae57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561110057600080fd5b82018360208201111561111257600080fd5b803590602001918460018302840111600160201b8311171561113357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506128d1945050505050565b6105db612a11565b61056b6004803603604081101561119257600080fd5b50803590602001356001600160a01b0316612a34565b610599600480360360408110156111be57600080fd5b506001600160a01b0381358116916020013516612a8d565b610a75612b2e565b61056b600480360360208110156111f457600080fd5b50356001600160a01b0316612b3d565b6105996004803603608081101561121a57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561124957600080fd5b82018360208201111561125b57600080fd5b803590602001918460018302840111600160201b8311171561127c57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156112ce57600080fd5b8201836020820111156112e057600080fd5b803590602001918460018302840111600160201b8311171561130157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612c1c945050505050565b6105db6004803603604081101561135857600080fd5b506001600160a01b0381358116916020013516612ce8565b61056b6004803603602081101561138657600080fd5b50356001600160a01b0316612d13565b61056b600480360360808110156113ac57600080fd5b810190602081018135600160201b8111156113c657600080fd5b8201836020820111156113d857600080fd5b803590602001918460018302840111600160201b831117156113f957600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050505080351515915060208101359060400135612dd0565b610a75612e33565b61056b6004803603602081101561146557600080fd5b50356001600160a01b0316612e42565b61056b6004803603602081101561148b57600080fd5b50356001600160a01b0316612f45565b61056b600480360360808110156114b157600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b8111156114e057600080fd5b8201836020820111156114f257600080fd5b803590602001918460018302840111600160201b8311171561151357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561156557600080fd5b82018360208201111561157757600080fd5b803590602001918460018302840111600160201b8311171561159857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613091945050505050565b610a756130e9565b61056b600480360360408110156115f757600080fd5b81359190810190604081016020820135600160201b81111561161857600080fd5b82018360208201111561162a57600080fd5b803590602001918460018302840111600160201b8311171561164b57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506130f8945050505050565b606060cd8054806020026020016040519081016040528092919081815260200182805480156116e457602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116116c6575b505050505090505b90565b60cb8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156116e45780601f10611750576101008083540402835291602001916116e4565b820191906000526020600020905b81548152906001019060200180831161175e57509395945050505050565b600054610100900460ff1680611795575061179561311a565b806117a3575060005460ff16155b6117de5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015611809576000805460ff1961ff0019909116610100171660011790555b606061181361312b565b61181e8585836131dc565b61182883846124da565b61183183612d13565b61183c600084611c67565b50801561184f576000805461ff00191690555b50505050565b600080611860613293565b905061186d8185856132a2565b60019150505b92915050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020600090611873908361230f565b60ca5490565b6118bd6118b7613293565b89612a8d565b6118f85760405162461bcd60e51b815260040180806020018281038252602c815260200180615629602c913960400191505060405180910390fd5b61196d888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525061338e92505050565b876001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad688884848a8a6040518086815260200180602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f1916909201829003995090975050505050505050a25050505050505050565b60006001600160a01b038316611a5c5760405162461bcd60e51b81526004018080602001828103825260248152602001806155e16024913960400191505060405180910390fd5b6001600160a01b038416611aa15760405162461bcd60e51b815260040180806020018281038252602681526020018061567e6026913960400191505060405180910390fd5b6000611aab613293565b9050611ad98186868660405180602001604052806000815250604051806020016040528060008152506135dc565b611b05818686866040518060200160405280600081525060405180602001604052806000815250613824565b611b5f8582611b5a86604051806060016040528060298152602001615655602991396001600160a01b03808c16600090815260d160209081526040808320938b1683529290522054919063ffffffff613a6716565b6132a2565b611b8d8186868660405180602001604052806000815250604051806020016040528060008152506000613afe565b506001949350505050565b60009081526033602052604090206002015490565b6000611bff846040518060200160405280600081525085858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128d192505050565b5060019392505050565b600082815260336020526040902060020154611c2c90611c27613293565b61230f565b611c675760405162461bcd60e51b815260040180806020018281038252602f815260200180615304602f913960400191505060405180910390fd5b611c718282613d9e565b5050565b60d25481565b601290565b611c88613293565b6001600160a01b0316816001600160a01b031614611cd75760405162461bcd60e51b815260040180806020018281038252602f8152602001806156ea602f913960400191505060405180910390fd5b611c718282613e0d565b60ff546001600160a01b0316611cf5613293565b6001600160a01b031614611d3a5760405162461bcd60e51b815260040180806020018281038252603581526020018061553f6035913960400191505060405180910390fd5b60ff54604080516001600160a01b039283168152918316602083015280517fe8fdc5340d9288e129a7c6af86dc4002f708091280d69f89583f7e6349c0a8d69281900390910190a160ff80546001600160a01b0319166001600160a01b0392909216919091179055565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dce9082611c09565b50565b600190565b611dde613293565b6001600160a01b0316611def6122db565b6001600160a01b031614611e38576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6001600160a01b038116611e7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806153c76022913960400191505060405180910390fd5b60fc80546001600160a01b0319166001600160a01b0392909216919091179055565b611eb0611eaa613293565b86612a8d565b611eeb5760405162461bcd60e51b815260040180806020018281038252602c815260200180615629602c913960400191505060405180910390fd5b611efa85858585856001613e7c565b5050505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dce9082612a34565b6001600160a01b038116600090815260c9602052604081205461187390613f53565b611f55613293565b6001600160a01b0316611f666122db565b6001600160a01b031614611faf576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b6097546001600160a01b031690565b6000612012611ff9565b6001600160a01b0316336001600160a01b0316146120615760405162461bcd60e51b81526004018080602001828103825260248152602001806156056024913960400191505060405180910390fd5b61187382613f84565b600060606000606085806020019051604081101561208757600080fd5b815160208301805160405192949293830192919084600160201b8211156120ad57600080fd5b9083019060208201858111156120c257600080fd5b8251600160201b8111828201881017156120db57600080fd5b82525081516020918201929091019080838360005b838110156121085781810151838201526020016120f0565b50505050905090810190601f1680156121355780820380516001836020036101000a031916815260200191505b50604052505050915091506060828e8e8e8e8e8e8e612152611ff9565b30604051602001808b81526020018a6001600160a01b03166001600160a01b031660601b8152601401896001600160a01b03166001600160a01b031660601b815260140188805190602001908083835b602083106121c15780518252601f1990920191602091820191016121a2565b51815160209384036101000a6000190180199092169116179052920198895250878101969096525060408087019490945260608087019390935290821b6bffffffffffffffffffffffff199081166080870152911b1660948401528051808403608801815260a8909301905260fc548251918301919091209196506001600160a01b0316945061226593508692506122599150613f8a565b9063ffffffff613fdb16565b6001600160a01b031614156122c35760408051602081018590526001600160a01b038f1681830152606081018d905260808082018d90528251808303909101815260a09091019091526122b79061405b565b945094505050506122cd565b6122b76000614060565b995099975050505050505050565b6065546001600160a01b031690565b6000828152603360205260408120612308908363ffffffff61407816565b9392505050565b6000828152603360205260408120612308908363ffffffff61408416565b806001600160a01b031661233f613293565b6001600160a01b031614156123855760405162461bcd60e51b815260040180806020018281038252602481526020018061540b6024913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff16156123e85760d060006123b2613293565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff1916905561242f565b600160cf60006123f6613293565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b612437613293565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60cc8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156116e45780601f10611750576101008083540402835291602001916116e4565b600054610100900460ff16806124f357506124f361311a565b80612501575060005460ff16155b61253c5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015612567576000805460ff1961ff0019909116610100171660011790555b61256f614099565b612577614136565b6001600160a01b0383166125bc5760405162461bcd60e51b81526004018080602001828103825260228152602001806153c76022913960400191505060405180910390fd5b60fc80546001600160a01b0319166001600160a01b0385811691909117909155821661262f576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fd80546001600160a01b0319166001600160a01b038416179055619c4060fe558015612662576000805461ff00191690555b505050565b612662612672613293565b848484604051806020016040528060008152506001613e7c565b612694613293565b6001600160a01b03166126a56122db565b6001600160a01b0316146126ee576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b60fe55565b600081565b60006001600160a01b03831661273f5760405162461bcd60e51b81526004018080602001828103825260248152602001806155e16024913960400191505060405180910390fd5b6000612749613293565b90506127778182868660405180602001604052806000815250604051806020016040528060008152506135dc565b6127a3818286866040518060200160405280600081525060405180602001604052806000815250613824565b61186d8182868660405180602001604052806000815250604051806020016040528060008152506000613afe565b6040805180820190915260058152640312e302e360dc1b602082015290565b60ff546001600160a01b0316612804613293565b6001600160a01b03161461285f576040805162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74207468652061646d696e206f70657261746f72604482015290519081900360640190fd5b61286e85858585856000613e7c565b60ff54604080516001600160a01b039092168252517fb22a57ba0314fafe219dc14abcf1f22e86e6e82d599c0c31177a2d7c2e1b17e19181900360200190a15050505050565b6000818152603360205260408120611873906141d3565b60fe5481565b6128f36128dc613293565b84846040518060200160405280600081525061338e565b6128fb613293565b6001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad68848385604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561296f578181015183820152602001612957565b50505050905090810190601f16801561299c5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156129cf5781810151838201526020016129b7565b50505050905090810190601f1680156129fc5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b01902081565b600082815260336020526040902060020154612a5290611c27613293565b611cd75760405162461bcd60e51b81526004018080602001828103825260308152602001806154516030913960400191505060405180910390fd5b6000816001600160a01b0316836001600160a01b03161480612af857506001600160a01b038316600090815260ce602052604090205460ff168015612af857506001600160a01b03808316600090815260d0602090815260408083209387168352929052205460ff16155b806123085750506001600160a01b03908116600090815260cf602090815260408083209490931682529290925290205460ff1690565b60fd546001600160a01b031681565b612b45613293565b6001600160a01b0316612b566122db565b6001600160a01b031614612b9f576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6001600160a01b038116612bfa576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fd80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038516301415612c665760405162461bcd60e51b815260040180806020018281038252602f8152602001806152d5602f913960400191505060405180910390fd5b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020612c9290611c27613293565b612cdc576040805162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b4b73a32b960511b604482015290519081900360640190fd5b611b8d858585856141de565b6001600160a01b03918216600090815260d16020908152604080832093909416825291909152205490565b600054610100900460ff1680612d2c5750612d2c61311a565b80612d3a575060005460ff16155b612d755760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015612da0576000805460ff1961ff0019909116610100171660011790555b60ff80546001600160a01b0319166001600160a01b0384161790558015611c71576000805461ff00191690555050565b612dd8611ff9565b6001600160a01b0316336001600160a01b031614612e275760405162461bcd60e51b81526004018080602001828103825260248152602001806156056024913960400191505060405180910390fd5b61184f84848484614674565b60ff546001600160a01b031681565b612e4a613293565b6001600160a01b0316612e5b6122db565b6001600160a01b031614612ea4576040805162461bcd60e51b81526020600482018190526024820152600080516020615574833981519152604482015290519081900360640190fd5b6001600160a01b038116612ee95760405162461bcd60e51b81526004018080602001828103825260268152602001806153a16026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b612f4d613293565b6001600160a01b0316816001600160a01b03161415612f9d5760405162461bcd60e51b81526004018080602001828103825260218152602001806154816021913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff161561300957600160d06000612fcc613293565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055613047565b60cf6000613015613293565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b61304f613293565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b6130a261309c613293565b85612a8d565b6130dd5760405162461bcd60e51b815260040180806020018281038252602c815260200180615629602c913960400191505060405180910390fd5b61184f8484848461338e565b60fc546001600160a01b031681565b611c71613103613293565b83836040518060200160405280600081525061338e565b600061312530614759565b15905090565b600054610100900460ff1680613144575061314461311a565b80613152575060005460ff16155b61318d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff161580156131b8576000805460ff1961ff0019909116610100171660011790555b6131c061475f565b6131c861475f565b8015611dce576000805461ff001916905550565b600054610100900460ff16806131f557506131f561311a565b80613203575060005460ff16155b61323e5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015613269576000805460ff1961ff0019909116610100171660011790555b61327161475f565b61327c8484846147ff565b801561184f576000805461ff001916905550505050565b600061329d614a73565b905090565b6001600160a01b0383166132e75760405162461bcd60e51b81526004018080602001828103825260258152602001806153336025913960400191505060405180910390fd5b6001600160a01b03821661332c5760405162461bcd60e51b81526004018080602001828103825260238152602001806156c76023913960400191505060405180910390fd5b6001600160a01b03808416600081815260d16020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0384166133d35760405162461bcd60e51b81526004018080602001828103825260228152602001806153e96022913960400191505060405180910390fd5b60006133dd613293565b90506133ee818660008787876135dc565b6133fb818660008761184f565b61344661340785614aab565b6040518060600160405280602381526020016156a4602391396001600160a01b038816600090815260c96020526040902054919063ffffffff613a6716565b6001600160a01b038616600090815260c9602052604090205560ca54613472908563ffffffff614acf16565b60ca81905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156134f75781810151838201526020016134df565b50505050905090810190601f1680156135245780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561355757818101518382015260200161353f565b50505050905090810190601f1680156135845780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516000916001600160a01b038816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b6040805163555ddc6560e11b81526001600160a01b03871660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89560248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b15801561366057600080fd5b505afa158015613674573d6000803e3d6000fd5b505050506040513d602081101561368a57600080fd5b505190506001600160a01b0381161561381b57806001600160a01b03166375ab97828888888888886040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015613750578181015183820152602001613738565b50505050905090810190601f16801561377d5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156137b0578181015183820152602001613798565b50505050905090810190601f1680156137dd5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561380257600080fd5b505af1158015613816573d6000803e3d6000fd5b505050505b50505050505050565b6138308686868661184f565b61387b61383c84614aab565b60405180606001604052806027815260200161537a602791396001600160a01b038816600090815260c96020526040902054919063ffffffff613a6716565b6001600160a01b038616600090815260c960205260409020556138c56138a084614aab565b6001600160a01b038616600090815260c960205260409020549063ffffffff614b2c16565b60c96000866001600160a01b03166001600160a01b0316815260200190815260200160002081905550836001600160a01b0316856001600160a01b0316876001600160a01b03167f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561397757818101518382015260200161395f565b50505050905090810190601f1680156139a45780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156139d75781810151838201526020016139bf565b50505050905090810190601f168015613a045780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3505050505050565b60008184841115613af65760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613abb578181015183820152602001613aa3565b50505050905090810190601f168015613ae85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6040805163555ddc6560e11b81526001600160a01b03871660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b158015613b8257600080fd5b505afa158015613b96573d6000803e3d6000fd5b505050506040513d6020811015613bac57600080fd5b505190506001600160a01b03811615613d4057806001600160a01b03166223de298989898989896040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015613c71578181015183820152602001613c59565b50505050905090810190601f168015613c9e5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015613cd1578181015183820152602001613cb9565b50505050905090810190601f168015613cfe5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015613d2357600080fd5b505af1158015613d37573d6000803e3d6000fd5b50505050613d94565b8115613d9457613d58866001600160a01b0316614759565b15613d945760405162461bcd60e51b815260040180806020018281038252604d815260200180615594604d913960600191505060405180910390fd5b5050505050505050565b6000828152603360205260409020613dbc908263ffffffff614b8616565b15611c7157613dc9613293565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020613e2b908263ffffffff614b9b16565b15611c7157613e38613293565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038616613ec15760405162461bcd60e51b81526004018080602001828103825260228152602001806153586022913960400191505060405180910390fd5b6001600160a01b038516613f1c576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6000613f26613293565b9050613f368188888888886135dc565b613f44818888888888613824565b61381b81888888888888613afe565b600061187369d3c21bcecceda1000000613f7860d25485614bb090919063ffffffff16565b9063ffffffff614c0916565b50600090565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114614033576040805162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015290519081900360640190fd5b60208201516040830151606084015160001a61405186828585614c70565b9695505050505050565b600091565b604080516020810190915260008152600b9190910191565b60006123088383614dea565b6000612308836001600160a01b038416614e4e565b600054610100900460ff16806140b257506140b261311a565b806140c0575060005460ff16155b6140fb5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015614126576000805460ff1961ff0019909116610100171660011790555b61412e61475f565b6131c8614e66565b600054610100900460ff168061414f575061414f61311a565b8061415d575060005460ff16155b6141985760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff161580156141c3576000805460ff1961ff0019909116610100171660011790555b6141cb61475f565b6131c8614f2d565b600061187382615026565b6001600160a01b038416614239576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6000614243613293565b9050614252816000878761184f565b60e0835110156142935760405162461bcd60e51b815260040180806020018281038252602c8152602001806154d0602c913960400191505060405180910390fd5b60608380602001905160808110156142aa57600080fd5b815160208301805160405192949293830192919084600160201b8211156142d057600080fd5b9083019060208201858111156142e557600080fd5b8251600160201b8111828201881017156142fe57600080fd5b82525081516020918201929091019080838360005b8381101561432b578181015183820152602001614313565b50505050905090810190601f1680156143585780820380516001836020036101000a031916815260200191505b5060405250508151919350600092508291602085019150606081101561437d57600080fd5b81516020830151604080850180519151939592948301929184600160201b8211156143a757600080fd5b9083019060208201858111156143bc57600080fd5b8251600160201b8111828201881017156143d557600080fd5b82525081516020918201929091019080838360005b838110156144025781810151838201526020016143ea565b50505050905090810190601f16801561442f5780820380516001836020036101000a031916815260200191505b5060405250505050915091506144436118a6565b61445a5769d3c21bcecceda100000060d2556144ba565b60006144746144676118a6565b849063ffffffff614acf16565b9050614486828263ffffffff614acf16565b91506144b56144936118a6565b613f786144a6858c63ffffffff614acf16565b60d2549063ffffffff614bb016565b60d255505b60ca8190556144e06144db886144cf8b611f2b565b9063ffffffff614b2c16565b614aab565b6001600160a01b038916600090815260c9602052604081209190915561450d9085908a8a8a8a6001613afe565b876001600160a01b0316846001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d898989604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561458c578181015183820152602001614574565b50505050905090810190601f1680156145b95780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156145ec5781810151838201526020016145d4565b50505050905090810190601f1680156146195780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805188815290516001600160a01b038a16916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050505050565b60008060008087806020019051608081101561468f57600080fd5b5080516020820151604083015160609093015160fe549297509095509193509091506000906146d3906146cc90620186a09063ffffffff614acf16565b838561502a565b90506000614703670de0b6b3a7640000613f78886146f78c8763ffffffff614acf16565b9063ffffffff614bb016565b9050801561474d5761474d8560fd60009054906101000a90046001600160a01b03168360405180602001604052806000815250604051806020016040528060008152506000613e7c565b50505050505050505050565b3b151590565b600054610100900460ff1680614778575061477861311a565b80614786575060005460ff16155b6147c15760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff161580156131c8576000805460ff1961ff0019909116610100171660011790558015611dce576000805461ff001916905550565b600054610100900460ff1680614818575061481861311a565b80614826575060005460ff16155b6148615760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff1615801561488c576000805460ff1961ff0019909116610100171660011790555b835161489f9060cb906020870190615195565b5082516148b39060cc906020860190615195565b5081516148c79060cd906020850190615213565b5060005b60cd5481101561492457600160ce600060cd84815481106148e857fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016148cb565b50604080516a22a9219b9b9baa37b5b2b760a91b8152815190819003600b0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad24916329965a1d91606480830192600092919082900301818387803b1580156149a257600080fd5b505af11580156149b6573d6000803e3d6000fd5b5050604080516922a92199182a37b5b2b760b11b8152815190819003600a0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad2493506329965a1d9250606480830192600092919082900301818387803b158015614a3657600080fd5b505af1158015614a4a573d6000803e3d6000fd5b505069d3c21bcecceda100000060d2555050801561184f576000805461ff001916905550505050565b6000614a7d611ff9565b6001600160a01b0316336001600160a01b031614614a9c5750336116ec565b614aa4615038565b90506116ec565b60d25460009061187390613f788469d3c21bcecceda100000063ffffffff614bb016565b600082821115614b26576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082820183811015612308576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000612308836001600160a01b038416615085565b6000612308836001600160a01b0384166150cf565b600082614bbf57506000611873565b82820282848281614bcc57fe5b04146123085760405162461bcd60e51b815260040180806020018281038252602181526020018061551e6021913960400191505060405180910390fd5b6000808211614c5f576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381614c6857fe5b049392505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115614cd15760405162461bcd60e51b815260040180806020018281038252602281526020018061542f6022913960400191505060405180910390fd5b8360ff16601b1480614ce657508360ff16601c145b614d215760405162461bcd60e51b81526004018080602001828103825260228152602001806154fc6022913960400191505060405180910390fd5b604080516000808252602080830180855289905260ff88168385015260608301879052608083018690529251909260019260a080820193601f1981019281900390910190855afa158015614d79573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116614de1576040805162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b81546000908210614e2c5760405162461bcd60e51b81526004018080602001828103825260228152602001806152b36022913960400191505060405180910390fd5b826000018281548110614e3b57fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600054610100900460ff1680614e7f5750614e7f61311a565b80614e8d575060005460ff16155b614ec85760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015614ef3576000805460ff1961ff0019909116610100171660011790555b609780546001600160a01b03191673d216153c06e857cd7f72665e0af1d7d82172f4941790558015611dce576000805461ff001916905550565b600054610100900460ff1680614f465750614f4661311a565b80614f54575060005460ff16155b614f8f5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a2602e913960400191505060405180910390fd5b600054610100900460ff16158015614fba576000805460ff1961ff0019909116610100171660011790555b6000614fc4613293565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015611dce576000805461ff001916905550565b5490565b606490810191909202020490565b600060606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031692915050565b60006150918383614e4e565b6150c757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611873565b506000611873565b6000818152600183016020526040812054801561518b578354600019808301919081019060009087908390811061510257fe5b906000526020600020015490508087600001848154811061511f57fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061514f57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611873565b6000915050611873565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106151d657805160ff1916838001178555615203565b82800160010185558215615203579182015b828111156152035782518255916020019190600101906151e8565b5061520f929150615274565b5090565b828054828255906000526020600020908101928215615268579160200282015b8281111561526857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615233565b5061520f92915061528e565b6116ec91905b8082111561520f576000815560010161527a565b6116ec91905b8082111561520f5780546001600160a01b031916815560010161529456fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473526563697069656e742063616e6e6f742062652074686520746f6b656e20636f6e7472616374206164647265737321416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433737373a20617070726f76652066726f6d20746865207a65726f20616464726573734552433737373a2073656e642066726f6d20746865207a65726f20616464726573734552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737374727573746564207369676e657220697320746865207a65726f20616464726573734552433737373a206275726e2066726f6d20746865207a65726f20616464726573734552433737373a20617574686f72697a696e672073656c66206173206f70657261746f7245434453413a20696e76616c6964207369676e6174757265202773272076616c7565416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433737373a207265766f6b696e672073656c66206173206f70657261746f72496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a65644e6f7420656e6f756768206d6574616461746120746f206d696e7420536166654d6f6f6e20746f6b656e732145434453413a20696e76616c6964207369676e6174757265202776272076616c7565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f6e6c79207468652061637475616c2061646d696e206f70657261746f722063616e206368616e67652074686520616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433737373a20746f6b656e20726563697069656e7420636f6e747261637420686173206e6f20696d706c656d656e74657220666f7220455243373737546f6b656e73526563697069656e744552433737373a207472616e7366657220746f20746865207a65726f206164647265737347534e526563697069656e743a2063616c6c6572206973206e6f742052656c61794875624552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f7220666f7220686f6c6465724552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a207472616e736665722066726f6d20746865207a65726f20616464726573734552433737373a206275726e20616d6f756e7420657863656564732062616c616e63654552433737373a20617070726f766520746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212206a7bb94537618b3f802a31b2ad816c9da8ee3d258f07b6c1d12ecbba8aed32b364736f6c63430006020033
Deployed Bytecode Sourcemap
112424:3101:0:-:0;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;112424:3101:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94774:132;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;94774:132:0;;;;;;;;;;;;;;;;;90824:100;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8::-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;90824:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112794:499;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;112794:499:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;112794:499:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;112794:499:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;112794:499:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;112794:499:0;;;;;;;;-1:-1:-1;112794:499:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;112794:499:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;112794:499:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;112794:499:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;112794:499:0;;-1:-1:-1;;;112794:499:0;;-1:-1:-1;;;;;112794:499:0;;-1:-1:-1;112794:499:0;;-1:-1:-1;112794:499:0:i;:::-;;96403:201;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;96403:201:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;115039:126;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;115039:126:0;-1:-1:-1;;;;;115039:126:0;;:::i;91650:147::-;;;:::i;:::-;;;;;;;;;;;;;;;;114298:509;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;114298:509:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;114298:509:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;114298:509:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;114298:509:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;114298:509:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;114298:509:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;114298:509:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;114298:509:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;114298:509:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;114298:509:0;;-1:-1:-1;114298:509:0;-1:-1:-1;114298:509:0;:::i;96980:694::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;96980:694:0;;;;;;;;;;;;;;;;;:::i;25013:114::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25013:114:0;;:::i;113761:231::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;113761:231:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;113761:231:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;113761:231:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;113761:231:0;;-1:-1:-1;113761:231:0;-1:-1:-1;113761:231:0;:::i;25389:227::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25389:227:0;;;;;;-1:-1:-1;;;;;25389:227:0;;:::i;89127:46::-;;;:::i;91281:84::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;26598:209;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;26598:209:0;;;;;;-1:-1:-1;;;;;26598:209:0;;:::i;111976:264::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;111976:264:0;-1:-1:-1;;;;;111976:264:0;;:::i;114815:103::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;114815:103:0;-1:-1:-1;;;;;114815:103:0;;:::i;91487:97::-;;;:::i;108371:204::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;108371:204:0;-1:-1:-1;;;;;108371:204:0;;:::i;95032:407::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;95032:407:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;95032:407:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;95032:407:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;95032:407:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;95032:407:0;;;;;;;;-1:-1:-1;95032:407:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;95032:407:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;95032:407:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;95032:407:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;95032:407:0;;-1:-1:-1;95032:407:0;;-1:-1:-1;;;;;95032:407:0:i;114926:105::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;114926:105:0;-1:-1:-1;;;;;114926:105:0;;:::i;91902:190::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;91902:190:0;-1:-1:-1;;;;;91902:190:0;;:::i;61342:148::-;;;:::i;50614:104::-;;;:::i;:::-;;;;-1:-1:-1;;;;;50614:104:0;;;;;;;;;;;;;;54373:224;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;54373:224:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;54373:224:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;54373:224:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;54373:224:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;54373:224:0;;-1:-1:-1;54373:224:0;;-1:-1:-1;;;;;54373:224:0:i;108983:1065::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;108983:1065:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;108983:1065:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;108983:1065:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;108983:1065:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;108983:1065:0;;;;;;;;;;;;;;;-1:-1:-1;108983:1065:0;;;;;-1:-1:-1;108983:1065:0;;-1:-1:-1;108983:1065:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;108983:1065:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;108983:1065:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;108983:1065:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;108983:1065:0;;-1:-1:-1;;108983:1065:0;;;-1:-1:-1;108983:1065:0;;-1:-1:-1;;108983:1065:0:i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;108983:1065:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60691:87;;;:::i;24686:138::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24686:138:0;;;;;;;:::i;23647:139::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23647:139:0;;;;;;-1:-1:-1;;;;;23647:139:0;;:::i;93797:423::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;93797:423:0;-1:-1:-1;;;;;93797:423:0;;:::i;90985:104::-;;;:::i;107537:461::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;107537:461:0;;;;;;;;;;:::i;92229:166::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;92229:166:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;92229:166:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;92229:166:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;92229:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;92229:166:0;;-1:-1:-1;92229:166:0;;-1:-1:-1;;;;;92229:166:0:i;108767:99::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;108767:99:0;;:::i;22392:49::-;;;:::i;92636:451::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;92636:451:0;;;;;;;;:::i;51897:238::-;;;:::i;111528:363::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;111528:363:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;111528:363:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;111528:363:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;111528:363:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;111528:363:0;;;;;;;;-1:-1:-1;111528:363:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;111528:363:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;111528:363:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;111528:363:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;111528:363:0;;-1:-1:-1;111528:363:0;;-1:-1:-1;;;;;111528:363:0:i;23960:127::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23960:127:0;;:::i;107466:26::-;;;:::i;114000:290::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;114000:290:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;114000:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;114000:290:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;114000:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;114000:290:0;;;;;;;;-1:-1:-1;114000:290:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;114000:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;114000:290:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;114000:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;114000:290:0;;-1:-1:-1;114000:290:0;;-1:-1:-1;;;;;114000:290:0:i;112569:62::-;;;:::i;25861:230::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25861:230:0;;;;;;-1:-1:-1;;;;;25861:230:0;;:::i;93422:303::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;93422:303:0;;;;;;;;;;:::i;107434:27::-;;;:::i;108581:180::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;108581:180:0;-1:-1:-1;;;;;108581:180:0;;:::i;113301:452::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;113301:452:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;113301:452:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;113301:452:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;113301:452:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;113301:452:0;;;;;;;;-1:-1:-1;113301:452:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;113301:452:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;113301:452:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;113301:452:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;113301:452:0;;-1:-1:-1;113301:452:0;;-1:-1:-1;;;;;113301:452:0:i;96105:153::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;96105:153:0;;;;;;;;;;:::i;111259:156::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;111259:156:0;-1:-1:-1;;;;;111259:156:0;;:::i;55255:290::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;55255:290:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;55255:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;55255:290:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;55255:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;55255:290:0;;-1:-1:-1;;;;55255:290:0;;;;;-1:-1:-1;55255:290:0;;;;;;;;;:::i;111101:28::-;;;:::i;61645:244::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61645:244:0;-1:-1:-1;;;;;61645:244:0;;:::i;94289:414::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;94289:414:0;-1:-1:-1;;;;;94289:414:0;;:::i;95567:290::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;95567:290:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;95567:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;95567:290:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;95567:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;95567:290:0;;;;;;;;-1:-1:-1;95567:290:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;95567:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;95567:290:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;95567:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;95567:290:0;;-1:-1:-1;95567:290:0;;-1:-1:-1;;;;;95567:290:0:i;107398:31::-;;;:::i;93224:130::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;93224:130:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;93224:130:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;93224:130:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;93224:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;93224:130:0;;-1:-1:-1;93224:130:0;;-1:-1:-1;;;;;93224:130:0:i;94774:132::-;94840:16;94876:22;94869:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;94869:29:0;;;;;;;;;;;;;;;;;;;;;;;94774:132;;:::o;90824:100::-;90911:5;90904:12;;;;;;;;-1:-1:-1;;90904:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90878:13;;90904:12;;90911:5;;90904:12;;90911:5;90904:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90904:12:0;;90824:100;-1:-1:-1;;;;;90824:100:0:o;112794:499::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;112966:33:::1;113010:22;:20;:22::i;:::-;113043:55;113057:9;113068:11;113081:16;113043:13;:55::i;:::-;113109;113137:12;113151;113109:27;:55::i;:::-;113175;113217:12;113175:41;:55::i;:::-;113241:44;22437:4;113272:12:::0;113241:10:::1;:44::i;:::-;8944:1;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;8958:68;112794:499;;;;:::o;96403:201::-;96485:4;96502:14;96519:12;:10;:12::i;:::-;96502:29;;96542:32;96551:6;96559:7;96568:5;96542:8;:32::i;:::-;96592:4;96585:11;;;96403:201;;;;;:::o;115039:126::-;112607:24;;;-1:-1:-1;;;112607:24:0;;;;;;;;;;;;115103:4;;115127:30;;115148:8;115127:7;:30::i;91650:147::-;91777:12;;91650:147;:::o;114298:509::-;114559:36;114573:12;:10;:12::i;:::-;114587:7;114559:13;:36::i;:::-;114537:130;;;;-1:-1:-1;;;114537:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114678:46;114684:7;114693:6;114701:8;;114678:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;114678:46:0;;;;137:4:-1;114678:46:0;;;;;;;;;;;;;;;;;;-1:-1:-1;114711:12:0;;-1:-1:-1;114711:12:0;;;;114678:46;;114711:12;;;;114678:46;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;114678:5:0;;-1:-1:-1;;;114678:46:0:i;:::-;114747:7;-1:-1:-1;;;;;114740:59:0;;114756:6;114764:24;;114790:8;;114740:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;;74:27;137:4;117:14;-1:-1;;113:30;157:16;;;114740:59:0;;;;;;;;;;;-1:-1:-1;114740:59:0;;;;;1:33:-1;99:1;81:16;;;74:27;114740:59:0;;137:4:-1;117:14;;;-1:-1;;113:30;157:16;;;114740:59:0;;;;-1:-1:-1;114740:59:0;;-1:-1:-1;;;;;;;;114740:59:0;114298:509;;;;;;;;:::o;96980:694::-;97086:4;-1:-1:-1;;;;;97111:23:0;;97103:72;;;;-1:-1:-1;;;97103:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;97194:20:0;;97186:71;;;;-1:-1:-1;;;97186:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97270:15;97288:12;:10;:12::i;:::-;97270:30;;97313:61;97331:7;97340:6;97348:9;97359:6;97313:61;;;;;;;;;;;;;;;;;;;;;;;;:17;:61::i;:::-;97387:49;97393:7;97402:6;97410:9;97421:6;97387:49;;;;;;;;;;;;;;;;;;;;;;;;:5;:49::i;:::-;97447:112;97456:6;97464:7;97473:85;97506:6;97473:85;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;97473:19:0;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;:85;;:32;:85;:::i;:::-;97447:8;:112::i;:::-;97572:70;97592:7;97601:6;97609:9;97620:6;97572:70;;;;;;;;;;;;;;;;;;;;;;;;97636:5;97572:19;:70::i;:::-;-1:-1:-1;97662:4:0;;96980:694;-1:-1:-1;;;;96980:694:0:o;25013:114::-;25070:7;25097:12;;;:6;:12;;;;;:22;;;;25013:114::o;113761:231::-;113896:4;113918:44;113925:6;113918:44;;;;;;;;;;;;113937:24;;113918:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;113918:6:0;;-1:-1:-1;;;113918:44:0:i;:::-;-1:-1:-1;113980:4:0;113761:231;;;;;:::o;25389:227::-;25481:12;;;;:6;:12;;;;;:22;;;25473:45;;25505:12;:10;:12::i;:::-;25473:7;:45::i;:::-;25465:105;;;;-1:-1:-1;;;25465:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25583:25;25594:4;25600:7;25583:10;:25::i;:::-;25389:227;;:::o;89127:46::-;;;;:::o;91281:84::-;91355:2;91281:84;:::o;26598:209::-;26696:12;:10;:12::i;:::-;-1:-1:-1;;;;;26685:23:0;:7;-1:-1:-1;;;;;26685:23:0;;26677:83;;;;-1:-1:-1;;;26677:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26773:26;26785:4;26791:7;26773:11;:26::i;111976:264::-;112064:13;;-1:-1:-1;;;;;112064:13:0;112048:12;:10;:12::i;:::-;-1:-1:-1;;;;;112048:29:0;;112040:95;;;;-1:-1:-1;;;112040:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112167:13;;112147:50;;;-1:-1:-1;;;;;112167:13:0;;;112147:50;;;;;;;;;;;;;;;;;;;;;112204:13;:30;;-1:-1:-1;;;;;;112204:30:0;-1:-1:-1;;;;;112204:30:0;;;;;;;;;;111976:264::o;114815:103::-;112607:24;;;-1:-1:-1;;;112607:24:0;;;;;;;;;;;;114878:32;;114901:8;114878:9;:32::i;:::-;114815:103;:::o;91487:97::-;91575:1;91487:97;:::o;108371:204::-;60922:12;:10;:12::i;:::-;-1:-1:-1;;;;;60911:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;60911:23:0;;60903:68;;;;;-1:-1:-1;;;60903:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;60903:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;108456:31:0;::::1;108448:78;;;;-1:-1:-1::0;;;108448:78:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108533:16;:36:::0;;-1:-1:-1;;;;;;108533:36:0::1;-1:-1:-1::0;;;;;108533:36:0;;;::::1;::::0;;;::::1;::::0;;108371:204::o;95032:407::-;95278:35;95292:12;:10;:12::i;:::-;95306:6;95278:13;:35::i;:::-;95270:92;;;;-1:-1:-1;;;95270:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95373:58;95379:6;95387:9;95398:6;95406:4;95412:12;95426:4;95373:5;:58::i;:::-;95032:407;;;;;:::o;114926:105::-;112607:24;;;-1:-1:-1;;;112607:24:0;;;;;;;;;;;;114990:33;;115014:8;114990:10;:33::i;91902:190::-;-1:-1:-1;;;;;92061:22:0;;92019:7;92061:22;;;:9;:22;;;;;;92046:38;;:13;:38::i;61342:148::-;60922:12;:10;:12::i;:::-;-1:-1:-1;;;;;60911:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;60911:23:0;;60903:68;;;;;-1:-1:-1;;;60903:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;60903:68:0;;;;;;;;;;;;;;;61433:6:::1;::::0;61412:40:::1;::::0;61449:1:::1;::::0;-1:-1:-1;;;;;61433:6:0::1;::::0;61412:40:::1;::::0;61449:1;;61412:40:::1;61463:6;:19:::0;;-1:-1:-1;;;;;;61463:19:0::1;::::0;;61342:148::o;50614:104::-;50701:9;;-1:-1:-1;;;;;50701:9:0;50614:104;:::o;54373:224::-;54452:7;54494:12;:10;:12::i;:::-;-1:-1:-1;;;;;54480:26:0;:10;-1:-1:-1;;;;;54480:26:0;;54472:75;;;;-1:-1:-1;;;54472:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54565:24;54581:7;54565:15;:24::i;108983:1065::-;109304:7;109313:12;109338:15;109355:22;109392:12;109381:39;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;109381:39:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:20;;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;109381:39:0;;420:4:-1;411:14;;;;109381:39:0;;;;;411:14:-1;109381:39:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;109381:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109337:83;;;;109427:17;109472:7;109488:5;109502:4;109515:15;109539:14;109562:8;109579;109596:5;109642:12;:10;:12::i;:::-;109713:4;109447:321;;;;;;;;;;;-1:-1:-1;;;;;109447:321:0;-1:-1:-1;;;;;109447:321:0;;;;;;;;-1:-1:-1;;;;;109447:321:0;-1:-1:-1;;;;;109447:321:0;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;109447:321:0;;;;;-1:-1:-1;109447:321:0;;;;;;;-1:-1:-1;109447:321:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;109447:321:0;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;109447:321:0;;;;;;109842:16;;109779:15;;;;;;;;;109447:321;;-1:-1:-1;;;;;;109842:16:0;;-1:-1:-1;109779:59:0;;-1:-1:-1;109828:9:0;;-1:-1:-1;109779:40:0;;-1:-1:-1;109779:38:0;:40::i;:::-;:48;:59;:48;:59;:::i;:::-;-1:-1:-1;;;;;109779:79:0;;109775:268;;;109896:51;;;;;;;;;-1:-1:-1;;;;;109896:51:0;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;109896:51:0;;;;;;;109876:72;;:19;:72::i;:::-;109869:79;;;;;;;;;109775:268;109978:57;110005:28;109978:18;:57::i;108983:1065::-;;;;;;;;;;;;;:::o;60691:87::-;60764:6;;-1:-1:-1;;;;;60764:6:0;60691:87;:::o;24686:138::-;24759:7;24786:12;;;:6;:12;;;;;:30;;24810:5;24786:30;:23;:30;:::i;:::-;24779:37;24686:138;-1:-1:-1;;;24686:138:0:o;23647:139::-;23716:4;23740:12;;;:6;:12;;;;;:38;;23770:7;23740:38;:29;:38;:::i;93797:423::-;93902:8;-1:-1:-1;;;;;93886:24:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;93886:24:0;;;93878:73;;;;-1:-1:-1;;;93878:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;93968:27:0;;;;;;:17;:27;;;;;;;;93964:189;;;94019:24;:38;94044:12;:10;:12::i;:::-;-1:-1:-1;;;;;94019:38:0;;;;;;;;;;;;;;;;;-1:-1:-1;94019:38:0;;;:48;;;;;;;;;94012:55;;-1:-1:-1;;94012:55:0;;;93964:189;;;94137:4;94100:10;:24;94111:12;:10;:12::i;:::-;-1:-1:-1;;;;;94100:24:0;;;;;;;;;;;;;;;;;-1:-1:-1;94100:24:0;;;:34;;;;;;;;;:41;;-1:-1:-1;;94100:41:0;;;;;;;;;;93964:189;94199:12;:10;:12::i;:::-;-1:-1:-1;;;;;94170:42:0;94189:8;-1:-1:-1;;;;;94170:42:0;;;;;;;;;;;93797:423;:::o;90985:104::-;91074:7;91067:14;;;;;;;;-1:-1:-1;;91067:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91041:13;;91067:14;;91074:7;;91067:14;;91074:7;91067:14;;;;;;;;;;;;;;;;;;;;;;;;107537:461;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;107678:21:::1;:19;:21::i;:::-;107706:16;:14;:16::i;:::-;-1:-1:-1::0;;;;;107739:31:0;::::1;107731:78;;;;-1:-1:-1::0;;;107731:78:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107816:16;:36:::0;;-1:-1:-1;;;;;;107816:36:0::1;-1:-1:-1::0;;;;;107816:36:0;;::::1;::::0;;;::::1;::::0;;;107869:27;::::1;107861:70;;;::::0;;-1:-1:-1;;;107861:70:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;107938:12;:28:::0;;-1:-1:-1;;;;;;107938:28:0::1;-1:-1:-1::0;;;;;107938:28:0;::::1;;::::0;;107987:5:::1;107973:11;:19:::0;8958:68;;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;8958:68;107537:461;;;:::o;92229:166::-;92333:54;92339:12;:10;:12::i;:::-;92353:9;92364:6;92372:4;92333:54;;;;;;;;;;;;92382:4;92333:5;:54::i;108767:99::-;60922:12;:10;:12::i;:::-;-1:-1:-1;;;;;60911:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;60911:23:0;;60903:68;;;;;-1:-1:-1;;;60903:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;60903:68:0;;;;;;;;;;;;;;;108834:11:::1;:26:::0;108767:99::o;22392:49::-;22437:4;22392:49;:::o;92636:451::-;92722:4;-1:-1:-1;;;;;92747:23:0;;92739:72;;;;-1:-1:-1;;;92739:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92824:12;92839;:10;:12::i;:::-;92824:27;;92864:56;92882:4;92888;92894:9;92905:6;92864:56;;;;;;;;;;;;;;;;;;;;;;;;:17;:56::i;:::-;92933:44;92939:4;92945;92951:9;92962:6;92933:44;;;;;;;;;;;;;;;;;;;;;;;;:5;:44::i;:::-;92990:65;93010:4;93016;93022:9;93033:6;92990:65;;;;;;;;;;;;;;;;;;;;;;;;93049:5;92990:19;:65::i;51897:238::-;52113:14;;;;;;;;;;;;-1:-1:-1;;;52113:14:0;;;;51897:238;:::o;111528:363::-;111722:13;;-1:-1:-1;;;;;111722:13:0;111706:12;:10;:12::i;:::-;-1:-1:-1;;;;;111706:29:0;;111698:74;;;;;-1:-1:-1;;;111698:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111779:59;111785:6;111793:9;111804:6;111812:4;111818:12;111832:5;111779;:59::i;:::-;111871:13;;111850:35;;;-1:-1:-1;;;;;111871:13:0;;;111850:35;;;;;;;;;;;;111528:363;;;;;:::o;23960:127::-;24023:7;24050:12;;;:6;:12;;;;;:29;;:27;:29::i;107466:26::-;;;;:::o;114000:290::-;114161:41;114167:12;:10;:12::i;:::-;114181:6;114189:8;114161:41;;;;;;;;;;;;:5;:41::i;:::-;114225:12;:10;:12::i;:::-;-1:-1:-1;;;;;114218:64:0;;114239:6;114247:24;114273:8;114218:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;114218:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;114218:64:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;114218:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114000:290;;;:::o;112569:62::-;112607:24;;;-1:-1:-1;;;112607:24:0;;;;;;;;;;;;112569:62;:::o;25861:230::-;25954:12;;;;:6;:12;;;;;:22;;;25946:45;;25978:12;:10;:12::i;25946:45::-;25938:106;;;;-1:-1:-1;;;25938:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93422:303;93522:4;93558:11;-1:-1:-1;;;;;93546:23:0;:8;-1:-1:-1;;;;;93546:23:0;;:121;;;-1:-1:-1;;;;;;93587:27:0;;;;;;:17;:27;;;;;;;;:79;;;;-1:-1:-1;;;;;;93619:37:0;;;;;;;:24;:37;;;;;;;;:47;;;;;;;;;;;;93618:48;93587:79;93546:171;;;-1:-1:-1;;;;;;;93684:23:0;;;;;;;:10;:23;;;;;;;;:33;;;;;;;;;;;;;;;;93422:303::o;107434:27::-;;;-1:-1:-1;;;;;107434:27:0;;:::o;108581:180::-;60922:12;:10;:12::i;:::-;-1:-1:-1;;;;;60911:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;60911:23:0;;60903:68;;;;;-1:-1:-1;;;60903:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;60903:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;108658:27:0;::::1;108650:70;;;::::0;;-1:-1:-1;;;108650:70:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;108727:12;:28:::0;;-1:-1:-1;;;;;;108727:28:0::1;-1:-1:-1::0;;;;;108727:28:0;;;::::1;::::0;;;::::1;::::0;;108581:180::o;113301:452::-;113476:4;-1:-1:-1;;;;;113506:26:0;;113527:4;113506:26;;113498:87;;;;-1:-1:-1;;;113498:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112607:24;;;-1:-1:-1;;;112607:24:0;;;;;;;;;;;;113604:34;;113625:12;:10;:12::i;113604:34::-;113596:69;;;;;-1:-1:-1;;;113596:69:0;;;;;;;;;;;;-1:-1:-1;;;113596:69:0;;;;;;;;;;;;;;;113676:47;113682:9;113693:5;113700:8;113710:12;113676:5;:47::i;96105:153::-;-1:-1:-1;;;;;96222:19:0;;;96195:7;96222:19;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;96105:153::o;111259:156::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;111377:13:::1;:30:::0;;-1:-1:-1;;;;;;111377:30:0::1;-1:-1:-1::0;;;;;111377:30:0;::::1;;::::0;;8958:68;;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;111259:156;;:::o;55255:290::-;55414:12;:10;:12::i;:::-;-1:-1:-1;;;;;55400:26:0;:10;-1:-1:-1;;;;;55400:26:0;;55392:75;;;;-1:-1:-1;;;55392:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55478:59;55495:7;55504;55513:12;55527:9;55478:16;:59::i;111101:28::-;;;-1:-1:-1;;;;;111101:28:0;;:::o;61645:244::-;60922:12;:10;:12::i;:::-;-1:-1:-1;;;;;60911:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;60911:23:0;;60903:68;;;;;-1:-1:-1;;;60903:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;60903:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;61734:22:0;::::1;61726:73;;;;-1:-1:-1::0;;;61726:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61836:6;::::0;61815:38:::1;::::0;-1:-1:-1;;;;;61815:38:0;;::::1;::::0;61836:6:::1;::::0;61815:38:::1;::::0;61836:6:::1;::::0;61815:38:::1;61864:6;:17:::0;;-1:-1:-1;;;;;;61864:17:0::1;-1:-1:-1::0;;;;;61864:17:0;;;::::1;::::0;;;::::1;::::0;;61645:244::o;94289:414::-;94387:12;:10;:12::i;:::-;-1:-1:-1;;;;;94375:24:0;:8;-1:-1:-1;;;;;94375:24:0;;;94367:70;;;;-1:-1:-1;;;94367:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;94454:27:0;;;;;;:17;:27;;;;;;;;94450:189;;;94549:4;94498:24;:38;94523:12;:10;:12::i;:::-;-1:-1:-1;;;;;94498:38:0;;;;;;;;;;;;;;;;;-1:-1:-1;94498:38:0;;;:48;;;;;;;;;:55;;-1:-1:-1;;94498:55:0;;;;;;;;;;94450:189;;;94593:10;:24;94604:12;:10;:12::i;:::-;-1:-1:-1;;;;;94593:24:0;;;;;;;;;;;;;;;;;-1:-1:-1;94593:24:0;;;:34;;;;;;;;;94586:41;;-1:-1:-1;;94586:41:0;;;94450:189;94682:12;:10;:12::i;:::-;-1:-1:-1;;;;;94656:39:0;94672:8;-1:-1:-1;;;;;94656:39:0;;;;;;;;;;;94289:414;:::o;95567:290::-;95711:36;95725:12;:10;:12::i;:::-;95739:7;95711:13;:36::i;:::-;95703:93;;;;-1:-1:-1;;;95703:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95807:42;95813:7;95822:6;95830:4;95836:12;95807:5;:42::i;107398:31::-;;;-1:-1:-1;;;;;107398:31:0;;:::o;93224:130::-;93309:37;93315:12;:10;:12::i;:::-;93329:6;93337:4;93309:37;;;;;;;;;;;;:5;:37::i;9126:125::-;9174:4;9199:44;9237:4;9199:29;:44::i;:::-;9198:45;9191:52;;9126:125;:::o;21877:141::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;21941:26:::1;:24;:26::i;:::-;21978:32;:30;:32::i;:::-;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;21877:141;:::o;89727:272::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;89896:26:::1;:24;:26::i;:::-;89933:58;89957:5;89964:7;89973:17;89933:23;:58::i;:::-;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;89727:272;;;;:::o;115173:173::-;115269:15;115304:36;:34;:36::i;:::-;115297:43;;115173:173;:::o;103501:341::-;-1:-1:-1;;;;;103595:20:0;;103587:70;;;;-1:-1:-1;;;103587:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;103676:21:0;;103668:69;;;;-1:-1:-1;;;103668:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;103750:19:0;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;:36;;;103802:32;;;;;;;;;;;;;;;;;103501:341;;;:::o;101996:774::-;-1:-1:-1;;;;;102189:18:0;;102181:65;;;;-1:-1:-1;;;102181:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102259:16;102278:12;:10;:12::i;:::-;102259:31;;102303:73;102321:8;102331:4;102345:1;102349:6;102357:4;102363:12;102303:17;:73::i;:::-;102389:56;102410:8;102420:4;102434:1;102438:6;102389:20;:56::i;:::-;102511:83;102531:23;102547:6;102531:15;:23::i;:::-;102511:83;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;102511:15:0;;;;;;:9;:15;;;;;;;:83;;:19;:83;:::i;:::-;-1:-1:-1;;;;;102493:15:0;;;;;;:9;:15;;;;;:101;102620:12;;:24;;102637:6;102620:24;:16;:24;:::i;:::-;102605:12;:39;;;;102679:4;-1:-1:-1;;;;;102662:50:0;102669:8;-1:-1:-1;;;;;102662:50:0;;102685:6;102693:4;102699:12;102662:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;102662:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102662:50:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;102662:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102728:34;;;;;;;;102751:1;;-1:-1:-1;;;;;102728:34:0;;;;;;;;;;;;101996:774;;;;;:::o;104326:509::-;104579:78;;;-1:-1:-1;;;104579:78:0;;-1:-1:-1;;;;;104579:78:0;;;;;;88020:66;104579:78;;;;;;104557:19;;87541:42;;104579:41;;:78;;;;;;;;;;;;;;;87541:42;104579:78;;;5:2:-1;;;;30:1;27;20:12;5:2;104579:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;104579:78:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;104579:78:0;;-1:-1:-1;;;;;;104672:25:0;;;104668:160;;104739:11;-1:-1:-1;;;;;104714:50:0;;104765:8;104775:4;104781:2;104785:6;104793:8;104803:12;104714:102;;;;;;;;;;;;;-1:-1:-1;;;;;104714:102:0;-1:-1:-1;;;;;104714:102:0;;;;;;-1:-1:-1;;;;;104714:102:0;-1:-1:-1;;;;;104714:102:0;;;;;;-1:-1:-1;;;;;104714:102:0;-1:-1:-1;;;;;104714:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;104714:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;104714:102:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;104714:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;104714:102:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;104714:102:0;;;;104668:160;104326:509;;;;;;;:::o;102778:578::-;102997:48;103018:8;103028:4;103034:2;103038:6;102997:20;:48::i;:::-;103076:87;103096:23;103112:6;103096:15;:23::i;:::-;103076:87;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;103076:15:0;;;;;;:9;:15;;;;;;;:87;;:19;:87;:::i;:::-;-1:-1:-1;;;;;103058:15:0;;;;;;:9;:15;;;;;:105;103190:42;103208:23;103224:6;103208:15;:23::i;:::-;-1:-1:-1;;;;;103190:13:0;;;;;;:9;:13;;;;;;;:42;:17;:42;:::i;:::-;103174:9;:13;103184:2;-1:-1:-1;;;;;103174:13:0;-1:-1:-1;;;;;103174:13:0;;;;;;;;;;;;:58;;;;103271:2;-1:-1:-1;;;;;103250:56:0;103265:4;-1:-1:-1;;;;;103250:56:0;103255:8;-1:-1:-1;;;;;103250:56:0;;103275:6;103283:8;103293:12;103250:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;103250:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;103250:56:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;103250:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103337:2;-1:-1:-1;;;;;103322:26:0;103331:4;-1:-1:-1;;;;;103322:26:0;;103341:6;103322:26;;;;;;;;;;;;;;;;;;102778:578;;;;;;:::o;79561:166::-;79647:7;79683:12;79675:6;;;;79667:29;;;;-1:-1:-1;;;79667:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;79667:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;79714:5:0;;;79561:166::o;105537:716::-;105827:79;;;-1:-1:-1;;;105827:79:0;;-1:-1:-1;;;;;105827:79:0;;;;;;88207:66;105827:79;;;;;;105805:19;;87541:42;;105827:41;;:79;;;;;;;;;;;;;;;87541:42;105827:79;;;5:2:-1;;;;30:1;27;20:12;5:2;105827:79:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;105827:79:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;105827:79:0;;-1:-1:-1;;;;;;105921:25:0;;;105917:329;;105991:11;-1:-1:-1;;;;;105963:55:0;;106019:8;106029:4;106035:2;106039:6;106047:8;106057:12;105963:107;;;;;;;;;;;;;-1:-1:-1;;;;;105963:107:0;-1:-1:-1;;;;;105963:107:0;;;;;;-1:-1:-1;;;;;105963:107:0;-1:-1:-1;;;;;105963:107:0;;;;;;-1:-1:-1;;;;;105963:107:0;-1:-1:-1;;;;;105963:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;105963:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;105963:107:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;105963:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;105963:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;105963:107:0;;;;105917:329;;;106092:19;106088:158;;;106137:15;:2;-1:-1:-1;;;;;106137:13:0;;:15::i;:::-;106136:16;106128:106;;;;-1:-1:-1;;;106128:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105537:716;;;;;;;;:::o;27841:188::-;27915:12;;;;:6;:12;;;;;:33;;27940:7;27915:33;:24;:33;:::i;:::-;27911:111;;;27997:12;:10;:12::i;:::-;-1:-1:-1;;;;;27970:40:0;27988:7;-1:-1:-1;;;;;27970:40:0;27982:4;27970:40;;;;;;;;;;27841:188;;:::o;28037:192::-;28112:12;;;;:6;:12;;;;;:36;;28140:7;28112:36;:27;:36;:::i;:::-;28108:114;;;28197:12;:10;:12::i;:::-;-1:-1:-1;;;;;28170:40:0;28188:7;-1:-1:-1;;;;;28170:40:0;28182:4;28170:40;;;;;;;;;;28037:192;;:::o;100991:691::-;-1:-1:-1;;;;;101244:18:0;;101236:65;;;;-1:-1:-1;;;101236:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;101320:16:0;;101312:61;;;;;-1:-1:-1;;;101312:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101386:16;101405:12;:10;:12::i;:::-;101386:31;;101430:69;101448:8;101458:4;101464:2;101468:6;101476:8;101486:12;101430:17;:69::i;:::-;101512:57;101518:8;101528:4;101534:2;101538:6;101546:8;101556:12;101512:5;:57::i;:::-;101582:92;101602:8;101612:4;101618:2;101622:6;101630:8;101640:12;101654:19;101582;:92::i;89182:227::-;89288:7;89320:81;89108:12;89320:44;89332:31;;89320:7;:11;;:44;;;;:::i;:::-;:48;:81;:48;:81;:::i;110054:85::-;-1:-1:-1;110128:7:0;;110054:85::o;32079:269::-;32281:58;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;32281:58:0;;;;;;;32271:69;;;;;;32079:269::o;29458:761::-;29536:7;29599:9;:16;29619:2;29599:22;29595:96;;29638:41;;;-1:-1:-1;;;29638:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;29595:96;30052:4;30037:20;;30031:27;30098:4;30083:20;;30077:27;30152:4;30137:20;;30131:27;29760:9;30123:36;30189:22;30197:4;30123:36;30031:27;30077;30189:7;:22::i;:::-;30182:29;29458:761;-1:-1:-1;;;;;;29458:761:0:o;56465:164::-;56547:7;;56465:164::o;56765:167::-;56877:47;;;;;;;;;-1:-1:-1;56877:47:0;;50191:2;56885:34;;;;;56765:167::o;17267:158::-;17341:7;17392:22;17396:3;17408:5;17392:3;:22::i;16553:167::-;16633:4;16657:55;16667:3;-1:-1:-1;;;;;16687:23:0;;16657:9;:55::i;49670:139::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;49733:26:::1;:24;:26::i;:::-;49770:31;:29;:31::i;60277:129::-:0;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;60335:26:::1;:24;:26::i;:::-;60372;:24;:26::i;16806:117::-:0;16869:7;16896:19;16904:3;16896:7;:19::i;98263:2241::-;-1:-1:-1;;;;;98463:21:0;;98455:66;;;;;-1:-1:-1;;;98455:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98534:16;98553:12;:10;:12::i;:::-;98534:31;;98578:59;98599:8;98617:1;98621:7;98630:6;98578:20;:59::i;:::-;98775:6;98756:8;:15;:25;;98748:82;;;;-1:-1:-1;;;98748:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99077:37;99146:8;99121:91;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;99121:91:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:20;;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;99121:91:0;;420:4:-1;411:14;;;;99121:91:0;;;;;411:14:-1;99121:91:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;99121:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99121:91:0;;-1:-1:-1;;99516:100:0;;99074:138;;-1:-1:-1;99459:27:0;;-1:-1:-1;99459:27:0;;99121:91;99516:100;;;-1:-1:-1;99121:91:0;5:11:-1;;2:2;;;29:1;26;19:12;2:2;99516:100:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:20;;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;;;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;99516:100:0;;420:4:-1;411:14;;;;99516:100:0;;;;;411:14:-1;99516:100:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;99516:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99458:158;;;;;99665:13;:11;:13::i;:::-;99661:451;;89108:12;99700:31;:69;99661:451;;;99802:23;99828:38;99852:13;:11;:13::i;:::-;99828:19;;:38;:23;:38;:::i;:::-;99802:64;-1:-1:-1;99898:35:0;:14;99802:64;99898:35;:18;:35;:::i;:::-;99881:52;;99982:118;100086:13;:11;:13::i;:::-;99982:81;100036:26;:14;100055:6;100036:26;:18;:26;:::i;:::-;99982:31;;;:81;:53;:81;:::i;:118::-;99948:31;:152;-1:-1:-1;99661:451:0;100159:12;:29;;;100220:47;100236:30;100259:6;100236:18;100246:7;100236:9;:18::i;:::-;:22;:30;:22;:30;:::i;:::-;100220:15;:47::i;:::-;-1:-1:-1;;;;;100199:18:0;;;;;;:9;:18;;;;;:68;;;;100280:88;;100300:8;;100209:7;100331:6;100339:8;100349:12;100363:4;100280:19;:88::i;:::-;100403:7;-1:-1:-1;;;;;100386:57:0;100393:8;-1:-1:-1;;;;;100386:57:0;;100412:6;100420:8;100430:12;100386:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;100386:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100386:57:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;100386:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100459:37;;;;;;;;-1:-1:-1;;;;;100459:37:0;;;100476:1;;100459:37;;;;;;;;;98263:2241;;;;;;;;:::o;110145:781::-;110256:15;110273:12;110287:22;110311:16;110349:7;110338:57;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;110338:57:0;;;;;;;;;;;;;;;110716:11;;110338:57;;-1:-1:-1;110338:57:0;;-1:-1:-1;110338:57:0;;-1:-1:-1;110338:57:0;;-1:-1:-1;110645:22:0;;110670:85;;110685:43;;50310:6;;110685:43;:30;:43;:::i;:::-;110730:8;110740:14;110670;:85::i;:::-;110645:110;-1:-1:-1;110762:8:0;110773:64;107307:6;110773:45;110810:7;110773:32;:12;110645:110;110773:32;:16;:32;:::i;:::-;:36;:45;:36;:45;:::i;:64::-;110762:75;-1:-1:-1;110850:7:0;;110846:75;;110868:45;110874:4;110880:12;;;;;;;;;-1:-1:-1;;;;;110880:12:0;110894:3;110868:45;;;;;;;;;;;;;;;;;;;;;;;;110907:5;110868;:45::i;:::-;110145:781;;;;;;;;;;:::o;839:422::-;1206:20;1245:8;;;839:422::o;19859:65::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8962:14;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;19859:65;:::o;90007:758::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;90186:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;90210:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;90240:42:0;;::::1;::::0;:22:::1;::::0;:42:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;90298:9:0::1;90293:138;90317:22;:29:::0;90313:33;::::1;90293:138;;;90415:4;90368:17;:44;90386:22;90409:1;90386:25;;;;;;;;;::::0;;;::::1;::::0;;;;;;::::1;::::0;-1:-1:-1;;;;;90386:25:0::1;90368:44:::0;;;::::1;::::0;;;;;;;;:51;;-1:-1:-1;;90368:51:0::1;::::0;::::1;;::::0;;;::::1;::::0;;-1:-1:-1;90348:3:0::1;90293:138;;;-1:-1:-1::0;90532:24:0::1;::::0;;-1:-1:-1;;;90532:24:0;;;;;;;;::::1;::::0;;;-1:-1:-1;;;90475:97:0;;90525:4:::1;90475:97;::::0;::::1;::::0;;;;;;;;;;;;;;;;87541:42:::1;::::0;90475:41:::1;::::0;:97;;;;;-1:-1:-1;;90475:97:0;;;;;;;-1:-1:-1;87541:42:0;90475:97;::::1;;5:2:-1::0;::::1;;;30:1;27::::0;20:12:::1;5:2;90475:97:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;;90640:23:0::1;::::0;;-1:-1:-1;;;90640:23:0;;;;;;;;::::1;::::0;;;-1:-1:-1;;;90583:96:0;;90633:4:::1;90583:96;::::0;::::1;::::0;;;;;;;;;;;;;;;;87541:42:::1;::::0;-1:-1:-1;90583:41:0::1;::::0;-1:-1:-1;90583:96:0;;;;;-1:-1:-1;;90583:96:0;;;;;;;-1:-1:-1;87541:42:0;90583:96;::::1;;5:2:-1::0;::::1;;;30:1;27::::0;20:12:::1;5:2;90583:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;;89108:12:0::1;90692:31;:65:::0;-1:-1:-1;;8958:68:0;;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;90007:758;;;;:::o;53129:236::-;53191:15;53237:12;:10;:12::i;:::-;-1:-1:-1;;;;;53223:26:0;:10;-1:-1:-1;;;;;53223:26:0;;53219:139;;-1:-1:-1;53273:10:0;53266:17;;53219:139;53323:23;:21;:23::i;:::-;53316:30;;;;89417:229;89606:31;;89525:7;;89557:81;;:44;:7;89108:12;89557:44;:11;:44;:::i;77196:158::-;77254:7;77287:1;77282;:6;;77274:49;;;;;-1:-1:-1;;;77274:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77341:5:0;;;77196:158::o;76734:179::-;76792:7;76824:5;;;76848:6;;;;76840:46;;;;;-1:-1:-1;;;76840:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;15981:152;16051:4;16075:50;16080:3;-1:-1:-1;;;;;16100:23:0;;16075:4;:50::i;16309:158::-;16382:4;16406:53;16414:3;-1:-1:-1;;;;;16434:23:0;;16406:7;:53::i;77613:220::-;77671:7;77695:6;77691:20;;-1:-1:-1;77710:1:0;77703:8;;77691:20;77734:5;;;77738:1;77734;:5;:1;77758:5;;;;;:10;77750:56;;;;-1:-1:-1;;;77750:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78311:153;78369:7;78401:1;78397;:5;78389:44;;;;;-1:-1:-1;;;78389:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;78455:1;78451;:5;;;;;;;78311:153;-1:-1:-1;;;78311:153:0:o;30373:1432::-;30458:7;31383:66;31369:80;;;31361:127;;;;-1:-1:-1;;;31361:127:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31507:1;:7;;31512:2;31507:7;:18;;;;31518:1;:7;;31523:2;31518:7;31507:18;31499:65;;;;-1:-1:-1;;;31499:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31679:24;;;31662:14;31679:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31662:14;;31679:24;;;;;;;-1:-1:-1;;31679:24:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;31679:24:0;;-1:-1:-1;;31679:24:0;;;-1:-1:-1;;;;;;;31722:20:0;;31714:57;;;;;-1:-1:-1;;;31714:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;31791:6;30373:1432;-1:-1:-1;;;;;30373:1432:0:o;13933:204::-;14028:18;;14000:7;;14028:26;-1:-1:-1;14020:73:0;;;;-1:-1:-1;;;14020:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14111:3;:11;;14123:5;14111:18;;;;;;;;;;;;;;;;14104:25;;13933:204;;;;:::o;13265:129::-;13338:4;13362:19;;;:12;;;;;:19;;;;;;:24;;;13265:129::o;49817:135::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;49890:9:::1;:54:::0;;-1:-1:-1;;;;;;49890:54:0::1;49902:42;49890:54;::::0;;8958:68;;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;49817:135;:::o;60414:196::-;8670:13;;;;;;;;:33;;;8687:16;:14;:16::i;:::-;8670:50;;;-1:-1:-1;8708:12:0;;;;8707:13;8670:50;8662:109;;;;-1:-1:-1;;;8662:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8784:19;8807:13;;;;;;8806:14;8831:101;;;;8866:13;:20;;-1:-1:-1;;;;8866:20:0;;;;;8901:19;8882:4;8901:19;;;8831:101;60482:17:::1;60502:12;:10;:12::i;:::-;60525:6;:18:::0;;-1:-1:-1;;;;;;60525:18:0::1;-1:-1:-1::0;;;;;60525:18:0;::::1;::::0;;::::1;::::0;;;60559:43:::1;::::0;60525:18;;-1:-1:-1;60525:18:0;-1:-1:-1;;60559:43:0::1;::::0;-1:-1:-1;;60559:43:0::1;8944:1;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;60414:196;:::o;13480:109::-;13563:18;;13480:109::o;57096:352::-;57437:3;57416:16;;;57398:14;;;;:35;57397:43;;57096:352::o;57456:1270::-;57511:22;58329:18;58350:8;;58329:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;;;58385:8:0;58621:17;58615:24;-1:-1:-1;;;;;58611:73:0;;57456:1270;-1:-1:-1;;57456:1270:0:o;11045:414::-;11108:4;11130:21;11140:3;11145:5;11130:9;:21::i;:::-;11125:327;;-1:-1:-1;27:10;;39:1;23:18;;;45:23;;11168:11:0;:23;;;;;;;;;;;;;11351:18;;11329:19;;;:12;;;:19;;;;;;:40;;;;11384:11;;11125:327;-1:-1:-1;11435:5:0;11428:12;;11635:1544;11701:4;11840:19;;;:12;;;:19;;;;;;11876:15;;11872:1300;;12311:18;;-1:-1:-1;;12262:14:0;;;;12311:22;;;;12238:21;;12311:3;;:22;;12598;;;;;;;;;;;;;;12578:42;;12744:9;12715:3;:11;;12727:13;12715:26;;;;;;;;;;;;;;;;;;;:38;;;;12821:23;;;12863:1;12821:12;;;:23;;;;;;12847:17;;;12821:43;;12973:17;;12821:3;;12973:17;;;;;;;;;;;;;;;;;;;;;;13068:3;:12;;:19;13081:5;13068:19;;;;;;;;;;;13061:26;;;13111:4;13104:11;;;;;;;;11872:1300;13155:5;13148:12;;;;;112424:3101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;112424:3101:0;;;-1:-1:-1;112424:3101:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;112424:3101:0;-1:-1:-1;;;;;112424:3101:0;;;;;;;;;;;-1:-1:-1;112424:3101:0;;;;;;;-1:-1:-1;112424:3101:0;;;-1:-1:-1;112424:3101:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;112424:3101:0;;;;;;
Swarm Source
ipfs://6a7bb94537618b3f802a31b2ad816c9da8ee3d258f07b6c1d12ecbba8aed32b3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.