Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Initialize | 14973266 | 959 days ago | IN | 0 ETH | 0.02022488 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PToken
Compiler Version
v0.6.2+commit.bacdbe57
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-04-28 */ // 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/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: @openzeppelin/contracts-upgradeable/token/ERC777/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; /** * @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)); } /** * @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 _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 userData, bytes memory operatorData ) internal virtual { require(account != address(0), "ERC777: mint to the zero address"); address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), account, amount); // Update state variables _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true); emit Minted(operator, account, amount, userData, 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(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(amount, "ERC777: transfer amount exceeds balance"); _balances[to] = _balances[to].add(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: @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: 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; contract PToken is Initializable, AccessControlUpgradeable, ERC777Upgradeable, 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 ) external returns (bool) { mint(recipient, value, "", ""); return true; } 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"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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"}]
Contract Creation Code
608060405234801561001057600080fd5b50615497806100206000396000f3fe608060405234801561001057600080fd5b506004361061035d5760003560e01c806391d14854116101d3578063d547741f11610104578063e06e0e22116100a2578063fad8b32a1161007c578063fad8b32a14611499578063fc673c4f146114bf578063fc876754146115fd578063fe9d9303146116055761035d565b8063e06e0e22146113ba578063e900a4911461146b578063f2fde38b146114735761035d565b8063dc3ca1bf116100de578063dc3ca1bf14611202578063dcdc7dd014611228578063dd62ed3e14611366578063de7a8064146113945761035d565b8063d547741f146111a0578063d95b6371146111cc578063dab02527146111fa5761035d565b8063a9059cbb11610171578063ca15c8731161014b578063ca15c87314611043578063cbe1f06c14611060578063ce67c00314611068578063d5391393146111985761035d565b8063a9059cbb14610ec6578063ad61ccd514610ef2578063bcc33e9d14610efa5761035d565b80639a7ed350116101ad5780639a7ed35014610dba5780639bd9bbc614610de85780639bf8d82f14610ea1578063a217fddf14610ebe5761035d565b806391d1485414610d60578063959b8c3f14610d8c57806395d89b4114610db25761035d565b8063394f0231116102ad57806370a082311161024b57806380274db71161022557806380274db714610ab557806383947ea014610b595780638da5cb5b14610d355780639010d07c14610d3d5761035d565b806370a0823114610a63578063715018a614610a8957806374e861d614610a915761035d565b8063556f0dc711610287578063556f0dc7146108c657806356a1c701146108ce57806362ad1b83146108f457806369e2f0fb14610a3d5761035d565b8063394f02311461084e5780633dd1eb611461087457806340c10f191461089a5761035d565b80631e9cee741161031a57806324b76fd5116102f457806324b76fd5146107635780632f2ff15d146107d8578063313ce5671461080457806336568abe146108225761035d565b80631e9cee74146105ed57806323b872dd14610710578063248a9ca3146107465761035d565b806306e485381461036257806306fdde03146103ba578063077f224a14610437578063095ea7b31461056d578063099db017146105ad57806318160ddd146105d3575b600080fd5b61036a6116b0565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a657818101518382015260200161038e565b505050509050019250505060405180910390f35b6103c2611713565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103fc5781810151838201526020016103e4565b50505050905090810190601f1680156104295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61056b6004803603606081101561044d57600080fd5b810190602081018135600160201b81111561046757600080fd5b82018360208201111561047957600080fd5b803590602001918460018302840111600160201b8311171561049a57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104ec57600080fd5b8201836020820111156104fe57600080fd5b803590602001918460018302840111600160201b8311171561051f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b031691506117a09050565b005b6105996004803603604081101561058357600080fd5b506001600160a01b038135169060200135611879565b604080519115158252519081900360200190f35b610599600480360360208110156105c357600080fd5b50356001600160a01b031661189d565b6105db6118ca565b60408051918252519081900360200190f35b61056b600480360360a081101561060357600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561063257600080fd5b82018360208201111561064457600080fd5b803590602001918460018302840111600160201b8311171561066557600080fd5b919390929091602081019035600160201b81111561068257600080fd5b82018360208201111561069457600080fd5b803590602001918460018302840111600160201b831117156106b557600080fd5b919390929091602081019035600160201b8111156106d257600080fd5b8201836020820111156106e457600080fd5b803590602001918460018302840111600160201b8311171561070557600080fd5b5090925090506118d0565b6105996004803603606081101561072657600080fd5b506001600160a01b03813581169160208101359091169060400135611a39565b6105db6004803603602081101561075c57600080fd5b5035611bbc565b6105996004803603604081101561077957600080fd5b81359190810190604081016020820135600160201b81111561079a57600080fd5b8201836020820111156107ac57600080fd5b803590602001918460018302840111600160201b831117156107cd57600080fd5b509092509050611bd1565b61056b600480360360408110156107ee57600080fd5b50803590602001356001600160a01b0316611c2d565b61080c611c99565b6040805160ff9092168252519081900360200190f35b61056b6004803603604081101561083857600080fd5b50803590602001356001600160a01b0316611c9e565b61056b6004803603602081101561086457600080fd5b50356001600160a01b0316611cff565b61056b6004803603602081101561088a57600080fd5b50356001600160a01b0316611dc2565b610599600480360360408110156108b057600080fd5b506001600160a01b038135169060200135611def565b6105db611e1b565b61056b600480360360208110156108e457600080fd5b50356001600160a01b0316611e20565b61056b600480360360a081101561090a57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561094457600080fd5b82018360208201111561095657600080fd5b803590602001918460018302840111600160201b8311171561097757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156109c957600080fd5b8201836020820111156109db57600080fd5b803590602001918460018302840111600160201b831117156109fc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ee9945050505050565b61056b60048036036020811015610a5357600080fd5b50356001600160a01b0316611f4b565b6105db60048036036020811015610a7957600080fd5b50356001600160a01b0316611f75565b61056b611f90565b610a9961203c565b604080516001600160a01b039092168252519081900360200190f35b6105db60048036036020811015610acb57600080fd5b810190602081018135600160201b811115610ae557600080fd5b820183602082011115610af757600080fd5b803590602001918460018302840111600160201b83111715610b1857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061204b945050505050565b610cb66004803603610120811015610b7057600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610ba357600080fd5b820183602082011115610bb557600080fd5b803590602001918460018302840111600160201b83111715610bd657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929584359560208601359560408101359550606081013594509192509060a081019060800135600160201b811115610c4057600080fd5b820183602082011115610c5257600080fd5b803590602001918460018302840111600160201b83111715610c7357600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506120ad915050565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cf9578181015183820152602001610ce1565b50505050905090810190601f168015610d265780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610a9961231e565b610a9960048036036040811015610d5357600080fd5b508035906020013561232d565b61059960048036036040811015610d7657600080fd5b50803590602001356001600160a01b0316612352565b61056b60048036036020811015610da257600080fd5b50356001600160a01b0316612370565b6103c26124bc565b61056b60048036036040811015610dd057600080fd5b506001600160a01b038135811691602001351661251d565b61056b60048036036060811015610dfe57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610e2d57600080fd5b820183602082011115610e3f57600080fd5b803590602001918460018302840111600160201b83111715610e6057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506126aa945050505050565b61056b60048036036020811015610eb757600080fd5b50356126cf565b6105db612736565b61059960048036036040811015610edc57600080fd5b506001600160a01b03813516906020013561273b565b6103c2612814565b61056b600480360360a0811015610f1057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610f4a57600080fd5b820183602082011115610f5c57600080fd5b803590602001918460018302840111600160201b83111715610f7d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610fcf57600080fd5b820183602082011115610fe157600080fd5b803590602001918460018302840111600160201b8311171561100257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612833945050505050565b6105db6004803603602081101561105957600080fd5b50356128f7565b6105db61290e565b61056b6004803603606081101561107e57600080fd5b81359190810190604081016020820135600160201b81111561109f57600080fd5b8201836020820111156110b157600080fd5b803590602001918460018302840111600160201b831117156110d257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561112457600080fd5b82018360208201111561113657600080fd5b803590602001918460018302840111600160201b8311171561115757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612914945050505050565b6105db612a54565b61056b600480360360408110156111b657600080fd5b50803590602001356001600160a01b0316612a77565b610599600480360360408110156111e257600080fd5b506001600160a01b0381358116916020013516612ad0565b610a99612b71565b61056b6004803603602081101561121857600080fd5b50356001600160a01b0316612b80565b6105996004803603608081101561123e57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561126d57600080fd5b82018360208201111561127f57600080fd5b803590602001918460018302840111600160201b831117156112a057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156112f257600080fd5b82018360208201111561130457600080fd5b803590602001918460018302840111600160201b8311171561132557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612c5f945050505050565b6105db6004803603604081101561137c57600080fd5b506001600160a01b0381358116916020013516612d2b565b61056b600480360360208110156113aa57600080fd5b50356001600160a01b0316612d56565b61056b600480360360808110156113d057600080fd5b810190602081018135600160201b8111156113ea57600080fd5b8201836020820111156113fc57600080fd5b803590602001918460018302840111600160201b8311171561141d57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050505080351515915060208101359060400135612e13565b610a99612e76565b61056b6004803603602081101561148957600080fd5b50356001600160a01b0316612e85565b61056b600480360360208110156114af57600080fd5b50356001600160a01b0316612f88565b61056b600480360360808110156114d557600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561150457600080fd5b82018360208201111561151657600080fd5b803590602001918460018302840111600160201b8311171561153757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561158957600080fd5b82018360208201111561159b57600080fd5b803590602001918460018302840111600160201b831117156115bc57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506130d4945050505050565b610a9961312c565b61056b6004803603604081101561161b57600080fd5b81359190810190604081016020820135600160201b81111561163c57600080fd5b82018360208201111561164e57600080fd5b803590602001918460018302840111600160201b8311171561166f57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061313b945050505050565b606060cd80548060200260200160405190810160405280929190818152602001828054801561170857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116116ea575b505050505090505b90565b60cb8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156117085780601f1061177457610100808354040283529160200191611708565b820191906000526020600020905b81548152906001019060200180831161178257509395945050505050565b600054610100900460ff16806117b957506117b961315d565b806117c7575060005460ff16155b6118025760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff1615801561182d576000805460ff1961ff0019909116610100171660011790555b606061183761316e565b61184285858361321f565b61184c838461251d565b61185583612d56565b611860600084611c8b565b508015611873576000805461ff00191690555b50505050565b6000806118846132d6565b90506118918185856132e5565b60019150505b92915050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b0190206000906118979083612352565b60ca5490565b6118e16118db6132d6565b89612ad0565b61191c5760405162461bcd60e51b815260040180806020018281038252602c815260200180615372602c913960400191505060405180910390fd5b611991888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506133d192505050565b876001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad688884848a8a6040518086815260200180602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f1916909201829003995090975050505050505050a25050505050505050565b60006001600160a01b038316611a805760405162461bcd60e51b815260040180806020018281038252602481526020018061532a6024913960400191505060405180910390fd5b6001600160a01b038416611ac55760405162461bcd60e51b81526004018080602001828103825260268152602001806153c76026913960400191505060405180910390fd5b6000611acf6132d6565b9050611afd818686866040518060200160405280600081525060405180602001604052806000815250613617565b611b2981868686604051806020016040528060008152506040518060200160405280600081525061385f565b611b838582611b7e8660405180606001604052806029815260200161539e602991396001600160a01b03808c16600090815260d160209081526040808320938b1683529290522054919063ffffffff613a8516565b6132e5565b611bb18186868660405180602001604052806000815250604051806020016040528060008152506000613b1c565b506001949350505050565b60009081526033602052604090206002015490565b6000611c23846040518060200160405280600081525085858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061291492505050565b5060019392505050565b600082815260336020526040902060020154611c5090611c4b6132d6565b612352565b611c8b5760405162461bcd60e51b815260040180806020018281038252602f815260200180615079602f913960400191505060405180910390fd5b611c958282613dbc565b5050565b601290565b611ca66132d6565b6001600160a01b0316816001600160a01b031614611cf55760405162461bcd60e51b815260040180806020018281038252602f815260200180615433602f913960400191505060405180910390fd5b611c958282613e2b565b60fe546001600160a01b0316611d136132d6565b6001600160a01b031614611d585760405162461bcd60e51b81526004018080602001828103825260358152602001806152886035913960400191505060405180910390fd5b60fe54604080516001600160a01b039283168152918316602083015280517fe8fdc5340d9288e129a7c6af86dc4002f708091280d69f89583f7e6349c0a8d69281900390910190a160fe80546001600160a01b0319166001600160a01b0392909216919091179055565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dec9082611c2d565b50565b6000611c2383836040518060200160405280600081525060405180602001604052806000815250612c5f565b600190565b611e286132d6565b6001600160a01b0316611e3961231e565b6001600160a01b031614611e82576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6001600160a01b038116611ec75760405162461bcd60e51b815260040180806020018281038252602281526020018061513c6022913960400191505060405180910390fd5b60fb80546001600160a01b0319166001600160a01b0392909216919091179055565b611efa611ef46132d6565b86612ad0565b611f355760405162461bcd60e51b815260040180806020018281038252602c815260200180615372602c913960400191505060405180910390fd5b611f4485858585856001613e9a565b5050505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dec9082612a77565b6001600160a01b0316600090815260c9602052604090205490565b611f986132d6565b6001600160a01b0316611fa961231e565b6001600160a01b031614611ff2576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b6097546001600160a01b031690565b600061205561203c565b6001600160a01b0316336001600160a01b0316146120a45760405162461bcd60e51b815260040180806020018281038252602481526020018061534e6024913960400191505060405180910390fd5b61189782613f71565b60006060600060608580602001905160408110156120ca57600080fd5b815160208301805160405192949293830192919084600160201b8211156120f057600080fd5b90830190602082018581111561210557600080fd5b8251600160201b81118282018810171561211e57600080fd5b82525081516020918201929091019080838360005b8381101561214b578181015183820152602001612133565b50505050905090810190601f1680156121785780820380516001836020036101000a031916815260200191505b50604052505050915091506060828e8e8e8e8e8e8e61219561203c565b30604051602001808b81526020018a6001600160a01b03166001600160a01b031660601b8152601401896001600160a01b03166001600160a01b031660601b815260140188805190602001908083835b602083106122045780518252601f1990920191602091820191016121e5565b51815160209384036101000a6000190180199092169116179052920198895250878101969096525060408087019490945260608087019390935290821b6bffffffffffffffffffffffff199081166080870152911b1660948401528051808403608801815260a8909301905260fb548251918301919091209196506001600160a01b031694506122a8935086925061229c9150613f77565b9063ffffffff613fc816565b6001600160a01b031614156123065760408051602081018590526001600160a01b038f1681830152606081018d905260808082018d90528251808303909101815260a09091019091526122fa90614048565b94509450505050612310565b6122fa600061404d565b995099975050505050505050565b6065546001600160a01b031690565b600082815260336020526040812061234b908363ffffffff61406516565b9392505050565b600082815260336020526040812061234b908363ffffffff61407116565b806001600160a01b03166123826132d6565b6001600160a01b031614156123c85760405162461bcd60e51b81526004018080602001828103825260248152602001806151806024913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff161561242b5760d060006123f56132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff19169055612472565b600160cf60006124396132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b61247a6132d6565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60cc8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156117085780601f1061177457610100808354040283529160200191611708565b600054610100900460ff1680612536575061253661315d565b80612544575060005460ff16155b61257f5760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156125aa576000805460ff1961ff0019909116610100171660011790555b6125b2614086565b6125ba614123565b6001600160a01b0383166125ff5760405162461bcd60e51b815260040180806020018281038252602281526020018061513c6022913960400191505060405180910390fd5b60fb80546001600160a01b0319166001600160a01b03858116919091179091558216612672576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fc80546001600160a01b0319166001600160a01b038416179055619c4060fd5580156126a5576000805461ff00191690555b505050565b6126a56126b56132d6565b848484604051806020016040528060008152506001613e9a565b6126d76132d6565b6001600160a01b03166126e861231e565b6001600160a01b031614612731576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b60fd55565b600081565b60006001600160a01b0383166127825760405162461bcd60e51b815260040180806020018281038252602481526020018061532a6024913960400191505060405180910390fd5b600061278c6132d6565b90506127ba818286866040518060200160405280600081525060405180602001604052806000815250613617565b6127e681828686604051806020016040528060008152506040518060200160405280600081525061385f565b6118918182868660405180602001604052806000815250604051806020016040528060008152506000613b1c565b6040805180820190915260058152640312e302e360dc1b602082015290565b60fe546001600160a01b03166128476132d6565b6001600160a01b0316146128a2576040805162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74207468652061646d696e206f70657261746f72604482015290519081900360640190fd5b6128b185858585856000613e9a565b60fe54604080516001600160a01b039092168252517fb22a57ba0314fafe219dc14abcf1f22e86e6e82d599c0c31177a2d7c2e1b17e19181900360200190a15050505050565b6000818152603360205260408120611897906141c0565b60fd5481565b61293661291f6132d6565b8484604051806020016040528060008152506133d1565b61293e6132d6565b6001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad68848385604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156129b257818101518382015260200161299a565b50505050905090810190601f1680156129df5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015612a125781810151838201526020016129fa565b50505050905090810190601f168015612a3f5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b01902081565b600082815260336020526040902060020154612a9590611c4b6132d6565b611cf55760405162461bcd60e51b81526004018080602001828103825260308152602001806151c66030913960400191505060405180910390fd5b6000816001600160a01b0316836001600160a01b03161480612b3b57506001600160a01b038316600090815260ce602052604090205460ff168015612b3b57506001600160a01b03808316600090815260d0602090815260408083209387168352929052205460ff16155b8061234b5750506001600160a01b03908116600090815260cf602090815260408083209490931682529290925290205460ff1690565b60fc546001600160a01b031681565b612b886132d6565b6001600160a01b0316612b9961231e565b6001600160a01b031614612be2576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6001600160a01b038116612c3d576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fc80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038516301415612ca95760405162461bcd60e51b815260040180806020018281038252602f81526020018061504a602f913960400191505060405180910390fd5b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020612cd590611c4b6132d6565b612d1f576040805162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b4b73a32b960511b604482015290519081900360640190fd5b611bb1858585856141cb565b6001600160a01b03918216600090815260d16020908152604080832093909416825291909152205490565b600054610100900460ff1680612d6f5750612d6f61315d565b80612d7d575060005460ff16155b612db85760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015612de3576000805460ff1961ff0019909116610100171660011790555b60fe80546001600160a01b0319166001600160a01b0384161790558015611c95576000805461ff00191690555050565b612e1b61203c565b6001600160a01b0316336001600160a01b031614612e6a5760405162461bcd60e51b815260040180806020018281038252602481526020018061534e6024913960400191505060405180910390fd5b6118738484848461440f565b60fe546001600160a01b031681565b612e8d6132d6565b6001600160a01b0316612e9e61231e565b6001600160a01b031614612ee7576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6001600160a01b038116612f2c5760405162461bcd60e51b81526004018080602001828103825260268152602001806151166026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b612f906132d6565b6001600160a01b0316816001600160a01b03161415612fe05760405162461bcd60e51b81526004018080602001828103825260218152602001806151f66021913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff161561304c57600160d0600061300f6132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff191691151591909117905561308a565b60cf60006130586132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b6130926132d6565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b6130e56130df6132d6565b85612ad0565b6131205760405162461bcd60e51b815260040180806020018281038252602c815260200180615372602c913960400191505060405180910390fd5b611873848484846133d1565b60fb546001600160a01b031681565b611c956131466132d6565b8383604051806020016040528060008152506133d1565b600061316830614500565b15905090565b600054610100900460ff1680613187575061318761315d565b80613195575060005460ff16155b6131d05760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156131fb576000805460ff1961ff0019909116610100171660011790555b613203614506565b61320b614506565b8015611dec576000805461ff001916905550565b600054610100900460ff1680613238575061323861315d565b80613246575060005460ff16155b6132815760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156132ac576000805460ff1961ff0019909116610100171660011790555b6132b4614506565b6132bf8484846145a6565b8015611873576000805461ff001916905550505050565b60006132e061480c565b905090565b6001600160a01b03831661332a5760405162461bcd60e51b81526004018080602001828103825260258152602001806150a86025913960400191505060405180910390fd5b6001600160a01b03821661336f5760405162461bcd60e51b81526004018080602001828103825260238152602001806154106023913960400191505060405180910390fd5b6001600160a01b03808416600081815260d16020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0384166134165760405162461bcd60e51b815260040180806020018281038252602281526020018061515e6022913960400191505060405180910390fd5b60006134206132d6565b905061343181866000878787613617565b61343e8186600087611873565b613481846040518060600160405280602381526020016153ed602391396001600160a01b038816600090815260c96020526040902054919063ffffffff613a8516565b6001600160a01b038616600090815260c9602052604090205560ca546134ad908563ffffffff61484416565b60ca81905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561353257818101518382015260200161351a565b50505050905090810190601f16801561355f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561359257818101518382015260200161357a565b50505050905090810190601f1680156135bf5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516000916001600160a01b038816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b6040805163555ddc6560e11b81526001600160a01b03871660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89560248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b15801561369b57600080fd5b505afa1580156136af573d6000803e3d6000fd5b505050506040513d60208110156136c557600080fd5b505190506001600160a01b0381161561385657806001600160a01b03166375ab97828888888888886040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561378b578181015183820152602001613773565b50505050905090810190601f1680156137b85780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156137eb5781810151838201526020016137d3565b50505050905090810190601f1680156138185780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561383d57600080fd5b505af1158015613851573d6000803e3d6000fd5b505050505b50505050505050565b61386b86868686611873565b6138ae836040518060600160405280602781526020016150ef602791396001600160a01b038816600090815260c96020526040902054919063ffffffff613a8516565b6001600160a01b03808716600090815260c9602052604080822093909355908616815220546138e3908463ffffffff6148a116565b60c96000866001600160a01b03166001600160a01b0316815260200190815260200160002081905550836001600160a01b0316856001600160a01b0316876001600160a01b03167f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561399557818101518382015260200161397d565b50505050905090810190601f1680156139c25780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156139f55781810151838201526020016139dd565b50505050905090810190601f168015613a225780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3505050505050565b60008184841115613b145760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ad9578181015183820152602001613ac1565b50505050905090810190601f168015613b065780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6040805163555ddc6560e11b81526001600160a01b03871660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b158015613ba057600080fd5b505afa158015613bb4573d6000803e3d6000fd5b505050506040513d6020811015613bca57600080fd5b505190506001600160a01b03811615613d5e57806001600160a01b03166223de298989898989896040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015613c8f578181015183820152602001613c77565b50505050905090810190601f168015613cbc5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015613cef578181015183820152602001613cd7565b50505050905090810190601f168015613d1c5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015613d4157600080fd5b505af1158015613d55573d6000803e3d6000fd5b50505050613db2565b8115613db257613d76866001600160a01b0316614500565b15613db25760405162461bcd60e51b815260040180806020018281038252604d8152602001806152dd604d913960600191505060405180910390fd5b5050505050505050565b6000828152603360205260409020613dda908263ffffffff6148fb16565b15611c9557613de76132d6565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020613e49908263ffffffff61491016565b15611c9557613e566132d6565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038616613edf5760405162461bcd60e51b81526004018080602001828103825260228152602001806150cd6022913960400191505060405180910390fd5b6001600160a01b038516613f3a576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6000613f446132d6565b9050613f54818888888888613617565b613f6281888888888861385f565b61385681888888888888613b1c565b50600090565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114614020576040805162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015290519081900360640190fd5b60208201516040830151606084015160001a61403e86828585614925565b9695505050505050565b600091565b604080516020810190915260008152600b9190910191565b600061234b8383614a9f565b600061234b836001600160a01b038416614b03565b600054610100900460ff168061409f575061409f61315d565b806140ad575060005460ff16155b6140e85760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614113576000805460ff1961ff0019909116610100171660011790555b61411b614506565b61320b614b1b565b600054610100900460ff168061413c575061413c61315d565b8061414a575060005460ff16155b6141855760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156141b0576000805460ff1961ff0019909116610100171660011790555b6141b8614506565b61320b614be2565b600061189782614cdb565b6001600160a01b038416614226576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b60006142306132d6565b905061423f8160008787611873565b60ca54614252908563ffffffff6148a116565b60ca556001600160a01b038516600090815260c9602052604090205461427e908563ffffffff6148a116565b6001600160a01b038616600090815260c960205260408120919091556142ab908290878787876001613b1c565b846001600160a01b0316816001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561432a578181015183820152602001614312565b50505050905090810190601f1680156143575780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561438a578181015183820152602001614372565b50505050905090810190601f1680156143b75780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516001600160a01b038716916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b60008060008087806020019051608081101561442a57600080fd5b5080516020820151604083015160609093015160fd5492975090955091935090915060009061446e9061446790620186a09063ffffffff61484416565b8385614cdf565b905060006144aa670de0b6b3a764000061449e886144928c8763ffffffff61484416565b9063ffffffff614ced16565b9063ffffffff614d4616565b905080156144f4576144f48560fc60009054906101000a90046001600160a01b03168360405180602001604052806000815250604051806020016040528060008152506000613e9a565b50505050505050505050565b3b151590565b600054610100900460ff168061451f575061451f61315d565b8061452d575060005460ff16155b6145685760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff1615801561320b576000805460ff1961ff0019909116610100171660011790558015611dec576000805461ff001916905550565b600054610100900460ff16806145bf57506145bf61315d565b806145cd575060005460ff16155b6146085760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614633576000805460ff1961ff0019909116610100171660011790555b83516146469060cb906020870190614f0a565b50825161465a9060cc906020860190614f0a565b50815161466e9060cd906020850190614f88565b5060005b60cd548110156146cb57600160ce600060cd848154811061468f57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff1916911515919091179055600101614672565b50604080516a22a9219b9b9baa37b5b2b760a91b8152815190819003600b0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad24916329965a1d91606480830192600092919082900301818387803b15801561474957600080fd5b505af115801561475d573d6000803e3d6000fd5b5050604080516922a92199182a37b5b2b760b11b8152815190819003600a0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad2493506329965a1d9250606480830192600092919082900301818387803b1580156147dd57600080fd5b505af11580156147f1573d6000803e3d6000fd5b505050508015611873576000805461ff001916905550505050565b600061481661203c565b6001600160a01b0316336001600160a01b031614614835575033611710565b61483d614dad565b9050611710565b60008282111561489b576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60008282018381101561234b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600061234b836001600160a01b038416614dfa565b600061234b836001600160a01b038416614e44565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156149865760405162461bcd60e51b81526004018080602001828103825260228152602001806151a46022913960400191505060405180910390fd5b8360ff16601b148061499b57508360ff16601c145b6149d65760405162461bcd60e51b81526004018080602001828103825260228152602001806152456022913960400191505060405180910390fd5b604080516000808252602080830180855289905260ff88168385015260608301879052608083018690529251909260019260a080820193601f1981019281900390910190855afa158015614a2e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116614a96576040805162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b81546000908210614ae15760405162461bcd60e51b81526004018080602001828103825260228152602001806150286022913960400191505060405180910390fd5b826000018281548110614af057fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600054610100900460ff1680614b345750614b3461315d565b80614b42575060005460ff16155b614b7d5760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614ba8576000805460ff1961ff0019909116610100171660011790555b609780546001600160a01b03191673d216153c06e857cd7f72665e0af1d7d82172f4941790558015611dec576000805461ff001916905550565b600054610100900460ff1680614bfb5750614bfb61315d565b80614c09575060005460ff16155b614c445760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614c6f576000805460ff1961ff0019909116610100171660011790555b6000614c796132d6565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015611dec576000805461ff001916905550565b5490565b606490810191909202020490565b600082614cfc57506000611897565b82820282848281614d0957fe5b041461234b5760405162461bcd60e51b81526004018080602001828103825260218152602001806152676021913960400191505060405180910390fd5b6000808211614d9c576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381614da557fe5b049392505050565b600060606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031692915050565b6000614e068383614b03565b614e3c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611897565b506000611897565b60008181526001830160205260408120548015614f005783546000198083019190810190600090879083908110614e7757fe5b9060005260206000200154905080876000018481548110614e9457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080614ec457fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611897565b6000915050611897565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614f4b57805160ff1916838001178555614f78565b82800160010185558215614f78579182015b82811115614f78578251825591602001919060010190614f5d565b50614f84929150614fe9565b5090565b828054828255906000526020600020908101928215614fdd579160200282015b82811115614fdd57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614fa8565b50614f84929150615003565b61171091905b80821115614f845760008155600101614fef565b61171091905b80821115614f845780546001600160a01b031916815560010161500956fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473526563697069656e742063616e6e6f742062652074686520746f6b656e20636f6e7472616374206164647265737321416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433737373a20617070726f76652066726f6d20746865207a65726f20616464726573734552433737373a2073656e642066726f6d20746865207a65726f20616464726573734552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737374727573746564207369676e657220697320746865207a65726f20616464726573734552433737373a206275726e2066726f6d20746865207a65726f20616464726573734552433737373a20617574686f72697a696e672073656c66206173206f70657261746f7245434453413a20696e76616c6964207369676e6174757265202773272076616c7565416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433737373a207265766f6b696e672073656c66206173206f70657261746f72496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445434453413a20696e76616c6964207369676e6174757265202776272076616c7565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f6e6c79207468652061637475616c2061646d696e206f70657261746f722063616e206368616e67652074686520616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433737373a20746f6b656e20726563697069656e7420636f6e747261637420686173206e6f20696d706c656d656e74657220666f7220455243373737546f6b656e73526563697069656e744552433737373a207472616e7366657220746f20746865207a65726f206164647265737347534e526563697069656e743a2063616c6c6572206973206e6f742052656c61794875624552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f7220666f7220686f6c6465724552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a207472616e736665722066726f6d20746865207a65726f20616464726573734552433737373a206275726e20616d6f756e7420657863656564732062616c616e63654552433737373a20617070726f766520746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212203ab221eea8be0979f07c3acaf98ba16c46c60dad02b2212897924a0e4d0cc0ac64736f6c63430006020033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061035d5760003560e01c806391d14854116101d3578063d547741f11610104578063e06e0e22116100a2578063fad8b32a1161007c578063fad8b32a14611499578063fc673c4f146114bf578063fc876754146115fd578063fe9d9303146116055761035d565b8063e06e0e22146113ba578063e900a4911461146b578063f2fde38b146114735761035d565b8063dc3ca1bf116100de578063dc3ca1bf14611202578063dcdc7dd014611228578063dd62ed3e14611366578063de7a8064146113945761035d565b8063d547741f146111a0578063d95b6371146111cc578063dab02527146111fa5761035d565b8063a9059cbb11610171578063ca15c8731161014b578063ca15c87314611043578063cbe1f06c14611060578063ce67c00314611068578063d5391393146111985761035d565b8063a9059cbb14610ec6578063ad61ccd514610ef2578063bcc33e9d14610efa5761035d565b80639a7ed350116101ad5780639a7ed35014610dba5780639bd9bbc614610de85780639bf8d82f14610ea1578063a217fddf14610ebe5761035d565b806391d1485414610d60578063959b8c3f14610d8c57806395d89b4114610db25761035d565b8063394f0231116102ad57806370a082311161024b57806380274db71161022557806380274db714610ab557806383947ea014610b595780638da5cb5b14610d355780639010d07c14610d3d5761035d565b806370a0823114610a63578063715018a614610a8957806374e861d614610a915761035d565b8063556f0dc711610287578063556f0dc7146108c657806356a1c701146108ce57806362ad1b83146108f457806369e2f0fb14610a3d5761035d565b8063394f02311461084e5780633dd1eb611461087457806340c10f191461089a5761035d565b80631e9cee741161031a57806324b76fd5116102f457806324b76fd5146107635780632f2ff15d146107d8578063313ce5671461080457806336568abe146108225761035d565b80631e9cee74146105ed57806323b872dd14610710578063248a9ca3146107465761035d565b806306e485381461036257806306fdde03146103ba578063077f224a14610437578063095ea7b31461056d578063099db017146105ad57806318160ddd146105d3575b600080fd5b61036a6116b0565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103a657818101518382015260200161038e565b505050509050019250505060405180910390f35b6103c2611713565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103fc5781810151838201526020016103e4565b50505050905090810190601f1680156104295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61056b6004803603606081101561044d57600080fd5b810190602081018135600160201b81111561046757600080fd5b82018360208201111561047957600080fd5b803590602001918460018302840111600160201b8311171561049a57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156104ec57600080fd5b8201836020820111156104fe57600080fd5b803590602001918460018302840111600160201b8311171561051f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b031691506117a09050565b005b6105996004803603604081101561058357600080fd5b506001600160a01b038135169060200135611879565b604080519115158252519081900360200190f35b610599600480360360208110156105c357600080fd5b50356001600160a01b031661189d565b6105db6118ca565b60408051918252519081900360200190f35b61056b600480360360a081101561060357600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561063257600080fd5b82018360208201111561064457600080fd5b803590602001918460018302840111600160201b8311171561066557600080fd5b919390929091602081019035600160201b81111561068257600080fd5b82018360208201111561069457600080fd5b803590602001918460018302840111600160201b831117156106b557600080fd5b919390929091602081019035600160201b8111156106d257600080fd5b8201836020820111156106e457600080fd5b803590602001918460018302840111600160201b8311171561070557600080fd5b5090925090506118d0565b6105996004803603606081101561072657600080fd5b506001600160a01b03813581169160208101359091169060400135611a39565b6105db6004803603602081101561075c57600080fd5b5035611bbc565b6105996004803603604081101561077957600080fd5b81359190810190604081016020820135600160201b81111561079a57600080fd5b8201836020820111156107ac57600080fd5b803590602001918460018302840111600160201b831117156107cd57600080fd5b509092509050611bd1565b61056b600480360360408110156107ee57600080fd5b50803590602001356001600160a01b0316611c2d565b61080c611c99565b6040805160ff9092168252519081900360200190f35b61056b6004803603604081101561083857600080fd5b50803590602001356001600160a01b0316611c9e565b61056b6004803603602081101561086457600080fd5b50356001600160a01b0316611cff565b61056b6004803603602081101561088a57600080fd5b50356001600160a01b0316611dc2565b610599600480360360408110156108b057600080fd5b506001600160a01b038135169060200135611def565b6105db611e1b565b61056b600480360360208110156108e457600080fd5b50356001600160a01b0316611e20565b61056b600480360360a081101561090a57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561094457600080fd5b82018360208201111561095657600080fd5b803590602001918460018302840111600160201b8311171561097757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156109c957600080fd5b8201836020820111156109db57600080fd5b803590602001918460018302840111600160201b831117156109fc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ee9945050505050565b61056b60048036036020811015610a5357600080fd5b50356001600160a01b0316611f4b565b6105db60048036036020811015610a7957600080fd5b50356001600160a01b0316611f75565b61056b611f90565b610a9961203c565b604080516001600160a01b039092168252519081900360200190f35b6105db60048036036020811015610acb57600080fd5b810190602081018135600160201b811115610ae557600080fd5b820183602082011115610af757600080fd5b803590602001918460018302840111600160201b83111715610b1857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061204b945050505050565b610cb66004803603610120811015610b7057600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610ba357600080fd5b820183602082011115610bb557600080fd5b803590602001918460018302840111600160201b83111715610bd657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929584359560208601359560408101359550606081013594509192509060a081019060800135600160201b811115610c4057600080fd5b820183602082011115610c5257600080fd5b803590602001918460018302840111600160201b83111715610c7357600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506120ad915050565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cf9578181015183820152602001610ce1565b50505050905090810190601f168015610d265780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610a9961231e565b610a9960048036036040811015610d5357600080fd5b508035906020013561232d565b61059960048036036040811015610d7657600080fd5b50803590602001356001600160a01b0316612352565b61056b60048036036020811015610da257600080fd5b50356001600160a01b0316612370565b6103c26124bc565b61056b60048036036040811015610dd057600080fd5b506001600160a01b038135811691602001351661251d565b61056b60048036036060811015610dfe57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610e2d57600080fd5b820183602082011115610e3f57600080fd5b803590602001918460018302840111600160201b83111715610e6057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506126aa945050505050565b61056b60048036036020811015610eb757600080fd5b50356126cf565b6105db612736565b61059960048036036040811015610edc57600080fd5b506001600160a01b03813516906020013561273b565b6103c2612814565b61056b600480360360a0811015610f1057600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610f4a57600080fd5b820183602082011115610f5c57600080fd5b803590602001918460018302840111600160201b83111715610f7d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610fcf57600080fd5b820183602082011115610fe157600080fd5b803590602001918460018302840111600160201b8311171561100257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612833945050505050565b6105db6004803603602081101561105957600080fd5b50356128f7565b6105db61290e565b61056b6004803603606081101561107e57600080fd5b81359190810190604081016020820135600160201b81111561109f57600080fd5b8201836020820111156110b157600080fd5b803590602001918460018302840111600160201b831117156110d257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561112457600080fd5b82018360208201111561113657600080fd5b803590602001918460018302840111600160201b8311171561115757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612914945050505050565b6105db612a54565b61056b600480360360408110156111b657600080fd5b50803590602001356001600160a01b0316612a77565b610599600480360360408110156111e257600080fd5b506001600160a01b0381358116916020013516612ad0565b610a99612b71565b61056b6004803603602081101561121857600080fd5b50356001600160a01b0316612b80565b6105996004803603608081101561123e57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561126d57600080fd5b82018360208201111561127f57600080fd5b803590602001918460018302840111600160201b831117156112a057600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b8111156112f257600080fd5b82018360208201111561130457600080fd5b803590602001918460018302840111600160201b8311171561132557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612c5f945050505050565b6105db6004803603604081101561137c57600080fd5b506001600160a01b0381358116916020013516612d2b565b61056b600480360360208110156113aa57600080fd5b50356001600160a01b0316612d56565b61056b600480360360808110156113d057600080fd5b810190602081018135600160201b8111156113ea57600080fd5b8201836020820111156113fc57600080fd5b803590602001918460018302840111600160201b8311171561141d57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050505080351515915060208101359060400135612e13565b610a99612e76565b61056b6004803603602081101561148957600080fd5b50356001600160a01b0316612e85565b61056b600480360360208110156114af57600080fd5b50356001600160a01b0316612f88565b61056b600480360360808110156114d557600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561150457600080fd5b82018360208201111561151657600080fd5b803590602001918460018302840111600160201b8311171561153757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561158957600080fd5b82018360208201111561159b57600080fd5b803590602001918460018302840111600160201b831117156115bc57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506130d4945050505050565b610a9961312c565b61056b6004803603604081101561161b57600080fd5b81359190810190604081016020820135600160201b81111561163c57600080fd5b82018360208201111561164e57600080fd5b803590602001918460018302840111600160201b8311171561166f57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061313b945050505050565b606060cd80548060200260200160405190810160405280929190818152602001828054801561170857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116116ea575b505050505090505b90565b60cb8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156117085780601f1061177457610100808354040283529160200191611708565b820191906000526020600020905b81548152906001019060200180831161178257509395945050505050565b600054610100900460ff16806117b957506117b961315d565b806117c7575060005460ff16155b6118025760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff1615801561182d576000805460ff1961ff0019909116610100171660011790555b606061183761316e565b61184285858361321f565b61184c838461251d565b61185583612d56565b611860600084611c8b565b508015611873576000805461ff00191690555b50505050565b6000806118846132d6565b90506118918185856132e5565b60019150505b92915050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b0190206000906118979083612352565b60ca5490565b6118e16118db6132d6565b89612ad0565b61191c5760405162461bcd60e51b815260040180806020018281038252602c815260200180615372602c913960400191505060405180910390fd5b611991888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a91508990819084018382808284376000920191909152506133d192505050565b876001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad688884848a8a6040518086815260200180602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f1916909201829003995090975050505050505050a25050505050505050565b60006001600160a01b038316611a805760405162461bcd60e51b815260040180806020018281038252602481526020018061532a6024913960400191505060405180910390fd5b6001600160a01b038416611ac55760405162461bcd60e51b81526004018080602001828103825260268152602001806153c76026913960400191505060405180910390fd5b6000611acf6132d6565b9050611afd818686866040518060200160405280600081525060405180602001604052806000815250613617565b611b2981868686604051806020016040528060008152506040518060200160405280600081525061385f565b611b838582611b7e8660405180606001604052806029815260200161539e602991396001600160a01b03808c16600090815260d160209081526040808320938b1683529290522054919063ffffffff613a8516565b6132e5565b611bb18186868660405180602001604052806000815250604051806020016040528060008152506000613b1c565b506001949350505050565b60009081526033602052604090206002015490565b6000611c23846040518060200160405280600081525085858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061291492505050565b5060019392505050565b600082815260336020526040902060020154611c5090611c4b6132d6565b612352565b611c8b5760405162461bcd60e51b815260040180806020018281038252602f815260200180615079602f913960400191505060405180910390fd5b611c958282613dbc565b5050565b601290565b611ca66132d6565b6001600160a01b0316816001600160a01b031614611cf55760405162461bcd60e51b815260040180806020018281038252602f815260200180615433602f913960400191505060405180910390fd5b611c958282613e2b565b60fe546001600160a01b0316611d136132d6565b6001600160a01b031614611d585760405162461bcd60e51b81526004018080602001828103825260358152602001806152886035913960400191505060405180910390fd5b60fe54604080516001600160a01b039283168152918316602083015280517fe8fdc5340d9288e129a7c6af86dc4002f708091280d69f89583f7e6349c0a8d69281900390910190a160fe80546001600160a01b0319166001600160a01b0392909216919091179055565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dec9082611c2d565b50565b6000611c2383836040518060200160405280600081525060405180602001604052806000815250612c5f565b600190565b611e286132d6565b6001600160a01b0316611e3961231e565b6001600160a01b031614611e82576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6001600160a01b038116611ec75760405162461bcd60e51b815260040180806020018281038252602281526020018061513c6022913960400191505060405180910390fd5b60fb80546001600160a01b0319166001600160a01b0392909216919091179055565b611efa611ef46132d6565b86612ad0565b611f355760405162461bcd60e51b815260040180806020018281038252602c815260200180615372602c913960400191505060405180910390fd5b611f4485858585856001613e9a565b5050505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020611dec9082612a77565b6001600160a01b0316600090815260c9602052604090205490565b611f986132d6565b6001600160a01b0316611fa961231e565b6001600160a01b031614611ff2576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b6097546001600160a01b031690565b600061205561203c565b6001600160a01b0316336001600160a01b0316146120a45760405162461bcd60e51b815260040180806020018281038252602481526020018061534e6024913960400191505060405180910390fd5b61189782613f71565b60006060600060608580602001905160408110156120ca57600080fd5b815160208301805160405192949293830192919084600160201b8211156120f057600080fd5b90830190602082018581111561210557600080fd5b8251600160201b81118282018810171561211e57600080fd5b82525081516020918201929091019080838360005b8381101561214b578181015183820152602001612133565b50505050905090810190601f1680156121785780820380516001836020036101000a031916815260200191505b50604052505050915091506060828e8e8e8e8e8e8e61219561203c565b30604051602001808b81526020018a6001600160a01b03166001600160a01b031660601b8152601401896001600160a01b03166001600160a01b031660601b815260140188805190602001908083835b602083106122045780518252601f1990920191602091820191016121e5565b51815160209384036101000a6000190180199092169116179052920198895250878101969096525060408087019490945260608087019390935290821b6bffffffffffffffffffffffff199081166080870152911b1660948401528051808403608801815260a8909301905260fb548251918301919091209196506001600160a01b031694506122a8935086925061229c9150613f77565b9063ffffffff613fc816565b6001600160a01b031614156123065760408051602081018590526001600160a01b038f1681830152606081018d905260808082018d90528251808303909101815260a09091019091526122fa90614048565b94509450505050612310565b6122fa600061404d565b995099975050505050505050565b6065546001600160a01b031690565b600082815260336020526040812061234b908363ffffffff61406516565b9392505050565b600082815260336020526040812061234b908363ffffffff61407116565b806001600160a01b03166123826132d6565b6001600160a01b031614156123c85760405162461bcd60e51b81526004018080602001828103825260248152602001806151806024913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff161561242b5760d060006123f56132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff19169055612472565b600160cf60006124396132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b61247a6132d6565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60cc8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156117085780601f1061177457610100808354040283529160200191611708565b600054610100900460ff1680612536575061253661315d565b80612544575060005460ff16155b61257f5760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156125aa576000805460ff1961ff0019909116610100171660011790555b6125b2614086565b6125ba614123565b6001600160a01b0383166125ff5760405162461bcd60e51b815260040180806020018281038252602281526020018061513c6022913960400191505060405180910390fd5b60fb80546001600160a01b0319166001600160a01b03858116919091179091558216612672576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fc80546001600160a01b0319166001600160a01b038416179055619c4060fd5580156126a5576000805461ff00191690555b505050565b6126a56126b56132d6565b848484604051806020016040528060008152506001613e9a565b6126d76132d6565b6001600160a01b03166126e861231e565b6001600160a01b031614612731576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b60fd55565b600081565b60006001600160a01b0383166127825760405162461bcd60e51b815260040180806020018281038252602481526020018061532a6024913960400191505060405180910390fd5b600061278c6132d6565b90506127ba818286866040518060200160405280600081525060405180602001604052806000815250613617565b6127e681828686604051806020016040528060008152506040518060200160405280600081525061385f565b6118918182868660405180602001604052806000815250604051806020016040528060008152506000613b1c565b6040805180820190915260058152640312e302e360dc1b602082015290565b60fe546001600160a01b03166128476132d6565b6001600160a01b0316146128a2576040805162461bcd60e51b815260206004820181905260248201527f63616c6c6572206973206e6f74207468652061646d696e206f70657261746f72604482015290519081900360640190fd5b6128b185858585856000613e9a565b60fe54604080516001600160a01b039092168252517fb22a57ba0314fafe219dc14abcf1f22e86e6e82d599c0c31177a2d7c2e1b17e19181900360200190a15050505050565b6000818152603360205260408120611897906141c0565b60fd5481565b61293661291f6132d6565b8484604051806020016040528060008152506133d1565b61293e6132d6565b6001600160a01b03167f4599e9bf0d45c505e011d0e11f473510f083a4fdc45e3f795d58bb5379dbad68848385604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156129b257818101518382015260200161299a565b50505050905090810190601f1680156129df5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015612a125781810151838201526020016129fa565b50505050905090810190601f168015612a3f5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2505050565b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b01902081565b600082815260336020526040902060020154612a9590611c4b6132d6565b611cf55760405162461bcd60e51b81526004018080602001828103825260308152602001806151c66030913960400191505060405180910390fd5b6000816001600160a01b0316836001600160a01b03161480612b3b57506001600160a01b038316600090815260ce602052604090205460ff168015612b3b57506001600160a01b03808316600090815260d0602090815260408083209387168352929052205460ff16155b8061234b5750506001600160a01b03908116600090815260cf602090815260408083209490931682529290925290205460ff1690565b60fc546001600160a01b031681565b612b886132d6565b6001600160a01b0316612b9961231e565b6001600160a01b031614612be2576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6001600160a01b038116612c3d576040805162461bcd60e51b815260206004820152601e60248201527f6665652074617267657420697320746865207a65726f20616464726573730000604482015290519081900360640190fd5b60fc80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038516301415612ca95760405162461bcd60e51b815260040180806020018281038252602f81526020018061504a602f913960400191505060405180910390fd5b604080516a4d494e5445525f524f4c4560a81b8152905190819003600b019020612cd590611c4b6132d6565b612d1f576040805162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b4b73a32b960511b604482015290519081900360640190fd5b611bb1858585856141cb565b6001600160a01b03918216600090815260d16020908152604080832093909416825291909152205490565b600054610100900460ff1680612d6f5750612d6f61315d565b80612d7d575060005460ff16155b612db85760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015612de3576000805460ff1961ff0019909116610100171660011790555b60fe80546001600160a01b0319166001600160a01b0384161790558015611c95576000805461ff00191690555050565b612e1b61203c565b6001600160a01b0316336001600160a01b031614612e6a5760405162461bcd60e51b815260040180806020018281038252602481526020018061534e6024913960400191505060405180910390fd5b6118738484848461440f565b60fe546001600160a01b031681565b612e8d6132d6565b6001600160a01b0316612e9e61231e565b6001600160a01b031614612ee7576040805162461bcd60e51b815260206004820181905260248201526000805160206152bd833981519152604482015290519081900360640190fd5b6001600160a01b038116612f2c5760405162461bcd60e51b81526004018080602001828103825260268152602001806151166026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b612f906132d6565b6001600160a01b0316816001600160a01b03161415612fe05760405162461bcd60e51b81526004018080602001828103825260218152602001806151f66021913960400191505060405180910390fd5b6001600160a01b038116600090815260ce602052604090205460ff161561304c57600160d0600061300f6132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff191691151591909117905561308a565b60cf60006130586132d6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b6130926132d6565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b6130e56130df6132d6565b85612ad0565b6131205760405162461bcd60e51b815260040180806020018281038252602c815260200180615372602c913960400191505060405180910390fd5b611873848484846133d1565b60fb546001600160a01b031681565b611c956131466132d6565b8383604051806020016040528060008152506133d1565b600061316830614500565b15905090565b600054610100900460ff1680613187575061318761315d565b80613195575060005460ff16155b6131d05760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156131fb576000805460ff1961ff0019909116610100171660011790555b613203614506565b61320b614506565b8015611dec576000805461ff001916905550565b600054610100900460ff1680613238575061323861315d565b80613246575060005460ff16155b6132815760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156132ac576000805460ff1961ff0019909116610100171660011790555b6132b4614506565b6132bf8484846145a6565b8015611873576000805461ff001916905550505050565b60006132e061480c565b905090565b6001600160a01b03831661332a5760405162461bcd60e51b81526004018080602001828103825260258152602001806150a86025913960400191505060405180910390fd5b6001600160a01b03821661336f5760405162461bcd60e51b81526004018080602001828103825260238152602001806154106023913960400191505060405180910390fd5b6001600160a01b03808416600081815260d16020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0384166134165760405162461bcd60e51b815260040180806020018281038252602281526020018061515e6022913960400191505060405180910390fd5b60006134206132d6565b905061343181866000878787613617565b61343e8186600087611873565b613481846040518060600160405280602381526020016153ed602391396001600160a01b038816600090815260c96020526040902054919063ffffffff613a8516565b6001600160a01b038616600090815260c9602052604090205560ca546134ad908563ffffffff61484416565b60ca81905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561353257818101518382015260200161351a565b50505050905090810190601f16801561355f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561359257818101518382015260200161357a565b50505050905090810190601f1680156135bf5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516000916001600160a01b038816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b6040805163555ddc6560e11b81526001600160a01b03871660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89560248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b15801561369b57600080fd5b505afa1580156136af573d6000803e3d6000fd5b505050506040513d60208110156136c557600080fd5b505190506001600160a01b0381161561385657806001600160a01b03166375ab97828888888888886040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561378b578181015183820152602001613773565b50505050905090810190601f1680156137b85780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156137eb5781810151838201526020016137d3565b50505050905090810190601f1680156138185780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561383d57600080fd5b505af1158015613851573d6000803e3d6000fd5b505050505b50505050505050565b61386b86868686611873565b6138ae836040518060600160405280602781526020016150ef602791396001600160a01b038816600090815260c96020526040902054919063ffffffff613a8516565b6001600160a01b03808716600090815260c9602052604080822093909355908616815220546138e3908463ffffffff6148a116565b60c96000866001600160a01b03166001600160a01b0316815260200190815260200160002081905550836001600160a01b0316856001600160a01b0316876001600160a01b03167f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561399557818101518382015260200161397d565b50505050905090810190601f1680156139c25780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156139f55781810151838201526020016139dd565b50505050905090810190601f168015613a225780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3505050505050565b60008184841115613b145760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ad9578181015183820152602001613ac1565b50505050905090810190601f168015613b065780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6040805163555ddc6560e11b81526001600160a01b03871660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b158015613ba057600080fd5b505afa158015613bb4573d6000803e3d6000fd5b505050506040513d6020811015613bca57600080fd5b505190506001600160a01b03811615613d5e57806001600160a01b03166223de298989898989896040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015613c8f578181015183820152602001613c77565b50505050905090810190601f168015613cbc5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015613cef578181015183820152602001613cd7565b50505050905090810190601f168015613d1c5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015613d4157600080fd5b505af1158015613d55573d6000803e3d6000fd5b50505050613db2565b8115613db257613d76866001600160a01b0316614500565b15613db25760405162461bcd60e51b815260040180806020018281038252604d8152602001806152dd604d913960600191505060405180910390fd5b5050505050505050565b6000828152603360205260409020613dda908263ffffffff6148fb16565b15611c9557613de76132d6565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152603360205260409020613e49908263ffffffff61491016565b15611c9557613e566132d6565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6001600160a01b038616613edf5760405162461bcd60e51b81526004018080602001828103825260228152602001806150cd6022913960400191505060405180910390fd5b6001600160a01b038516613f3a576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6000613f446132d6565b9050613f54818888888888613617565b613f6281888888888861385f565b61385681888888888888613b1c565b50600090565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114614020576040805162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015290519081900360640190fd5b60208201516040830151606084015160001a61403e86828585614925565b9695505050505050565b600091565b604080516020810190915260008152600b9190910191565b600061234b8383614a9f565b600061234b836001600160a01b038416614b03565b600054610100900460ff168061409f575061409f61315d565b806140ad575060005460ff16155b6140e85760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614113576000805460ff1961ff0019909116610100171660011790555b61411b614506565b61320b614b1b565b600054610100900460ff168061413c575061413c61315d565b8061414a575060005460ff16155b6141855760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff161580156141b0576000805460ff1961ff0019909116610100171660011790555b6141b8614506565b61320b614be2565b600061189782614cdb565b6001600160a01b038416614226576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b60006142306132d6565b905061423f8160008787611873565b60ca54614252908563ffffffff6148a116565b60ca556001600160a01b038516600090815260c9602052604090205461427e908563ffffffff6148a116565b6001600160a01b038616600090815260c960205260408120919091556142ab908290878787876001613b1c565b846001600160a01b0316816001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561432a578181015183820152602001614312565b50505050905090810190601f1680156143575780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561438a578181015183820152602001614372565b50505050905090810190601f1680156143b75780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516001600160a01b038716916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b60008060008087806020019051608081101561442a57600080fd5b5080516020820151604083015160609093015160fd5492975090955091935090915060009061446e9061446790620186a09063ffffffff61484416565b8385614cdf565b905060006144aa670de0b6b3a764000061449e886144928c8763ffffffff61484416565b9063ffffffff614ced16565b9063ffffffff614d4616565b905080156144f4576144f48560fc60009054906101000a90046001600160a01b03168360405180602001604052806000815250604051806020016040528060008152506000613e9a565b50505050505050505050565b3b151590565b600054610100900460ff168061451f575061451f61315d565b8061452d575060005460ff16155b6145685760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff1615801561320b576000805460ff1961ff0019909116610100171660011790558015611dec576000805461ff001916905550565b600054610100900460ff16806145bf57506145bf61315d565b806145cd575060005460ff16155b6146085760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614633576000805460ff1961ff0019909116610100171660011790555b83516146469060cb906020870190614f0a565b50825161465a9060cc906020860190614f0a565b50815161466e9060cd906020850190614f88565b5060005b60cd548110156146cb57600160ce600060cd848154811061468f57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff1916911515919091179055600101614672565b50604080516a22a9219b9b9baa37b5b2b760a91b8152815190819003600b0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad24916329965a1d91606480830192600092919082900301818387803b15801561474957600080fd5b505af115801561475d573d6000803e3d6000fd5b5050604080516922a92199182a37b5b2b760b11b8152815190819003600a0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad2493506329965a1d9250606480830192600092919082900301818387803b1580156147dd57600080fd5b505af11580156147f1573d6000803e3d6000fd5b505050508015611873576000805461ff001916905550505050565b600061481661203c565b6001600160a01b0316336001600160a01b031614614835575033611710565b61483d614dad565b9050611710565b60008282111561489b576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60008282018381101561234b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600061234b836001600160a01b038416614dfa565b600061234b836001600160a01b038416614e44565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156149865760405162461bcd60e51b81526004018080602001828103825260228152602001806151a46022913960400191505060405180910390fd5b8360ff16601b148061499b57508360ff16601c145b6149d65760405162461bcd60e51b81526004018080602001828103825260228152602001806152456022913960400191505060405180910390fd5b604080516000808252602080830180855289905260ff88168385015260608301879052608083018690529251909260019260a080820193601f1981019281900390910190855afa158015614a2e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116614a96576040805162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b81546000908210614ae15760405162461bcd60e51b81526004018080602001828103825260228152602001806150286022913960400191505060405180910390fd5b826000018281548110614af057fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600054610100900460ff1680614b345750614b3461315d565b80614b42575060005460ff16155b614b7d5760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614ba8576000805460ff1961ff0019909116610100171660011790555b609780546001600160a01b03191673d216153c06e857cd7f72665e0af1d7d82172f4941790558015611dec576000805461ff001916905550565b600054610100900460ff1680614bfb5750614bfb61315d565b80614c09575060005460ff16155b614c445760405162461bcd60e51b815260040180806020018281038252602e815260200180615217602e913960400191505060405180910390fd5b600054610100900460ff16158015614c6f576000805460ff1961ff0019909116610100171660011790555b6000614c796132d6565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015611dec576000805461ff001916905550565b5490565b606490810191909202020490565b600082614cfc57506000611897565b82820282848281614d0957fe5b041461234b5760405162461bcd60e51b81526004018080602001828103825260218152602001806152676021913960400191505060405180910390fd5b6000808211614d9c576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381614da557fe5b049392505050565b600060606000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031692915050565b6000614e068383614b03565b614e3c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611897565b506000611897565b60008181526001830160205260408120548015614f005783546000198083019190810190600090879083908110614e7757fe5b9060005260206000200154905080876000018481548110614e9457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080614ec457fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611897565b6000915050611897565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614f4b57805160ff1916838001178555614f78565b82800160010185558215614f78579182015b82811115614f78578251825591602001919060010190614f5d565b50614f84929150614fe9565b5090565b828054828255906000526020600020908101928215614fdd579160200282015b82811115614fdd57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614fa8565b50614f84929150615003565b61171091905b80821115614f845760008155600101614fef565b61171091905b80821115614f845780546001600160a01b031916815560010161500956fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473526563697069656e742063616e6e6f742062652074686520746f6b656e20636f6e7472616374206164647265737321416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744552433737373a20617070726f76652066726f6d20746865207a65726f20616464726573734552433737373a2073656e642066726f6d20746865207a65726f20616464726573734552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737374727573746564207369676e657220697320746865207a65726f20616464726573734552433737373a206275726e2066726f6d20746865207a65726f20616464726573734552433737373a20617574686f72697a696e672073656c66206173206f70657261746f7245434453413a20696e76616c6964207369676e6174757265202773272076616c7565416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b654552433737373a207265766f6b696e672073656c66206173206f70657261746f72496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a656445434453413a20696e76616c6964207369676e6174757265202776272076616c7565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f6e6c79207468652061637475616c2061646d696e206f70657261746f722063616e206368616e67652074686520616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433737373a20746f6b656e20726563697069656e7420636f6e747261637420686173206e6f20696d706c656d656e74657220666f7220455243373737546f6b656e73526563697069656e744552433737373a207472616e7366657220746f20746865207a65726f206164647265737347534e526563697069656e743a2063616c6c6572206973206e6f742052656c61794875624552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f7220666f7220686f6c6465724552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a207472616e736665722066726f6d20746865207a65726f20616464726573734552433737373a206275726e20616d6f756e7420657863656564732062616c616e63654552433737373a20617070726f766520746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a26469706673582212203ab221eea8be0979f07c3acaf98ba16c46c60dad02b2212897924a0e4d0cc0ac64736f6c63430006020033
Deployed Bytecode Sourcemap
109994:3324:0:-:0;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;109994:3324:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60319: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;60319:132:0;;;;;;;;;;;;;;;;;56385: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;56385:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110388:499;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;110388:499:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;110388:499:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;110388: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;110388:499:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;110388:499:0;;;;;;;;-1:-1:-1;110388:499:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;110388:499:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;110388: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;110388:499:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;110388:499:0;;-1:-1:-1;;;110388:499:0;;-1:-1:-1;;;;;110388:499:0;;-1:-1:-1;110388:499:0;;-1:-1:-1;110388:499:0:i;:::-;;61948:201;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;61948:201:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;112832:126;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;112832:126:0;-1:-1:-1;;;;;112832:126:0;;:::i;57211:147::-;;;:::i;:::-;;;;;;;;;;;;;;;;112091:509;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;112091:509:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;112091:509:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;112091: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;112091:509:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;112091:509:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;112091: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;112091:509:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;112091:509:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;112091: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;112091:509:0;;-1:-1:-1;112091:509:0;-1:-1:-1;112091:509:0;:::i;62525:694::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;62525: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;111554:231::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;111554:231:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;111554:231:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;111554: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;111554:231:0;;-1:-1:-1;111554:231:0;-1:-1:-1;111554: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;56842: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;109649:264::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;109649:264:0;-1:-1:-1;;;;;109649:264:0;;:::i;112608:103::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;112608:103:0;-1:-1:-1;;;;;112608:103:0;;:::i;110895:191::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;110895:191:0;;;;;;;;:::i;57048:97::-;;;:::i;106044:204::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;106044:204:0;-1:-1:-1;;;;;106044:204:0;;:::i;60577:407::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;60577:407:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;60577:407:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;60577: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;60577:407:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;60577:407:0;;;;;;;;-1:-1:-1;60577:407:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;60577:407:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;60577: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;60577:407:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;60577:407:0;;-1:-1:-1;60577:407:0;;-1:-1:-1;;;;;60577:407:0:i;112719:105::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;112719:105:0;-1:-1:-1;;;;;112719:105:0;;:::i;57463:174::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57463:174:0;-1:-1:-1;;;;;57463:174:0;;:::i;104133:148::-;;;:::i;93405:104::-;;;:::i;:::-;;;;-1:-1:-1;;;;;93405:104:0;;;;;;;;;;;;;;97164:224;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;97164:224:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;97164:224:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;97164: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;97164:224:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;97164:224:0;;-1:-1:-1;97164:224:0;;-1:-1:-1;;;;;97164:224:0:i;106656:1065::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;106656:1065:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;106656:1065:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;106656: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;106656:1065:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;106656:1065:0;;;;;;;;;;;;;;;-1:-1:-1;106656:1065:0;;;;;-1:-1:-1;106656:1065:0;;-1:-1:-1;106656:1065:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;106656:1065:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;106656: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;106656:1065:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;106656:1065:0;;-1:-1:-1;;106656:1065:0;;;-1:-1:-1;106656:1065:0;;-1:-1:-1;;106656: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;106656:1065:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103482: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;59342:423::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59342:423:0;-1:-1:-1;;;;;59342:423:0;;:::i;56546:104::-;;;:::i;105210:461::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;105210:461:0;;;;;;;;;;:::i;57774:166::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;57774:166:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;57774:166:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;57774: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;57774:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;57774:166:0;;-1:-1:-1;57774:166:0;;-1:-1:-1;;;;;57774:166:0:i;106440:99::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;106440:99:0;;:::i;22392:49::-;;;:::i;58181:451::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;58181:451:0;;;;;;;;:::i;94688:238::-;;;:::i;109201:363::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;109201:363:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;109201:363:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;109201: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;109201:363:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;109201:363:0;;;;;;;;-1:-1:-1;109201:363:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;109201:363:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;109201: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;109201:363:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;109201:363:0;;-1:-1:-1;109201:363:0;;-1:-1:-1;;;;;109201: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;105139:26::-;;;:::i;111793:290::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;111793:290:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;111793:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;111793: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;111793:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;111793:290:0;;;;;;;;-1:-1:-1;111793:290:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;111793:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;111793: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;111793:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;111793:290:0;;-1:-1:-1;111793:290:0;;-1:-1:-1;;;;;111793:290:0:i;110163: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;58967:303::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;58967:303:0;;;;;;;;;;:::i;105107:27::-;;;:::i;106254:180::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;106254:180:0;-1:-1:-1;;;;;106254:180:0;;:::i;111094:452::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;111094:452:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;111094:452:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;111094: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;111094:452:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;111094:452:0;;;;;;;;-1:-1:-1;111094:452:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;111094:452:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;111094: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;111094:452:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;111094:452:0;;-1:-1:-1;111094:452:0;;-1:-1:-1;;;;;111094:452:0:i;61650:153::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;61650:153:0;;;;;;;;;;:::i;108932:156::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;108932:156:0;-1:-1:-1;;;;;108932:156:0;;:::i;98046:290::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;98046:290:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;98046:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;98046: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;98046:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;98046:290:0;;-1:-1:-1;;;;98046:290:0;;;;;-1:-1:-1;98046:290:0;;;;;;;;;:::i;108774:28::-;;;:::i;104436:244::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;104436:244:0;-1:-1:-1;;;;;104436:244:0;;:::i;59834:414::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59834:414:0;-1:-1:-1;;;;;59834:414:0;;:::i;61112:290::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;61112:290:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;61112:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;61112: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;61112:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;61112:290:0;;;;;;;;-1:-1:-1;61112:290:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;61112:290:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;61112: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;61112:290:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;61112:290:0;;-1:-1:-1;61112:290:0;;-1:-1:-1;;;;;61112:290:0:i;105071:31::-;;;:::i;58769:130::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58769:130:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;58769:130:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;58769: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;58769:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;58769:130:0;;-1:-1:-1;58769:130:0;;-1:-1:-1;;;;;58769:130:0:i;60319:132::-;60385:16;60421:22;60414:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60414:29:0;;;;;;;;;;;;;;;;;;;;;;;60319:132;;:::o;56385:100::-;56472:5;56465:12;;;;;;;;-1:-1:-1;;56465:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56439:13;;56465:12;;56472:5;;56465:12;;56472:5;56465:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56465:12:0;;56385:100;-1:-1:-1;;;;;56385:100:0:o;110388: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;110560:33:::1;110604:22;:20;:22::i;:::-;110637:55;110651:9;110662:11;110675:16;110637:13;:55::i;:::-;110703;110731:12;110745;110703:27;:55::i;:::-;110769;110811:12;110769:41;:55::i;:::-;110835:44;22437:4;110866:12:::0;110835:10:::1;:44::i;:::-;8944:1;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;8958:68;110388:499;;;;:::o;61948:201::-;62030:4;62047:14;62064:12;:10;:12::i;:::-;62047:29;;62087:32;62096:6;62104:7;62113:5;62087:8;:32::i;:::-;62137:4;62130:11;;;61948:201;;;;;:::o;112832:126::-;110201:24;;;-1:-1:-1;;;110201:24:0;;;;;;;;;;;;112896:4;;112920:30;;112941:8;112920:7;:30::i;57211:147::-;57338:12;;57211:147;:::o;112091:509::-;112352:36;112366:12;:10;:12::i;:::-;112380:7;112352:13;:36::i;:::-;112330:130;;;;-1:-1:-1;;;112330:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112471:46;112477:7;112486:6;112494:8;;112471:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;112471:46:0;;;;137:4:-1;112471:46:0;;;;;;;;;;;;;;;;;;-1:-1:-1;112504:12:0;;-1:-1:-1;112504:12:0;;;;112471:46;;112504:12;;;;112471:46;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;112471:5:0;;-1:-1:-1;;;112471:46:0:i;:::-;112540:7;-1:-1:-1;;;;;112533:59:0;;112549:6;112557:24;;112583:8;;112533: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;;;112533:59:0;;;;;;;;;;;-1:-1:-1;112533:59:0;;;;;1:33:-1;99:1;81:16;;;74:27;112533:59:0;;137:4:-1;117:14;;;-1:-1;;113:30;157:16;;;112533:59:0;;;;-1:-1:-1;112533:59:0;;-1:-1:-1;;;;;;;;112533:59:0;112091:509;;;;;;;;:::o;62525:694::-;62631:4;-1:-1:-1;;;;;62656:23:0;;62648:72;;;;-1:-1:-1;;;62648:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62739:20:0;;62731:71;;;;-1:-1:-1;;;62731:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62815:15;62833:12;:10;:12::i;:::-;62815:30;;62858:61;62876:7;62885:6;62893:9;62904:6;62858:61;;;;;;;;;;;;;;;;;;;;;;;;:17;:61::i;:::-;62932:49;62938:7;62947:6;62955:9;62966:6;62932:49;;;;;;;;;;;;;;;;;;;;;;;;:5;:49::i;:::-;62992:112;63001:6;63009:7;63018:85;63051:6;63018:85;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63018:19:0;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;:85;;:32;:85;:::i;:::-;62992:8;:112::i;:::-;63117:70;63137:7;63146:6;63154:9;63165:6;63117:70;;;;;;;;;;;;;;;;;;;;;;;;63181:5;63117:19;:70::i;:::-;-1:-1:-1;63207:4:0;;62525:694;-1:-1:-1;;;;62525:694:0:o;25013:114::-;25070:7;25097:12;;;:6;:12;;;;;:22;;;;25013:114::o;111554:231::-;111689:4;111711:44;111718:6;111711:44;;;;;;;;;;;;111730:24;;111711:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;111711:6:0;;-1:-1:-1;;;111711:44:0:i;:::-;-1:-1:-1;111773:4:0;111554: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;56842:84::-;56916:2;56842: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;109649:264::-;109737:13;;-1:-1:-1;;;;;109737:13:0;109721:12;:10;:12::i;:::-;-1:-1:-1;;;;;109721:29:0;;109713:95;;;;-1:-1:-1;;;109713:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109840:13;;109820:50;;;-1:-1:-1;;;;;109840:13:0;;;109820:50;;;;;;;;;;;;;;;;;;;;;109877:13;:30;;-1:-1:-1;;;;;;109877:30:0;-1:-1:-1;;;;;109877:30:0;;;;;;;;;;109649:264::o;112608:103::-;110201:24;;;-1:-1:-1;;;110201:24:0;;;;;;;;;;;;112671:32;;112694:8;112671:9;:32::i;:::-;112608:103;:::o;110895:191::-;111004:4;111026:30;111031:9;111042:5;111026:30;;;;;;;;;;;;;;;;;;;;;;;;:4;:30::i;57048:97::-;57136:1;57048:97;:::o;106044:204::-;103713:12;:10;:12::i;:::-;-1:-1:-1;;;;;103702:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;103702:23:0;;103694:68;;;;;-1:-1:-1;;;103694:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;103694:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;106129:31:0;::::1;106121:78;;;;-1:-1:-1::0;;;106121:78:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106206:16;:36:::0;;-1:-1:-1;;;;;;106206:36:0::1;-1:-1:-1::0;;;;;106206:36:0;;;::::1;::::0;;;::::1;::::0;;106044:204::o;60577:407::-;60823:35;60837:12;:10;:12::i;:::-;60851:6;60823:13;:35::i;:::-;60815:92;;;;-1:-1:-1;;;60815:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60918:58;60924:6;60932:9;60943:6;60951:4;60957:12;60971:4;60918:5;:58::i;:::-;60577:407;;;;;:::o;112719:105::-;110201:24;;;-1:-1:-1;;;110201:24:0;;;;;;;;;;;;112783:33;;112807:8;112783:10;:33::i;57463:174::-;-1:-1:-1;;;;;57607:22:0;57580:7;57607:22;;;:9;:22;;;;;;;57463:174::o;104133:148::-;103713:12;:10;:12::i;:::-;-1:-1:-1;;;;;103702:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;103702:23:0;;103694:68;;;;;-1:-1:-1;;;103694:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;103694:68:0;;;;;;;;;;;;;;;104224:6:::1;::::0;104203:40:::1;::::0;104240:1:::1;::::0;-1:-1:-1;;;;;104224:6:0::1;::::0;104203:40:::1;::::0;104240:1;;104203:40:::1;104254:6;:19:::0;;-1:-1:-1;;;;;;104254:19:0::1;::::0;;104133:148::o;93405:104::-;93492:9;;-1:-1:-1;;;;;93492:9:0;93405:104;:::o;97164:224::-;97243:7;97285:12;:10;:12::i;:::-;-1:-1:-1;;;;;97271:26:0;:10;-1:-1:-1;;;;;97271:26:0;;97263:75;;;;-1:-1:-1;;;97263:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97356:24;97372:7;97356:15;:24::i;106656:1065::-;106977:7;106986:12;107011:15;107028:22;107065:12;107054:39;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;107054: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;107054:39:0;;420:4:-1;411:14;;;;107054:39:0;;;;;411:14:-1;107054: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;107054:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107010:83;;;;107100:17;107145:7;107161:5;107175:4;107188:15;107212:14;107235:8;107252;107269:5;107315:12;:10;:12::i;:::-;107386:4;107120:321;;;;;;;;;;;-1:-1:-1;;;;;107120:321:0;-1:-1:-1;;;;;107120:321:0;;;;;;;;-1:-1:-1;;;;;107120:321:0;-1:-1:-1;;;;;107120: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;;107120:321:0;;;;;-1:-1:-1;107120:321:0;;;;;;;-1:-1:-1;107120:321:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;107120:321:0;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;107120:321:0;;;;;;107515:16;;107452:15;;;;;;;;;107120:321;;-1:-1:-1;;;;;;107515:16:0;;-1:-1:-1;107452:59:0;;-1:-1:-1;107501:9:0;;-1:-1:-1;107452:40:0;;-1:-1:-1;107452:38:0;:40::i;:::-;:48;:59;:48;:59;:::i;:::-;-1:-1:-1;;;;;107452:79:0;;107448:268;;;107569:51;;;;;;;;;-1:-1:-1;;;;;107569:51:0;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;107569:51:0;;;;;;;107549:72;;:19;:72::i;:::-;107542:79;;;;;;;;;107448:268;107651:57;107678:28;107651:18;:57::i;106656:1065::-;;;;;;;;;;;;;:::o;103482:87::-;103555:6;;-1:-1:-1;;;;;103555:6:0;103482: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;59342:423::-;59447:8;-1:-1:-1;;;;;59431:24:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;59431:24:0;;;59423:73;;;;-1:-1:-1;;;59423:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59513:27:0;;;;;;:17;:27;;;;;;;;59509:189;;;59564:24;:38;59589:12;:10;:12::i;:::-;-1:-1:-1;;;;;59564:38:0;;;;;;;;;;;;;;;;;-1:-1:-1;59564:38:0;;;:48;;;;;;;;;59557:55;;-1:-1:-1;;59557:55:0;;;59509:189;;;59682:4;59645:10;:24;59656:12;:10;:12::i;:::-;-1:-1:-1;;;;;59645:24:0;;;;;;;;;;;;;;;;;-1:-1:-1;59645:24:0;;;:34;;;;;;;;;:41;;-1:-1:-1;;59645:41:0;;;;;;;;;;59509:189;59744:12;:10;:12::i;:::-;-1:-1:-1;;;;;59715:42:0;59734:8;-1:-1:-1;;;;;59715:42:0;;;;;;;;;;;59342:423;:::o;56546:104::-;56635:7;56628:14;;;;;;;;-1:-1:-1;;56628:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56602:13;;56628:14;;56635:7;;56628:14;;56635:7;56628:14;;;;;;;;;;;;;;;;;;;;;;;;105210: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;105351:21:::1;:19;:21::i;:::-;105379:16;:14;:16::i;:::-;-1:-1:-1::0;;;;;105412:31:0;::::1;105404:78;;;;-1:-1:-1::0;;;105404:78:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105489:16;:36:::0;;-1:-1:-1;;;;;;105489:36:0::1;-1:-1:-1::0;;;;;105489:36:0;;::::1;::::0;;;::::1;::::0;;;105542:27;::::1;105534:70;;;::::0;;-1:-1:-1;;;105534:70:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;105611:12;:28:::0;;-1:-1:-1;;;;;;105611:28:0::1;-1:-1:-1::0;;;;;105611:28:0;::::1;;::::0;;105660:5:::1;105646:11;:19:::0;8958:68;;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;8958:68;105210:461;;;:::o;57774:166::-;57878:54;57884:12;:10;:12::i;:::-;57898:9;57909:6;57917:4;57878:54;;;;;;;;;;;;57927:4;57878:5;:54::i;106440:99::-;103713:12;:10;:12::i;:::-;-1:-1:-1;;;;;103702:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;103702:23:0;;103694:68;;;;;-1:-1:-1;;;103694:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;103694:68:0;;;;;;;;;;;;;;;106507:11:::1;:26:::0;106440:99::o;22392:49::-;22437:4;22392:49;:::o;58181:451::-;58267:4;-1:-1:-1;;;;;58292:23:0;;58284:72;;;;-1:-1:-1;;;58284:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58369:12;58384;:10;:12::i;:::-;58369:27;;58409:56;58427:4;58433;58439:9;58450:6;58409:56;;;;;;;;;;;;;;;;;;;;;;;;:17;:56::i;:::-;58478:44;58484:4;58490;58496:9;58507:6;58478:44;;;;;;;;;;;;;;;;;;;;;;;;:5;:44::i;:::-;58535:65;58555:4;58561;58567:9;58578:6;58535:65;;;;;;;;;;;;;;;;;;;;;;;;58594:5;58535:19;:65::i;94688:238::-;94904:14;;;;;;;;;;;;-1:-1:-1;;;94904:14:0;;;;94688:238;:::o;109201:363::-;109395:13;;-1:-1:-1;;;;;109395:13:0;109379:12;:10;:12::i;:::-;-1:-1:-1;;;;;109379:29:0;;109371:74;;;;;-1:-1:-1;;;109371:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109452:59;109458:6;109466:9;109477:6;109485:4;109491:12;109505:5;109452;:59::i;:::-;109544:13;;109523:35;;;-1:-1:-1;;;;;109544:13:0;;;109523:35;;;;;;;;;;;;109201:363;;;;;:::o;23960:127::-;24023:7;24050:12;;;:6;:12;;;;;:29;;:27;:29::i;105139:26::-;;;;:::o;111793:290::-;111954:41;111960:12;:10;:12::i;:::-;111974:6;111982:8;111954:41;;;;;;;;;;;;:5;:41::i;:::-;112018:12;:10;:12::i;:::-;-1:-1:-1;;;;;112011:64:0;;112032:6;112040:24;112066:8;112011: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;112011:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;112011: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;112011:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111793:290;;;:::o;110163:62::-;110201:24;;;-1:-1:-1;;;110201:24:0;;;;;;;;;;;;110163: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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58967:303;59067:4;59103:11;-1:-1:-1;;;;;59091:23:0;:8;-1:-1:-1;;;;;59091:23:0;;:121;;;-1:-1:-1;;;;;;59132:27:0;;;;;;:17;:27;;;;;;;;:79;;;;-1:-1:-1;;;;;;59164:37:0;;;;;;;:24;:37;;;;;;;;:47;;;;;;;;;;;;59163:48;59132:79;59091:171;;;-1:-1:-1;;;;;;;59229:23:0;;;;;;;:10;:23;;;;;;;;:33;;;;;;;;;;;;;;;;58967:303::o;105107:27::-;;;-1:-1:-1;;;;;105107:27:0;;:::o;106254:180::-;103713:12;:10;:12::i;:::-;-1:-1:-1;;;;;103702:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;103702:23:0;;103694:68;;;;;-1:-1:-1;;;103694:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;103694:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;106331:27:0;::::1;106323:70;;;::::0;;-1:-1:-1;;;106323:70:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;106400:12;:28:::0;;-1:-1:-1;;;;;;106400:28:0::1;-1:-1:-1::0;;;;;106400:28:0;;;::::1;::::0;;;::::1;::::0;;106254:180::o;111094:452::-;111269:4;-1:-1:-1;;;;;111299:26:0;;111320:4;111299:26;;111291:87;;;;-1:-1:-1;;;111291:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110201:24;;;-1:-1:-1;;;110201:24:0;;;;;;;;;;;;111397:34;;111418:12;:10;:12::i;111397:34::-;111389:69;;;;;-1:-1:-1;;;111389:69:0;;;;;;;;;;;;-1:-1:-1;;;111389:69:0;;;;;;;;;;;;;;;111469:47;111475:9;111486:5;111493:8;111503:12;111469:5;:47::i;61650:153::-;-1:-1:-1;;;;;61767:19:0;;;61740:7;61767:19;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;61650:153::o;108932: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;109050:13:::1;:30:::0;;-1:-1:-1;;;;;;109050:30:0::1;-1:-1:-1::0;;;;;109050:30:0;::::1;;::::0;;8958:68;;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;108932:156;;:::o;98046:290::-;98205:12;:10;:12::i;:::-;-1:-1:-1;;;;;98191:26:0;:10;-1:-1:-1;;;;;98191:26:0;;98183:75;;;;-1:-1:-1;;;98183:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98269:59;98286:7;98295;98304:12;98318:9;98269:16;:59::i;108774:28::-;;;-1:-1:-1;;;;;108774:28:0;;:::o;104436:244::-;103713:12;:10;:12::i;:::-;-1:-1:-1;;;;;103702:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;103702:23:0;;103694:68;;;;;-1:-1:-1;;;103694:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;103694:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;104525:22:0;::::1;104517:73;;;;-1:-1:-1::0;;;104517:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104627:6;::::0;104606:38:::1;::::0;-1:-1:-1;;;;;104606:38:0;;::::1;::::0;104627:6:::1;::::0;104606:38:::1;::::0;104627:6:::1;::::0;104606:38:::1;104655:6;:17:::0;;-1:-1:-1;;;;;;104655:17:0::1;-1:-1:-1::0;;;;;104655:17:0;;;::::1;::::0;;;::::1;::::0;;104436:244::o;59834:414::-;59932:12;:10;:12::i;:::-;-1:-1:-1;;;;;59920:24:0;:8;-1:-1:-1;;;;;59920:24:0;;;59912:70;;;;-1:-1:-1;;;59912:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59999:27:0;;;;;;:17;:27;;;;;;;;59995:189;;;60094:4;60043:24;:38;60068:12;:10;:12::i;:::-;-1:-1:-1;;;;;60043:38:0;;;;;;;;;;;;;;;;;-1:-1:-1;60043:38:0;;;:48;;;;;;;;;:55;;-1:-1:-1;;60043:55:0;;;;;;;;;;59995:189;;;60138:10;:24;60149:12;:10;:12::i;:::-;-1:-1:-1;;;;;60138:24:0;;;;;;;;;;;;;;;;;-1:-1:-1;60138:24:0;;;:34;;;;;;;;;60131:41;;-1:-1:-1;;60131:41:0;;;59995:189;60227:12;:10;:12::i;:::-;-1:-1:-1;;;;;60201:39:0;60217:8;-1:-1:-1;;;;;60201:39:0;;;;;;;;;;;59834:414;:::o;61112:290::-;61256:36;61270:12;:10;:12::i;:::-;61284:7;61256:13;:36::i;:::-;61248:93;;;;-1:-1:-1;;;61248:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61352:42;61358:7;61367:6;61375:4;61381:12;61352:5;:42::i;105071:31::-;;;-1:-1:-1;;;;;105071:31:0;;:::o;58769:130::-;58854:37;58860:12;:10;:12::i;:::-;58874:6;58882:4;58854: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;55366: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;55535:26:::1;:24;:26::i;:::-;55572:58;55596:5;55603:7;55612:17;55572:23;:58::i;:::-;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;55366:272;;;;:::o;112966:173::-;113062:15;113097:36;:34;:36::i;:::-;113090:43;;112966:173;:::o;67514:341::-;-1:-1:-1;;;;;67608:20:0;;67600:70;;;;-1:-1:-1;;;67600:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67689:21:0;;67681:69;;;;-1:-1:-1;;;67681:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67763:19:0;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;:36;;;67815:32;;;;;;;;;;;;;;;;;67514:341;;;:::o;66060:757::-;-1:-1:-1;;;;;66253:18:0;;66245:65;;;;-1:-1:-1;;;66245:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66323:16;66342:12;:10;:12::i;:::-;66323:31;;66367:73;66385:8;66395:4;66409:1;66413:6;66421:4;66427:12;66367:17;:73::i;:::-;66453:56;66474:8;66484:4;66498:1;66502:6;66453:20;:56::i;:::-;66575:66;66595:6;66575:66;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66575:15:0;;;;;;:9;:15;;;;;;;:66;;:19;:66;:::i;:::-;-1:-1:-1;;;;;66557:15:0;;;;;;:9;:15;;;;;:84;66667:12;;:24;;66684:6;66667:24;:16;:24;:::i;:::-;66652:12;:39;;;;66726:4;-1:-1:-1;;;;;66709:50:0;66716:8;-1:-1:-1;;;;;66709:50:0;;66732:6;66740:4;66746:12;66709: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;66709:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66709: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;66709:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66775:34;;;;;;;;66798:1;;-1:-1:-1;;;;;66775:34:0;;;;;;;;;;;;66060:757;;;;;:::o;68339:509::-;68592:78;;;-1:-1:-1;;;68592:78:0;;-1:-1:-1;;;;;68592:78:0;;;;;;54399:66;68592:78;;;;;;68570:19;;53920:42;;68592:41;;:78;;;;;;;;;;;;;;;53920:42;68592:78;;;5:2:-1;;;;30:1;27;20:12;5:2;68592:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68592:78:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68592:78:0;;-1:-1:-1;;;;;;68685:25:0;;;68681:160;;68752:11;-1:-1:-1;;;;;68727:50:0;;68778:8;68788:4;68794:2;68798:6;68806:8;68816:12;68727:102;;;;;;;;;;;;;-1:-1:-1;;;;;68727:102:0;-1:-1:-1;;;;;68727:102:0;;;;;;-1:-1:-1;;;;;68727:102:0;-1:-1:-1;;;;;68727:102:0;;;;;;-1:-1:-1;;;;;68727:102:0;-1:-1:-1;;;;;68727: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;68727:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68727: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;68727:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68727:102:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68727:102:0;;;;68681:160;68339:509;;;;;;;:::o;66825:544::-;67044:48;67065:8;67075:4;67081:2;67085:6;67044:20;:48::i;:::-;67123:70;67143:6;67123:70;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67123:15:0;;;;;;:9;:15;;;;;;;:70;;:19;:70;:::i;:::-;-1:-1:-1;;;;;67105:15:0;;;;;;;:9;:15;;;;;;:88;;;;67220:13;;;;;;;:25;;67238:6;67220:25;:17;:25;:::i;:::-;67204:9;:13;67214:2;-1:-1:-1;;;;;67204:13:0;-1:-1:-1;;;;;67204:13:0;;;;;;;;;;;;:41;;;;67284:2;-1:-1:-1;;;;;67263:56:0;67278:4;-1:-1:-1;;;;;67263:56:0;67268:8;-1:-1:-1;;;;;67263:56:0;;67288:6;67296:8;67306:12;67263: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;67263:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67263: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;67263:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67350:2;-1:-1:-1;;;;;67335:26:0;67344:4;-1:-1:-1;;;;;67335:26:0;;67354:6;67335:26;;;;;;;;;;;;;;;;;;66825:544;;;;;;:::o;45901:166::-;45987:7;46023:12;46015:6;;;;46007:29;;;;-1:-1:-1;;;46007: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;46007:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46054:5:0;;;45901:166::o;69550:716::-;69840:79;;;-1:-1:-1;;;69840:79:0;;-1:-1:-1;;;;;69840:79:0;;;;;;54586:66;69840:79;;;;;;69818:19;;53920:42;;69840:41;;:79;;;;;;;;;;;;;;;53920:42;69840:79;;;5:2:-1;;;;30:1;27;20:12;5:2;69840:79:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69840:79:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69840:79:0;;-1:-1:-1;;;;;;69934:25:0;;;69930:329;;70004:11;-1:-1:-1;;;;;69976:55:0;;70032:8;70042:4;70048:2;70052:6;70060:8;70070:12;69976:107;;;;;;;;;;;;;-1:-1:-1;;;;;69976:107:0;-1:-1:-1;;;;;69976:107:0;;;;;;-1:-1:-1;;;;;69976:107:0;-1:-1:-1;;;;;69976:107:0;;;;;;-1:-1:-1;;;;;69976:107:0;-1:-1:-1;;;;;69976: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;69976:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;69976: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;69976:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69976:107:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69976:107:0;;;;69930:329;;;70105:19;70101:158;;;70150:15;:2;-1:-1:-1;;;;;70150:13:0;;:15::i;:::-;70149:16;70141:106;;;;-1:-1:-1;;;70141:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69550: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;65055:691::-;-1:-1:-1;;;;;65308:18:0;;65300:65;;;;-1:-1:-1;;;65300:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65384:16:0;;65376:61;;;;;-1:-1:-1;;;65376:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65450:16;65469:12;:10;:12::i;:::-;65450:31;;65494:69;65512:8;65522:4;65528:2;65532:6;65540:8;65550:12;65494:17;:69::i;:::-;65576:57;65582:8;65592:4;65598:2;65602:6;65610:8;65620:12;65576:5;:57::i;:::-;65646:92;65666:8;65676:4;65682:2;65686:6;65694:8;65704:12;65718:19;65646;:92::i;107727:85::-;-1:-1:-1;107801:7:0;;107727:85::o;74870:269::-;75072:58;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;75072:58:0;;;;;;;75062:69;;;;;;74870:269::o;72249:761::-;72327:7;72390:9;:16;72410:2;72390:22;72386:96;;72429:41;;;-1:-1:-1;;;72429:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;72386:96;72843:4;72828:20;;72822:27;72889:4;72874:20;;72868:27;72943:4;72928:20;;72922:27;72551:9;72914:36;72980:22;72988:4;72914:36;72822:27;72868;72980:7;:22::i;:::-;72973:29;72249:761;-1:-1:-1;;;;;;72249:761:0:o;99256:164::-;99338:7;;99256:164::o;99556:167::-;99668:47;;;;;;;;;-1:-1:-1;99668:47:0;;92982:2;99676:34;;;;;99556: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;92461: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;92524:26:::1;:24;:26::i;:::-;92561:31;:29;:31::i;103068: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;103126:26:::1;:24;:26::i;:::-;103163;:24;:26::i;16806:117::-:0;16869:7;16896:19;16904:3;16896:7;:19::i;63808:760::-;-1:-1:-1;;;;;64008:21:0;;64000:66;;;;;-1:-1:-1;;;64000:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64079:16;64098:12;:10;:12::i;:::-;64079:31;;64123:59;64144:8;64162:1;64166:7;64175:6;64123:20;:59::i;:::-;64245:12;;:24;;64262:6;64245:24;:16;:24;:::i;:::-;64230:12;:39;-1:-1:-1;;;;;64301:18:0;;;;;;:9;:18;;;;;;:30;;64324:6;64301:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;64280:18:0;;;;;;:9;:18;;;;;:51;;;;64344:88;;64364:8;;64290:7;64395:6;64403:8;64413:12;64427:4;64344:19;:88::i;:::-;64467:7;-1:-1:-1;;;;;64450:57:0;64457:8;-1:-1:-1;;;;;64450:57:0;;64476:6;64484:8;64494:12;64450: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;64450:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64450: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;64450:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64523:37;;;;;;;;-1:-1:-1;;;;;64523:37:0;;;64540:1;;64523:37;;;;;;;;;63808:760;;;;;:::o;107818:781::-;107929:15;107946:12;107960:22;107984:16;108022:7;108011:57;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;108011:57:0;;;;;;;;;;;;;;;108389:11;;108011:57;;-1:-1:-1;108011:57:0;;-1:-1:-1;108011:57:0;;-1:-1:-1;108011:57:0;;-1:-1:-1;108318:22:0;;108343:85;;108358:43;;93101:6;;108358:43;:30;:43;:::i;:::-;108403:8;108413:14;108343;:85::i;:::-;108318:110;-1:-1:-1;108435:8:0;108446:64;104980:6;108446:45;108483:7;108446:32;:12;108318:110;108446:32;:16;:32;:::i;:::-;:36;:45;:36;:45;:::i;:::-;:49;:64;:49;:64;:::i;:::-;108435:75;-1:-1:-1;108523:7:0;;108519:75;;108541:45;108547:4;108553:12;;;;;;;;;-1:-1:-1;;;;;108553:12:0;108567:3;108541:45;;;;;;;;;;;;;;;;;;;;;;;;108580:5;108541;:45::i;:::-;107818: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;55646:680::-;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;55825:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;55849:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;55879:42:0;;::::1;::::0;:22:::1;::::0;:42:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;55937:9:0::1;55932:138;55956:22;:29:::0;55952:33;::::1;55932:138;;;56054:4;56007:17;:44;56025:22;56048:1;56025:25;;;;;;;;;::::0;;;::::1;::::0;;;;;;::::1;::::0;-1:-1:-1;;;;;56025:25:0::1;56007:44:::0;;;::::1;::::0;;;;;;;;:51;;-1:-1:-1;;56007:51:0::1;::::0;::::1;;::::0;;;::::1;::::0;;-1:-1:-1;55987:3:0::1;55932:138;;;-1:-1:-1::0;56171:24:0::1;::::0;;-1:-1:-1;;;56171:24:0;;;;;;;;::::1;::::0;;;-1:-1:-1;;;56114:97:0;;56164:4:::1;56114:97;::::0;::::1;::::0;;;;;;;;;;;;;;;;53920:42:::1;::::0;56114:41:::1;::::0;:97;;;;;-1:-1:-1;;56114:97:0;;;;;;;-1:-1:-1;53920:42:0;56114:97;::::1;;5:2:-1::0;::::1;;;30:1;27::::0;20:12:::1;5:2;56114: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;;56279:23:0::1;::::0;;-1:-1:-1;;;56279:23:0;;;;;;;;::::1;::::0;;;-1:-1:-1;;;56222:96:0;;56272:4:::1;56222:96;::::0;::::1;::::0;;;;;;;;;;;;;;;;53920:42:::1;::::0;-1:-1:-1;56222:41:0::1;::::0;-1:-1:-1;56222:96:0;;;;;-1:-1:-1;;56222:96:0;;;;;;;-1:-1:-1;53920:42:0;56222:96;::::1;;5:2:-1::0;::::1;;;30:1;27::::0;20:12:::1;5:2;56222:96:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;56222:96:0;;;;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;55646:680;;;;:::o;95920:236::-;95982:15;96028:12;:10;:12::i;:::-;-1:-1:-1;;;;;96014:26:0;:10;-1:-1:-1;;;;;96014:26:0;;96010:139;;-1:-1:-1;96064:10:0;96057:17;;96010:139;96114:23;:21;:23::i;:::-;96107:30;;;;43536:158;43594:7;43627:1;43622;:6;;43614:49;;;;;-1:-1:-1;;;43614:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43681:5:0;;;43536:158::o;43074:179::-;43132:7;43164:5;;;43188:6;;;;43180:46;;;;;-1:-1:-1;;;43180: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;73164:1432::-;73249:7;74174:66;74160:80;;;74152:127;;;;-1:-1:-1;;;74152:127:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74298:1;:7;;74303:2;74298:7;:18;;;;74309:1;:7;;74314:2;74309:7;74298:18;74290:65;;;;-1:-1:-1;;;74290:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74470:24;;;74453:14;74470:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74453:14;;74470:24;;;;;;;-1:-1:-1;;74470:24:0;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;74470:24:0;;-1:-1:-1;;74470:24:0;;;-1:-1:-1;;;;;;;74513:20:0;;74505:57;;;;;-1:-1:-1;;;74505:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;74582:6;73164:1432;-1:-1:-1;;;;;73164: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;92608: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;92681:9:::1;:54:::0;;-1:-1:-1;;;;;;92681:54:0::1;92693:42;92681:54;::::0;;8958:68;;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;92608:135;:::o;103205: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;103273:17:::1;103293:12;:10;:12::i;:::-;103316:6;:18:::0;;-1:-1:-1;;;;;;103316:18:0::1;-1:-1:-1::0;;;;;103316:18:0;::::1;::::0;;::::1;::::0;;;103350:43:::1;::::0;103316:18;;-1:-1:-1;103316:18:0;-1:-1:-1;;103350:43:0::1;::::0;-1:-1:-1;;103350:43:0::1;8944:1;8962:14:::0;8958:68;;;9009:5;8993:21;;-1:-1:-1;;8993:21:0;;;103205:196;:::o;13480:109::-;13563:18;;13480:109::o;99887:352::-;100228:3;100207:16;;;100189:14;;;;:35;100188:43;;99887:352::o;43953:220::-;44011:7;44035:6;44031:20;;-1:-1:-1;44050:1:0;44043:8;;44031:20;44074:5;;;44078:1;44074;:5;:1;44098:5;;;;;:10;44090:56;;;;-1:-1:-1;;;44090:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44651:153;44709:7;44741:1;44737;:5;44729:44;;;;;-1:-1:-1;;;44729:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;44795:1;44791;:5;;;;;;;44651:153;-1:-1:-1;;;44651:153:0:o;100247:1270::-;100302:22;101120:18;101141:8;;101120:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;;;101176:8:0;101412:17;101406:24;-1:-1:-1;;;;;101402:73:0;;100247:1270;-1:-1:-1;;100247: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;;;;;109994:3324;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109994:3324:0;;;-1:-1:-1;109994:3324:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;109994:3324:0;-1:-1:-1;;;;;109994:3324:0;;;;;;;;;;;-1:-1:-1;109994:3324:0;;;;;;;-1:-1:-1;109994:3324:0;;;-1:-1:-1;109994:3324:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;109994:3324:0;;;;;;
Swarm Source
ipfs://3ab221eea8be0979f07c3acaf98ba16c46c60dad02b2212897924a0e4d0cc0ac
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 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.